This article is part of a serie about how to spy and feed your pet with Raspberry Pi, don’t miss the first steps !
In the previous articles, we have learned how to build a camera server and a food dispenser. Now is the time to add the final touch to our connected cage. Buttons at the front of course ! One to turn off the camera when we’re at home, another to trigger manually the food dispenser.
If you’re interested in going deeper in understanding what I am going to do, I recommend you going through a quick overview of electricity base concepts. Disclaimer : I have been learning so much during this project but feel free to give me feedback on things I could improve on my setup !
They only works when wired correctly. The negative lead (Cathode) is the shorter lead. From the manufacturer specifications we have :
Resistors are a way of limiting the amount of electricity going through a circuit. As you can see, the Pi pins can deliver up to 50mA when our tiny leds can handle 20mA at best. You can calculate the exact resistor necessary (which is around 60 ohm) but since there is a limited list of available resistors, 220 ohm is still a good choice. However, you can definitely go for 100 ohm !
Couldn’t get enough wires.. bye bye consistency 😆
The breadboard is an awesome prototyping and testing tool ! You just have to wire up your components on it, or directly plug them.
The magic behind the bread board is quite simple. On the edges, where you can see the red and blues lines, all dots are connected vertically (I have highlighted the top + in green). When a signal enters a dot, it is spread in the entire line. This is basically where we are going to put our Pi 3V pin which will empower everything and Ground pin to close the circuit.
On the center of the breadboard, it’s the opposite. Everything is connected horizontally and divided in two parts seperated by the middle space. Example : you put a 3V generator + in J30 (highlighted in blue), the signal will flow in F G H I 30 but NOT in A B C D E since it is on the other side of the middle space.
So what is it that we need ? First of all, we need to plug a button on our circuit and be able to tell if it’s “On” or “Off”. If we detect that the button is “On”, we launch the camera server and we light the led of the button. If it’s off, we turn off the server and the led. No need to have a camera running all day if you’re home right ?
Raspberry Pi GPIO Pins have two distinct modes.
Perfect ! We will use a pin on IN mode to listen to our button state, and a pin on OUT mode to light our button led !
To be able to listen to a button state, we need to build what is called a “pull-up resistor”. I strongly recommend doing this tutorial from CamJam(PDF download). Let’s analyse the electric flow on the following scheme.
Because I have purchased led buttons, there are four pins. 2 pins to make the switch (big), 2 pins to empower a led (small). If you don’t buy led buttons, you can get rid of steps 4 and 4bis.
Red : 3V | Black : Ground | Green : BCM 9| Orange : BCM 23
1 : The red wire connects the 3V pin to the breadboard vertical line.
2 : The power flows inside the 470 ohm resistor.
3 (button off) : The power flows back to the raspberry Pi through the green wire. The Pi is able to detect that power, returning “true” when analysed by code.
3Bis (button on) : The power flows into the button and then goes to ground, resulting in too few power going back in the green wire. Returning “false” when tested by code.
So basically, it returns “false” when pressed, and “true” when off. I know, I know… quite misleading at first right ?
4 (code detects button on) : we send a signal into the orange wire. This will go through a 100 or 220 ohm resistor and light the button led.
4bis (code detects button off) : we cut the signal from the orange wire and shut down the button led by doing so.
Are we good with the algorithm ? Perfect !
Just like in Build a connected food dispenser with Raspberry Pi, we are going to use Python and Rpi.GPIO library to create our script. Move on to your Pi and do the following :
# If you have followed previous tutorialcd /var/www/html/pet-feeder
# Create the file with execution rightstouch camera_button.pychmod +x camera_button.py
Now edit that file with the editor of your choice, and let’s begin scripting by importing our awesome GPIO library !
##!/usr/bin/env pythonimport RPi.GPIO as GPIO
# set the mode to BCM to match BCM number and not physical slotsGPIO.setmode(GPIO.BCM)
Then, let’s put in some variable the BCM pins we are using in our previous scheme.
CAMERA_BTN_LED_OUTPUT = 23CAMERA_BTN_INPUT = 9
Now we need to be able to constantly listen for the buttons state and acvtivate code when it changes. To do this, we are going to use an infinite loop. Of course, to get out of that loop, we add a Keyboard listener, so we can stop the script by holding CTRL + C a few seconds.
try:while True:if GPIO.input(CAMERA_BTN_INPUT) == False:print("CAMERA Pressed - button led ON")GPIO.output(CAMERA_BTN_LED_OUTPUT, GPIO.HIGH)# START the camera serverelseprint("CAMERA OFF - button led OFF")GPIO.output(CAMERA_BTN_LED_OUTPUT, GPIO.HIGH)# STOP the camera serverexcept KeyboardInterrupt:print 'interrupted!'GPIO.cleanup()
How to start or stop the camera server ?
Remember when we were Spying our pet with a Raspberry Pi Camera Server ? We were using Motion as the stream server. Remember how it was so simple to enable or disable the server ? sudo service motion (start | stop). How can we use this command in our script ? Easy ! let’s import the os library.
# at the top of the scriptimport os
And then use the library to launch our command line !
command = 'sudo service motion stop'p = os.system(command)
Let’s test it !
# in your script folderpython camera_button.py
Everything should be working for you too !
Feed Green wire : BCM 25 | Feed Orange wire : BCM 22
Note that you can find the entire scheme on Fritzing.
You want to hear the best part ? No additional difficulty here ! It’s just the same as before. As you can see we added to the scheme a second pull-up resistor. However there is also a yellow led because I thought it was a good idea to add a led on the food dispenser. When you will trigger the feeding remotely, you will see a little led lightening up !
The resistor here is optional, since we will have two leds in series (one inside the button and one on the food dispenser), the 3.3V pin will be just enough.
First things first, let’s change the script name since we are going to handle the camera and the dispenser.
# in your script foldermv camera_button.py buttons_action.py
Now, open the file and let’s add our new BCM number variables
FEED_BTN_LED_OUTPUT = 22FEED_BTN_INPUT = 25
# Set INPUT to analyse incoming signalGPIO.setup(FEED_BTN_INPUT, GPIO.IN)# Set OUPUT as a conditional 3V power pinGPIO.setup(FEED_BTN_LED_OUTPUT, GPIO.OUT)
And now what ? look at this ! We only have to add an if/else statement in our code to handle everything.
try:while True:# ... if/else camera code ...
# our brand new feed button listener
if GPIO.input(FEED\_BTN\_INPUT) == False:
print("FEED Pressed - button led ON")
GPIO.output(CAMERA\_BTN\_LED\_OUTPUT, GPIO.HIGH)
# Launch the feed script
else
print("FEED OFF - button led OFF")
GPIO.output(FEED\_BTN\_LED\_OUTPUT, GPIO.LOW)
except KeyboardInterrupt:print 'interrupted!'GPIO.cleanup()
Ok but how do we launch the feed script ? We use the os library, just like before !
# Please find the detail of feed.py on the previous tutorial.command = 'python /var/www/html/pet-feeder/feed.py'p = os.system(command)
Now test it !
python buttons_action.py
Our script is ready ! But we are not quite down yet. We have to tackle two problems :
The proper way to do this is using an “init script”. These are stored in the /etc/init.d/ folder of your Pi. To help you build it from scratch, there is a template file called “skeleton” inside that folder. Let’s copy paste it and create our own script.
# Let's create the scriptcd /etc/init.dcp skeleton petfeederbuttonssudo chmod +x petfeederbuttons
# Now, let's edit the filesudo vi petfeederbuttons
Now, for this tutorial to stay short and accessible, I’m not going to enter in the details of every line in the file. All you need to know is that we have to declare our script information in the INFO header. Then, we have to define the script location and the base commands : start, stop, restart !
Great ! Now you should be able to execute these commands :
sudo service petfeederbuttons startsudo service petfeederbuttons stop
Final steps ! Add the script for automatic boot launch :
# This creates a link to raspbian list of boot commandssudo update-rc.d petfeederbuttons defaults
Reboot your Pi and test your buttons directly to see the result !
The extra led for the food dispenser works fine when pressing the button, but doesn’t work when I run feed.py. Why ???
Our daemon is running the button listener script which is waiting for the feed button to be pressed in order to trigger feed.py. However, when the button is not pressed, the daemon is constantly setting the GPIO output to LOW
elseprint("FEED OFF - button led OFF")GPIO.output(FEED_BTN_LED_OUTPUT, GPIO.LOW)
Which means turning off the power. So what does happen when we run our feed.py manually or through our browser ? Our extra led will not be lightened since the daemon👺 is going to re-turn it off in a fraction of a second. There are two possible solutions here :
Choose the solution your prefer ! For me, I took the second one (the hard path if you want my opinion). Here is the solution, on your feed.py script.
import subprocess
# add this just before manipulating GPIO's
subprocess.Popen(['sudo /etc/init.d/petfeederbuttons stop'], shell=True, stdout=FNULL, stderr=subprocess.STDOUT)
# add this before cleaning up
subprocess.Popen(['sudo /etc/init.d/petfeederbuttons start'], shell=True, stdout=FNULL, stderr=subprocess.STDOUT)
However, our Apache server is running under the linux user “www-data”. And the command sudo on our daemon requires root privileges. So what now ?
# let's give the rights to Apache to run start/stop commands on our daemonsudo visudo
# Add this line under the root linewww-data ALL=(root) NOPASSWD: /etc/init.d/mochibuttons
Voila ! Now you have your prototype !! You just have to remove this from the breadboard and make it real using a perma-proto !
What’s next now ? It only depends on your imagination ! I personally decided to create a react-native application and use the URLS from the second tutorial to remotely control from my smartphone the camera and the food dispenser ! Take a look !
Tell me in the comments if you want me to do a last tutorial about my react-native app !
Thanks to all of you for reading this article series !