Friday, November 9, 2018

Raspberry Photo Camera 2

For an index to all my stories click this text

This story is a follow up on the first story about the Raspberry Pi Camera. Before proceeding with this story I urge you to read the first story which you can find here: https://lucstechblog.blogspot.com/2018/11/raspberry-pi-camera.html

A Raspberry Photocam

The previous story about the Raspberry Pi Camera told you how to take a picture or make a video and alter the settings for the camera. . But that is not what my goal was. I wanted a camera and not a computer with a camera.
Meaning to say that I do not want a mouse, keyboard and monitor attached to my Raspberry. I just need some buttons to control it and a power supply. That's it. So first I'll define what I want:

- an ON-OFF button
- a led indicating that the camera is on or off
- a button for taking a picture
- a led that indicates that the picture is taken

Let's build it.

The hardware.

Start with soldering headers to the Pi Zero or, if you are confident about your soldering techniques, solder the wires direct to the PCB. The last option is the best if you are damn sure you are not going to use the Pi Zero for any other projects.


Next make the breadboard connections as shown above.

Gnd ==> GND
GPIO 3 ==> button
GPIO 21 ==> button 2
GPIO 18 ==> green led
GPIO 15 ==> blue led

Make sure you connect both leds to a 1K delimiting resistor otherwise you will damage your Raspberry Pi.



Above you can see my setup. This is made during my final tests, so no HDMI, keyboard or mouse but just a USB power bank. The Pi is somewhat hidden beneath the camera cable.

The software.

Again we will use Python to write software that controls our camera.

As usual start with installing a fresh Raspbian installation on a SD card and make sure that you update it. If you are not sure how to do that read my story about building an internet radio or check the Raspberry Foundation pages:
https://www.raspberrypi.org/documentation/installation/installing-images/README.md

Boot the Raspberry and wait till the desktop is ready. You can attach a monitor, keyboard and mouse to your Raspberry Pi, however I prefer controlling the Raspberry with my PC using VNC. This keeps me from using a second monitor, keyboard and mouse and also makes it more convenient to copy and paste texts and programs from and to the Raspberry. VNC is standard installed on every Raspberry and you really ought to check it out. For more info on this check the VNC pages: https://www.realvnc.com/en/raspberrypi/


Now open a terminal window by clicking on the terminal icon (where the red arrow poits to). first let us make sure we are working in the /home/pi directory by typing the following command:

cd ~

Open the nano editor and make sure a new file is opened called foto01.py by giving the following command:

sudo nano foto01.py

When the nano editor opens type (or paste) in the following code:


#!/usr/bin/python3

import picamera
import RPi.GPIO as GPIO
import os

numberfile = open('/home/pi/number.txt','r')
number = numberfile.readline()
numberfile.close()
camera = picamera.PiCamera()
camera.resolution = (1920, 1080)

os.system

('printf "\033c"')

GPIO.setmode(GPIO.BCM)
GPIO.setup(15, GPIO.OUT)


GPIO.setup(18, GPIO.OUT)


GPIO.setup(3, GPIO.IN, 

pull_up_down=GPIO.PUD_UP)
GPIO.setup(21, GPIO.IN, 

pull_up_down=GPIO.PUD_UP)

GPIO.output(18, GPIO.HIGH)



def takepic(picture):
        GPIO.output(15, GPIO.HIGH)


        global number
        number2 = int(float(number))
        number2 = number2 + 1
        namefile = "image" + str

(number2) + ".jpg"
        camera.capture(namefile)
        numberfile = open('/home/pi/number.txt','w')
        numberstr = str(number2)
        number = numberstr
        numberfile.write(numberstr)
        numberfile.close()
        GPIO.output(15, GPIO.LOW)


        
def progend(stopprog):
 GPIO.output(18, GPIO.LOW)


 os.system('sudo shutdown now')         

GPIO.add_event_detect(3, 

GPIO.FALLING, callback=progend, bouncetime=300)
GPIO.add_event_detect(21, 

GPIO.FALLING, callback=takepic, bouncetime=1000)

while True:
 pass
    


    

If all is done close the editor by typing CTRL-x and anser yes when asked it the file must be saved and make sure the right name is used at saving.

A closer look at the code

First the import commands make sure the necessary libraries are included in the program.

Then a file is opened and a variable called number is read from the file.
This variable is used to store the number of the photo that is made.

Let me get a bit deeper into this. Some programs incorporate the date and time functions into the name of the photo's when they are written to the SD card. That is neat because it tells you exactly when a photo is made. Unfortunately I can not use that. The camera will work stand-alone. So it has no internet connection and therefore will never know the right day and time. So if we would use day and time to stamp the name of a photo there is a possibillity of duplicates when the camera is shut down and restarted. So I will give each photo a subsequent number.

Next the camera is initiated and the GPIO's are set. For the buttons I make use of the internal pull-up resistors by using

    GPIO.IN, pull_up_down=GPIO.PUD_UP

Then GPIO 18 is set HIGH so the led goes on and we know the camera is ready for use.

Next two routine's are defined called def takepic and def progend.

In def takepic several things happen.

        GPIO.output(15, GPIO.HIGH)

First GPIO 15 is set HIGH so the second led will go ON. This way we know a picture is being taken.

        global number
        number2 = int(float(number))
        number2 = number2 + 1
        namefile = "image" + str(number2) + ".jpg"
        camera.capture(namefile)

These lines determine the name of the file that the picture will get. It consists of the word image followed by the number.

And then the command camera.capture(namefile) takes the actual photo and writes it to the SD card in the /home directory.

        numberfile = open('/home/pi/number.txt','w')
        numberstr = str(number2)
        number = numberstr
        numberfile.write(numberstr)
        numberfile.close()

These lines make sure that the new number is saved to the SD card. The benefit off all this is that when you shut down the Raspberry Pi and restart it the next number the photo should get is retrieved from the SD card so you will not get duplicate numbers which would overwrite existing photo's.

Then GPIO 15 is set LOW again so we know the camera is ready for taking another picture.

The second routine:

def progend(stopprog):
    GPIO.output(18, GPIO.LOW)
    os.system('sudo shutdown now')

safely shuts down the Raspberry Pi. GPIO18 is set to LOW setting the led OFF so we know the Pi is shut-down.

Pressing the ON/OFF button again will automatically reboot the Pi. This is happens when GPIO3 is shortly connected to ground as described before in my stopy about the Raspberry ON-OFF button.

GPIO.add_event_detect(3, GPIO.FALLING, callback=progend, bouncetime=300)
GPIO.add_event_detect(21, GPIO.FALLING, callback=takepic, bouncetime=1000)

These commands constantly test wether a button is pressed and when that has happened activate the right routine. The bouncetime parameter takes care of any bouncing from the buttons.

while True:
      pass

These commands make sure the program runs indefinite.

Resolution

While taking photo's in real life I noticed the following phenomenon.
At first I did not set the camera resolution in the program. When I started making photo's they just had a resolution of 760 x 480 pixels. I had no idea why that was till I realised that the Pi did not see a HDMI connection and therefore switched to a lower resolution.

Therefore I incorporated the following line in the program:

camera.resolution = (1920, 1080)

Now this is the standard Full HD resolution and that will be enough for most purposes. However if you need a higher resolution, which will give better pictures change this into:

camera.resolution = (3280, 2464)

The tradeoff is that the pictures take more memory so you will have to clear out the SD card more often.

Choose wisely.

Making number.txt

As you have seen the program writes the number of the photo to a seperate file. However when the Python program starts for the very first time it searches for the file called number.txt and when it does not find it gives an error and quits.

If that would be the case we could never make photo's.

So we need to make the file number.txt manually. In the terminal window type the following command:

sudo nano number.txt

When the editor opens type at the first position on the first line a figure. I suggest 0 (zero)

Close the editor with CTRL-x and like usual answer yes when asked if it needs to be saved and check the name.

We now have a file with the number 0 in it that will be read by foto01.py increased by 1 and makes sure that the first photo that will be taken will get the name image1.jpg

There are other (easier) ways to make a file with just 1 line of text and if you know how then do not hesitate. But thats for real Linux wizzards. For simplicity just follow the way I just described. 

Testing

Before we go on it is best practice to test if the program works like intended.

Open the filemanager and make sure it is pointed at the /home/pi directory.
In the terminal window type the next command:

python photo01.py

The green led (on/off) should go on. Now press the photo button (the one attached to GPIO21) and a picture will be taken.


As you can see in my example it was my 21st picture.

Autobooting

We now know everything works as it should so we have to make sure the foto01.py program starts immediately when the Raspberry Pi boots.

Open again the terminal window and make sure you are working in the /home/pi directory by typing the following command:

cd ~

Next step is to write the script. Open the Nano editor with:

sudo nano ~/.config/lxsession/LXDE-pi/autostart

The Nano editor opens and displays the autostart file which looks (in my case) like this:

@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@point-rpi

Now alter the autostart file so that it looks like the next lines:

@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
python3 /home/pi/foto01.py
@xscreensaver -no-splash
@point-rpi

When done press CTRL-x to stop the editor and make sure you answer yes to the question wether the changes must be saved. Also like usual check if the right filename is used at saving: ~/.config/lxsession/LXDE-pi/autostart

Finished !!!!

So lets do one more last test. Reboot the Pi with the command:

sudo reboot now

Or reboot from the menu.

The Pi will shutdown / restart and when the GUI is started the foto01.py program is automatically started in the background. No terminal window will be opened and just the plain desktop is shown. Open the File Manager and you will see the previous picture you have taken. Now press the photo button and a new picture will show up.

Done !!!

Pressing the ON/OFF button will shut down the Pi and pressing it again will re-boot the Pi and the photocamera program will be direct available again.

Shutting down manually.

If you need to make alterations to the program you can shut down the program manually even if it is running in the background.

Open the terminal window and type the following command

sudo killall python3

This kills any running Python3 program.

The last steps.

Best thing to do is to move all components to a stripboard and make that as convenient as you like.

Remove all other attachments like HDMI cable, mouse, keyboard, USB network adapter etc. Just plug in a power supply (like a power bank) or connect batteries and we have a stand-alone camera !!!

Start the Pi with the ON/OFF button and wait till the green led goes on. Then you can make pictures and switch the Pi off with the ON/OFF button.

Just do not forget to attach the Pi regularly to your PC or a NAS or an external harddisk to transfer the foto's. Clean up the /home/pi directory and you are set to make more photo's.

Now make a nice case / housing and start fotographing the lomographic style. https://en.wikipedia.org/wiki/Lomography I am going to design a casing and print it.

Forographing in real life.

Make sure you use a good powerbank or batteries. I had some trouble with a powerbank that was supposed to supply 2000Ma (2 Amps) and my pi just kept on re-booting just like the trouble I had with a 5 meter USB power cable.

When I switched it for a different power bank everything went smoothly.

After pushing the ON/OFF button it takes about 33 seconds for the Pi to power up and start the program. So watch the led and start shooting when it is ON, not earlier. Undoubtedly the Pi3 would speed this up, however I did not test it. The Pi3 would use more current and is bigger. So for me that is no option. Just have patience.





Above you can see some pictures I took in the evening in our garden. Meaning there was not a lot of light. Nevertheless I am satisfied. Remember we are talking here about a 35 Euro camera !!! The original resolution was 1920 x 1080 but I cropped them for this weblog to 1200 pixels wide and about 700 high.

So the actual pictures are far better as what you see here. And then there is the possibillity to add some more buttons to set ISO value which would have made them a bit more brighter. Well nobody obstructs you to alter my design and add more functionality !!

Have fun shooting
Till next time

Luc Volders