Controlling a Servo Motor with Gmail and Raspberry Pi
You covered part one and part two (good work!), or maybe you didn’t and you found yourself here anyway (welcome). Part three is focused on the servo motor, primarily making it spin. Later in part four we’ll wrap things up by connecting it to the dispenser.
As always, let’s start with what it is we’re trying to accomplish here:
- Connect the servo motor to the Raspberry Pi’s GPIO header pins
- Write some code to make that motor functional
- Tie in the GmailWrapper.py script we wrote in part two so the motor spins when the right email lands in your inbox
Here we go!
Connecting the Servo Motor to the Raspberry Pi
If you’re using the same servo motor as me, it has power, ground and control wires. If you decided to use the standard non-continuous servo motor (which is a viable alternative since we won’t be performing a full revolution), then: power is red, ground is black and white is control.
Connect your male-to-female jumper cables to the servo. Now, using the GPIO diagram below as reference, connect the wires to the Pi’s GPIO headers as follows:
Note: this diagram is for Raspberry Pi’s with 40 pin GPIO, but the below works with 26 pin GPIO as well.
- power connects to header pin 2 (5v power)
- ground (black wire for standard servo) connects to header pin 6 (Ground)
- control (white for standard servo) connects to header pin 12 (GPIO18)
Here’s what mine looks like (don’t mind the zip tie):
Writing Code to Make the Servo Motor Spin
Before getting started, let’s update our Pi to the latest packages and install the GPIO library. Run this in the terminal:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install rpi.gpio
We’re all set. In the terminal, create a new python script using nano: sudo nano CatFeeder.py
Within the CatFeeder.py script, add the following code:
#!/usr/bin/env python import RPi.GPIO as GPIO import time def feed(): # let the GPIO library know where we've connected our servo to the Pi GPIO.setmode(GPIO.BCM) GPIO.setup(18, GPIO.OUT) try: servo = GPIO.PWM(18, 50) servo.start(12.5) # spin left, right, then left again rather than in a continuous circle # to prevent the food from jamming the servo for index in range(0, 3): dutyCycle = 2.5 if (index % 2 == 0) else 12.5 servo.ChangeDutyCycle(dutyCycle) # adjust the sleep time to have the servo spin longer or shorter in that direction time.sleep(0.8) finally: # always cleanup after ourselves servo.stop() GPIO.cleanup() if __name__ == '__main__': # kick off the feeding process (move the servo) feed()
Save and exit the nano editor: CTRL+X
, then Y
, then Enter
. Moment of truth, time to make that servo move! Let’s drop back into the Python interpreter, in the terminal:
# remember, hit enter after each line to have the interpreter... interpret python import CatFeeder CatFeeder.feed()
I hope that went smooth for you, because I just got really excited. Welcome to physical computing! You moved a physical object with code, hell yeah.
GmailWrapper, Meet CatFeeder: Putting it all Together
Alright, so we’ve created a way to read emails, and we’ve created a way to move a servo motor. Now we need to combine the two so the servo motor moves when we read emails.
Open CatFeeder.py in nano and add the highlighted lines of code: sudo nano CatFeeder.py
#!/usr/bin/env python from GmailWrapper import GmailWrapper import RPi.GPIO as GPIO import time HOSTNAME = 'imap.gmail.com' USERNAME = '<your gmail username>' PASSWORD = '<your app password or regular gmail password>' def feedByGmail(): gmailWrapper = GmailWrapper(HOSTNAME, USERNAME, PASSWORD) ids = gmailWrapper.getIdsBySubject('feed cats') if(len(ids) > 0): try: feed() gmailWrapper.markAsRead(ids) except: print("Failed to feed cats, they're starvingggg") def feed(): # let the library know where we've connected our servo to the Pi GPIO.setmode(GPIO.BCM) GPIO.setup(18, GPIO.OUT) try: servo = GPIO.PWM(18, 50) servo.start(12.5) # spin left, right, then left again rather than in a continuous circle # to prevent the food from jamming the servo for index in range(0, 3): dutyCycle = 2.5 if (index % 2 == 0) else 12.5 servo.ChangeDutyCycle(dutyCycle) time.sleep(0.8) finally: # always cleanup after ourselves servo.stop() GPIO.cleanup() if __name__ == '__main__': # kick off the feeding process (move the servo) # we now use our new feedByGmail method to handle the feeding feedByGmail()
Save and exit the nano editor: CTRL+X
, then Y
, then Enter
. As always, let’s give it a test. Send yourself an email with the subject feed cats. Drop into the python interpreter once the email arrives:
python import CatFeeder CatFeeder.feedByGmail()
Did it work? It did? Excellent! If it didn’t, don’t be discouraged! Python’s support community is huge, you’ll find the answer. Plus, you can always leave a comment below.
Scheduling a Cron Job to Run Our Script Regularly
We have code to move our servo motor when the correct email lands in our inbox, but it currently only runs when we physically tell it to. Let’s fix that by setting up a cron job to run our script every 60 seconds.
In order for the cron job to execute our script, we need to make our script executable. This is done by issuing the following command in the terminal: sudo chmod +x CatFeeder.py
Now we’ll add the cron job. In the terminal: crontab -e
. Add the following after the very last commented line (comments start with #
):
* * * * * python /path/to/your/script/CatFeeder.py
As Gabe called out in the comments, adding python
after the last asterisk (*) in the line above will force the python interpreter to be used while running our script. We’re in the nano editor, so save and exit: CTRL+X
, Y
, Enter
. Easy as Pi (sorry). A job is now running every 60 seconds with the sole task of looking for emails and feeding cats. Don’t believe me? Give it a shot, send yourself an email with the subject feed cats.
A nicety of cron jobs is they’ll continue running automatically if your Pi ever restarts.
Scheduling an Email to be Sent Regularly
We have the code, we have the cron job. Sending an email on demand will cause the servo motor to spin, but what about spinning it on a schedule? That’s where we’ll make use of IFTTT. IFTTT stands for if this then that and allows you to connect two disparate systems based on what they call a “recipe” (trigger and action). For our purpose, we need the clock to trigger an email to be sent (action). Here’s what to do:
- Setup an account if you haven’t already
- Use IFTTT website or download the app to your phone and log in
- In the My Applets section, add a new applet
- You’ll see a screen saying if +this then that: click the +this button, then select the Date & Time service.
- Select the Every day at trigger, and select the time you’d like the cat feeder to activate, then hit next
- Now you’ll see +that, click it and find the Gmail service. You’ll need to connect the service to your Gmail account. Once finished, set the action to Send yourself an email with the subject Feed cats.
- Hit next, then Finish
There you have it, every day at the time you specified an email will be sent to your account. If you had any issues setting up the IFTTT recipe, check out this post for a really nice and in-depth walk-through.
Having fun? Here’s Other Ways to Send an Email
Alexa
Alexa integrates nicely with IFTTT. In the IFTTT app, create a new recipe with the trigger (+this) connecting to Alexa. You’ll need to connect the service like you did for Gmail. Once connected, set the action (+that) to send an email, like we did in the previous section.
Hands free feeding at your ready: Alexa, trigger the cat feeder.
The DO Button App
Created by the IFTTT team, the DO Button app and accompanying widget provides a straightforward way to trigger the action. You! You’re the trigger. You setup a recipe, same as before, except you’ll notice there’s no +this. You are the +this. You open the app and click the button, it then triggers an email. This app can also be configured to show on your iPhone or Androids home screen, so triggering the email is even easier.
Conclusion and Next Steps
Part one has goals and items covered, part two has Gmail automation down, and part three provided the spinning of the motor. A lot has been done so far, we’re nearly there. Up for part four? That’s where I’m headed to connect the Pi and motor to the dispenser.
Hi, I’m Sam.
I’m a programmer and a DIYer. When I’m not finding things to build I enjoy cooking, hiking, camping and traveling the world with my best friend. Say Hello!