A physical button to take photos

S.L.P. image questions, stereoscopic video livestream and recording, stereoscopic photo capture etc.
User avatar
Realizator
Site Admin
Posts: 594
Joined: Tue Apr 16, 2019 9:23 am
Contact:

Re: A physical button to take photos

Post by Realizator »

Hi MauriceCyril,
All your steps looks fine for me.
Notice 1: if you're using SLP image, step "0" is not necessary, as all libs are already installed (as mentioned by Stereomaton).
Notice 2: your post looks like a step-by-step guide. If you want to mention all the steps, please add "unlock filesystem" in your step 2, as it is read-only by default on SLP.
Eugene a.k.a. Realizator

MauriceCyril
Posts: 4
Joined: Fri Feb 21, 2020 3:13 am

Re: A physical button to take photos

Post by MauriceCyril »

Hi Realizator, thanks so much. I updated the steps based on your recommendation.

stereomaton
Posts: 183
Joined: Tue May 21, 2019 12:33 pm
Location: France

Re: A physical button to take photos

Post by stereomaton »

Nice rewording into step by step guide.
Stereophotographer and hacker
Despite my quite active participation in the forum, I am not in the StereoPi team
StereoPi Standard Edition + CM3Lite module + a few cameras

bensailor
Posts: 14
Joined: Thu Mar 05, 2020 9:46 pm

Re: A physical button to take photos

Post by bensailor »

Hi all,

I have been reading this forum post and it is exactly something I am looking to do. One question is the button connect through a breadboard, or straight onto the GPIO pins using the stereopi power connector?

Thanks

stereomaton
Posts: 183
Joined: Tue May 21, 2019 12:33 pm
Location: France

Re: A physical button to take photos

Post by stereomaton »

You can connect it in several ways, the goal is to have a high impedance (i.e. open circuit) in general and a GND (0V) briefly to take the photo.
The code has a rudimentary (but sufficient in this context) debouncing so that you can connect the button without additional electronical hardware.
When I wrote it, I connected two jumper wires on the extension connector to the right pins and shorted the two wires to take the photo.

About denouncing: when you use a button/contacter/wire-shorting, there are always several edges due to mechanical contact that is not perfect. Here, the code has a neutralization period when it do not wait for an edge to be more sure to not trigger on a ripple of the last contact.
Stereophotographer and hacker
Despite my quite active participation in the forum, I am not in the StereoPi team
StereoPi Standard Edition + CM3Lite module + a few cameras

TomDev
Posts: 17
Joined: Thu Jun 04, 2020 5:56 pm

Re: A physical button to take photos

Post by TomDev »

Hey all, I'm working on my own version of this, but am having trouble getting my script to run as part of run.sh

I've added my script file to it, but it's not running on startup :S I followed the step by step guide too, so it should work fine.

I've basically copied the make_photo.php file and made a python version of it. It works great when I run the trigger.py python file while ssh'd into the StereoPi, but the script just won't run on startup/offline.

The code is below for both the trigger script and the offline_make_photo script. The idea is that the trigger script runs even when the pi is offline and makes use of the raspistill command in the offline_make_photo script.

trigger.py

Code: Select all

# Nabbed from Stereomaton and Modified by TechDevTom/Tom Southworth

#!/usr/bin/env python

# Import necessary libraries
import RPi.GPIO as GPIO
import os
from time import sleep

# Set up the Trigger Pin which will trigger the taking of Photos
triggerPin = 4

# Set the GPIO Board mode to BCM, so it uses GPIO number reference not Pin number reference
GPIO.setmode (GPIO.BCM)
# Set the triggerPin to be an input and for its internal resistor to be initially HIGH
GPIO.setup(triggerPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Infinitely Loop
while True:
	# Wait for a change in the triggerPin
	GPIO.wait_for_edge(triggerPin, GPIO.FALLING)
	# Say cheese!
	print ('cheese!')
	# Create a system call to run the Python based offline_make_photo.py script
	os.system('sudo python /opt/StereoPi/scripts/offline_make_photo.py')
	# Sleep for a second while the photo is taken
	sleep(1)


# Can you spot the SAO anime reference in this code :P
offline_make_photo.py

Code: Select all

# PHP version Nabbed from Realizator/StereoPi and Modified into Python by TechDevTom/Tom Southworth

#!/usr/bin/env python

# Import necessary libraries
import io
import os
from datetime import datetime

# Declare file paths
filename 	= 'stereoImage_' + datetime.now().strftime('%d%m%Y-%H%M%S') + '.jpg'
storagepath = 'media/DCIM/'
configpath 	= '/opt/StereoPi/config.conf'

# Load Config File
with open (configpath) as file_object:
	config_strings = file_object.readlines()

# Parse Config File into a dictionary
config = {}
for line in config_strings:

	temp = str(line).split('=')
	temp[0] = temp[0].rstrip()
	temp[1] = temp[1].rstrip()
	config.update ( {temp[0] : temp[1]} )

# Stop raspidvid from streaming
os.system ('killall -q raspivid')

# Determine raspistill settings
if config['video_mode'] == '3D':
	VIDEOMODE = ' -3d sbs '
else:
	VIDEOMODE = ''

if config['up_down'] == '1':
	UPDOWN = ' -vf -hf '
else:
	UPDOWN = ''

if config['swapcams'] == '1':
	SWAPCAMS = ' -cs 1 '
else:
	SWAPCAMS = ''

if config['photo_resolution'] == 'V1-full-size':
	PHOTO_RESOLUTION = ' -w 5184 -h 1944 '
elif config['photo_resolution'] == 'V2-full-size':
	PHOTO_RESOLUTION = ' -w 6560 -h 2464 '
else:
	PHOTO_RESOLUTION = ''

# Print the information related to the raspistill command
print ('videomode:  ' + VIDEOMODE)
print ('updown:  ' + UPDOWN)
print ('swapcams:  ' + SWAPCAMS)
print ('photoresolution:  ' + PHOTO_RESOLUTION)

# Take the photo with raspistill
os.system ('raspistill -n -t 500 -awb sun ' + VIDEOMODE + UPDOWN + SWAPCAMS + PHOTO_RESOLUTION + ' -o ' + storagepath + filename)
os.system ('sudo sync')
print (filename)

User avatar
Realizator
Site Admin
Posts: 594
Joined: Tue Apr 16, 2019 9:23 am
Contact:

Re: A physical button to take photos

Post by Realizator »

Hi Tom,
Which command line you're trying to add to the autostart script? If it is using "python script.py" or just "script.py"? For the second case you have to add execution rights to the .py file.
Eugene a.k.a. Realizator

TomDev
Posts: 17
Joined: Thu Jun 04, 2020 5:56 pm

Re: A physical button to take photos

Post by TomDev »

Ah, do I have to type python script.py into run.sh? I did this: sudo nano /opt/StereoPi/run.sh and then added this: ./scripts/trigger.py & but it never ran on startup.

I'm afraid I think I've broken all of it, as now my Pi won't load anything and the web interface isn't appearing, nor can I find its IP address using IP scanning software. Maybe I did something wrong to the run.sh file. Is there any way to reset it? Is the run.sh file on the SD card/SLP image? Or is it loaded onto the StereoPi itself/compute module? Could you tell me how to reset everything to factory condition please?

User avatar
Realizator
Site Admin
Posts: 594
Joined: Tue Apr 16, 2019 9:23 am
Contact:

Re: A physical button to take photos

Post by Realizator »

Tom, I'm glad you've solved that after our chat! :-)
For other mates who will read this - adding a "python " helped here, like in the previous case in this thread.
Eugene a.k.a. Realizator

TomDev
Posts: 17
Joined: Thu Jun 04, 2020 5:56 pm

Re: A physical button to take photos

Post by TomDev »

So, with the help of Realizator, I'm back up and running!

If you want to use the Python files I created, here's a step by step guide to get it running:

Step 1: Wire up the two pins, GPIO 004 for the button and one of the GROUND pins, I used Board Pin 9.

Step 2. Power up the StereoPi and make the file system writeable:

Code: Select all

sudo mount -o rw,remount /
Step 3. Create the trigger_photo.py file:

Code: Select all

sudo nano /opt/StereoPi/scripts/trigger_photo.py
Once opened and ready for editing, paste the following code in there:

Code: Select all

# Nabbed from Stereomaton and Modified by TechDevTom/Tom Southworth

#!/usr/bin/env python

# Import necessary libraries
import RPi.GPIO as GPIO
import os
from time import sleep

# Set up the Trigger Pin which will trigger the taking of Photos
triggerPin = 4

# Set the GPIO Board mode to BCM, so it uses GPIO number reference not Pin number reference
GPIO.setmode (GPIO.BCM)
# Set the triggerPin to be an input and for its internal resistor to be initially HIGH
GPIO.setup(triggerPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Infinitely Loop
while True:
	# Wait for a change in the triggerPin
	GPIO.wait_for_edge(triggerPin, GPIO.FALLING)
	# Say cheese!
	print ('cheese!')
	# Create a system call to run the Python based python_make_photo.py script
	os.system('python /opt/StereoPi/scripts/python_make_photo.py')
	# Sleep for a second while the photo is taken
	sleep(1)
Exit the file when code is pasted and saved.

Step 4. Create the python_make_photo.py file:

Code: Select all

sudo nano /opt/StereoPi/scripts/python_make_photo.py
Once opened and ready for editing, paste the following code in there:

Code: Select all

# PHP version Nabbed from Realizator/StereoPi and Modified into Python by TechDevTom/Tom Southworth

#!/usr/bin/env python

# Import necessary libraries
import io
import os
from datetime import datetime

# Declare file paths
filename 	= 'stereoImage_' + datetime.now().strftime('%d%m%Y-%H%M%S') + '.jpg'
storagepath = '/media/DCIM/'
configpath 	= '/opt/StereoPi/config.conf'

# Load Config File
with open (configpath) as file_object:
	config_strings = file_object.readlines()

# Parse Config File into an array
config = {}
for line in config_strings:

	temp = str(line).split('=')
	temp[0] = temp[0].rstrip()
	temp[1] = temp[1].rstrip()
	config.update ( {temp[0] : temp[1]} )

# Stop raspidvid from streaming
os.system ('killall -q raspivid')

# Determine raspistill settings
if config['video_mode'] == '3D':
	VIDEOMODE = ' -3d sbs '
else:
	VIDEOMODE = ''

if config['up_down'] == '1':
	UPDOWN = ' -vf -hf '
else:
	UPDOWN = ''

if config['swapcams'] == '1':
	SWAPCAMS = ' -cs 1 '
else:
	SWAPCAMS = ''

if config['photo_resolution'] == 'V1-full-size':
	PHOTO_RESOLUTION = ' -w 5184 -h 1944 '
elif config['photo_resolution'] == 'V2-full-size':
	PHOTO_RESOLUTION = ' -w 6560 -h 2464 '
else:
	PHOTO_RESOLUTION = ''

# Print the information related to the raspistill command
print ('videomode:  ' + VIDEOMODE)
print ('updown:  ' + UPDOWN)
print ('swapcams:  ' + SWAPCAMS)
print ('photoresolution:  ' + PHOTO_RESOLUTION)

# Take the photo with raspistill
os.system ('raspistill -n -t 500 -awb sun ' + VIDEOMODE + UPDOWN + SWAPCAMS + PHOTO_RESOLUTION + ' -o ' + storagepath + filename)
os.system ('sudo sync')
print (filename)
Exit the file when code is pasted and saved.

Step 5. Make both python files executable:

Code: Select all

sudo chmod +x /opt/StereoPi/scripts/trigger_photo.py

Code: Select all

sudo chmod +x /opt/StereoPi/scripts/python_make_photo.py
Step 6. Add the call to execute trigger_photo.py on start up to the run.sh file:

Code: Select all

sudo nano /opt/StereoPi/run.sh
Once opened and ready for editing, add the following two lines:
# Adding in the ability to Trigger the taking of Photos via Python (USER ADDED)
python ./scripts/trigger_photo.py &

Notice the (USER ADDED) on the comment, it's just to help me find it later on amongst all the other calls. Now save and close the file.

Step 7. Power off your StereoPi and unplug your Wi-Fi/Ethernet cable, so that the StereoPi has no internet access.

Step 8. Power up your StereoPi, and make the connection between the GPIO 004 pin and the GROUND pin as mentioned in Step 1. This should take a photo and add it to your photo records on the StereoPi. Take more than one photo if you like! A red LED lights up on the StereoPi board when a photo is being taken.

Step 9. Power off your StereoPi, plug in your Wi-Fi/Ethernet cable, so that the StereoPi has internet access again.

Step 10. Power on your StereoPi one last time, and connect to the SLP Web Interface's records section on a different machine. Type in either http://stereopi.local/records/ or IPADDRESS/records/, where IPADDRESS is the IP Address of your StereoPi. This should take you to the collection of photos that your StereoPi has taken and stored for you. The photos you took in Step 8 should be here. If not, something has gone wrong!

Hope this helps people who might want to take the photo making ability that comes with the StereoPi and extend it using Python :) The python_make_photo.py is pretty much a Python version of the make_photo.php that comes with the StereoPi, with a few minor Python based adjustments.

Let me know if you use it and what you do with it :)
Last edited by TomDev on Sat Jun 13, 2020 3:43 pm, edited 2 times in total.

stereomaton
Posts: 183
Joined: Tue May 21, 2019 12:33 pm
Location: France

Re: A physical button to take photos

Post by stereomaton »

TomDev wrote:
Thu Jun 11, 2020 10:55 pm
Hey all, I'm working on my own version of this, but am having trouble getting my script to run as part of run.sh
The first thing I notice is that the shebang is at the wrong place.
To execute a text file, the kernel needs to know with which interpreter to run it and it is described by the first line starting with #!.
Move your description after it.

Alternatively you can launch the text file directly from the interpreter in which case the shebang and the execution right are optional.
That is why it works when adding python in run.sh and not when launching it directly.
TomDev wrote:
Fri Jun 12, 2020 3:44 pm
Notice the (USER ADDED) on the comment, it's just to help me find it later on amongst all the other calls. Now save and close the file.
I would encourage you to learn to use a decentralized version control system such as git. No need to know every command to profit from it.
That way, you can track the original file, and then know every change you made, when it was made, why and details optionally added in the commit message. And you will never ever need this kind of trick in the file because you would have far better tool to follow the changes and optionally backup them externally through network or filesystem and even be able to switch versions with one command line.
TomDev wrote:
Fri Jun 12, 2020 3:44 pm
# Create a system call to run the Python based offline_make_photo.py script
os.system('sudo python /opt/StereoPi/scripts/offline_make_photo.py')
Not sure that sudo is needed here, because when launched by run.sh you are already root (same thing for sync in the other script). By the way, sudo in a script is always surprising.
Moreover, as they are two python scripts, you could do something cleverer [in the sense of not wasting processing resources] by defining a function in the second script and call it from the first. You can use the if __name__ == "__main__": test trick to run the function automatically when executed as script.

Also I wonder what is the point to rewrite those scripts. Sure you gain some indirections that can introduce a delay, but at the price of not benefiting from future improvement of the official script.
I guess that the name "offline" is a clue to reveal a potential misunderstanding. The http server is running inside the StereoPi, being a network connected to be able to reach it or not. When using the localhost address, you can contact this server from inside the StereoPi without the need of any external connection, so that the original script works offline as well. By the way, you probably could have run the php script directly with the right interpreter.
Stereophotographer and hacker
Despite my quite active participation in the forum, I am not in the StereoPi team
StereoPi Standard Edition + CM3Lite module + a few cameras

TomDev
Posts: 17
Joined: Thu Jun 04, 2020 5:56 pm

Re: A physical button to take photos

Post by TomDev »

stereomaton wrote:
Sat Jun 13, 2020 9:53 am
The first thing I notice is that the shebang is at the wrong place.
To execute a text file, the kernel needs to know with which interpreter to run it and it is described by the first line starting with #!.
Move your description after it.

Alternatively you can launch the text file directly from the interpreter in which case the shebang and the execution right are optional.
That is why it works when adding python in run.sh and not when launching it directly.
Is it? You mean in my python scripts? I'm not sure I follow, on every example I can find online the shebang is always at the start of the path? Cna you send a few links where the shebang is placed differently please so I can learn better?
stereomaton wrote:
Sat Jun 13, 2020 9:53 am
I would encourage you to learn to use a decentralized version control system such as git. No need to know every command to profit from it.
That way, you can track the original file, and then know every change you made, when it was made, why and details optionally added in the commit message. And you will never ever need this kind of trick in the file because you would have far better tool to follow the changes and optionally backup them externally through network or filesystem and even be able to switch versions with one command line.
You've assumed that I don't already know how to use git. I've been using version control for the majority of my projects for the last five years almost. I put that there not to know if I'm changing it or not, but because amongst all the other code that is not mine, if I need to find that line quickly, I can search a specific phrase/word and find it immediately, rather than opening up a git command line or using something like SourceTree to wade through the commit history. I actually said that in the comment, "it's just to help me find it later on amongst all the other calls".

stereomaton wrote:
Sat Jun 13, 2020 9:53 am
Not sure that sudo is needed here, because when launched by run.sh you are already root (same thing for sync in the other script). By the way, sudo in a script is always surprising.
Moreover, as they are two python scripts, you could do something cleverer [in the sense of not wasting processing resources] by defining a function in the second script and call it from the first. You can use the if __name__ == "__main__": test trick to run the function automatically when executed as script.
The sudo was left over from when I was having trouble running the script out of run.sh, I'll go remove that now, good spot! The second sudo though is in the PHP version, so I'm leaving it in there. Yes, I could combine them as two scripts, and I tried that, but I ended up having issues running the call to raspistill when I combined both of the scripts together, hence why they are currently apart. When I get around to fixing that up I'll probably combine them. I was getting mmal errors if I remember right, but I have no idea why :S Since it worked as two scripts I left them as two scripts. It also means that if I want to expand either on their own as reusable modules for other purposes, then I don't have to have excess code in one or the other that might not relate to their new purpose.
stereomaton wrote:
Sat Jun 13, 2020 9:53 am
Also I wonder what is the point to rewrite those scripts. Sure you gain some indirections that can introduce a delay, but at the price of not benefiting from future improvement of the official script.
I guess that the name "offline" is a clue to reveal a potential misunderstanding. The http server is running inside the StereoPi, being a network connected to be able to reach it or not. When using the localhost address, you can contact this server from inside the StereoPi without the need of any external connection, so that the original script works offline as well. By the way, you probably could have run the php script directly with the right interpreter.
Yes, it is no longer linked to updates to the official script, but the official script does something very simple, can it be improved that much in the future? Will I miss out on things if I create my own version? Who can tell. If it turns out like that, I may just use the .php version again.

I wanted to create my own version because I don't code in php, nor do I wish to learn it. I know Python, C# and a few other languages, my head's already full! By having my own separate script also, I don't mess about with anything that is official. I don't break anything. I can experiment all I like and expand it as much as I like. I'm already trying to incorporate bluetooth control into the work I've done. Also, by recreating the scripts, I get to understand more about how everything work. I guess what I'm trying to say is, by doing all this, I learn, can have fun and can build my own tools without causing damage.

And yes, I didn't understand the fact that the php script ran offline, but I do now after talking through it with Realizator, so will rename the file and the code. I'll have a look into php interpreters.

stereomaton
Posts: 183
Joined: Tue May 21, 2019 12:33 pm
Location: France

Re: A physical button to take photos

Post by stereomaton »

TomDev wrote:
Sat Jun 13, 2020 3:40 pm
Is it? You mean in my python scripts? I'm not sure I follow, on every example I can find online the shebang is always at the start of the path? Cna you send a few links where the shebang is placed differently please so I can learn better?
As I said, perhaps not clearly enough, the shebang has to be on the first line.
In the code you quoted in this thread, you added a comment and a blank line before, so that it is not on the first line anymore, hence my remark stating that it is wrongly placed.
TomDev wrote:
Sat Jun 13, 2020 3:40 pm
You've assumed that I don't already know how to use git.
Given the context you gave by using a marker to point where a change was done, it was a reasonable assumption. Running "git show" (or other subcommands that show diffs which might be more relevant depending on the context) indicate at which lines are the changes, what text is there and other metadata, which is more than enough to find the change later, so simply adding a marker (that you have to remember somehow) looked like you do not use this wonderful tool.
Sorry if you were insulted by the advice.

You also gave a lot of justifications on other subjects. Sorry if you felt attacked by my words, they were just remarks meant to be constructive. For example, my point about diverging from the official scripts to do exactly the same thing is not a reproach, just a highlight of a possible questionable choice in the design. Whatever, have fun with your board.

Anyway, I guess that this function will be somehow added in the next version of SLP. If you find a way to start the script without passing by the web server (which is probably just calling the script with "php /absolute/path/to/file.php", but not tested; might need to launch in the right working directory, I do not know how php behaves if there is inclusion) you can indicate it (preferably here) so that Realizator might replace the urllib call by this one. However, I wonder which method would have the less jitter in the execution, because the original has a webserver in the path, but the php direct call has to create a process and parse the script.
Stereophotographer and hacker
Despite my quite active participation in the forum, I am not in the StereoPi team
StereoPi Standard Edition + CM3Lite module + a few cameras

TomDev
Posts: 17
Joined: Thu Jun 04, 2020 5:56 pm

Re: A physical button to take photos

Post by TomDev »

Sorry Stereomaton, I did feel slightly put upon by what you said, but that's because of the constant harassment I go through on a weekly basis at my job, which has given me insecurities and a complex about my programming :(

Your advice has been taken on board. I used to take such things easily, now I'm slightly paranoid when people offer advice, as it feels like massive criticism when it's not. Apologies for bringing my personal issues to the forum. I need to find a different job so I can enjoy coding again.

Ps. Bluetooth pairing successful, but getting a connection / receiving data on the stereopi is proving horrible.

User avatar
Realizator
Site Admin
Posts: 594
Joined: Tue Apr 16, 2019 9:23 am
Contact:

Re: A physical button to take photos

Post by Realizator »

Whoa, hot discussion here! :-)
I've updated our post for upcoming SLP update with the feature request "physical button to take photos" support out of the box.
Eugene a.k.a. Realizator

TomDev
Posts: 17
Joined: Thu Jun 04, 2020 5:56 pm

Re: A physical button to take photos

Post by TomDev »

Realizator wrote:
Thu Jun 18, 2020 8:04 am
Whoa, hot discussion here! :-)
I've updated our post for upcoming SLP update with the feature request "physical button to take photos" support out of the box.
That would be great :D

Post Reply