Controlling a Servo Motor with Gmail and Raspberry Pi

Sep 16, 2017

💬 52 comments

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)
GPIO Pinout Diagram

Here's what mine looks like (don't mind the zip tie):

Servo Connecting to Pi
Servo Connecting to Pi's GPIO

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:

  1. Setup an account if you haven't already
  2. Use IFTTT website or download the app to your phone and log in
  3. In the My Applets section, add a new applet
  4. You'll see a screen saying if +this then that: click the +this button, then select the Date & Time service.
  5. Select the Every day at trigger, and select the time you'd like the cat feeder to activate, then hit next
  6. 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.
  7. 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.

Thanks for reading! I'd love to hear your thoughts - if you have something you want to share feel free to leave a comment or shoot me an email.

Comments

Leave a Comment

  • Mike

    October 30, 2017 at 1:17:45 PM UTC

    Everything is working great expect for the pesky cron job. It just won’t run. I’ve always had issues getting python scripts to run using cron. Any ideas?

  • Sam Storino

    October 30, 2017 at 8:07:53 PM UTC

    Awesome, glad you’re making your way through the posts without much difficulty.

    I had trouble running a cronjob in the past and wrote a post about the findings. Check it out and let me know if it helps!

    https://storiknow.com/linux-cronjob-doesnt-execute-valid-python-script/

  • Carl

    January 10, 2018 at 2:55:29 PM UTC

    I must say this is one of the best tutorials I have seen. I particularly like the way you got me to check every step of the coding before proceeding to the next. I managed to troubleshoot every thing up to the Cron part Just Like Mike. I read the post you linked to on your blog and that line is in the script already. Im not sue what I have missed.

  • Sam Storino

    January 11, 2018 at 7:46:09 AM UTC

    That’s excellent to hear, I appreciate the feedback, Carl! I won’t pretend to be an expect in Cron jobs, but would start by ensuring you can run the script manually without issue. If you can then we can safely point the blame at the cronjob step. Here’s how:

    In the terminal:
    1) make the the script executable (chmod +x script.py) if you haven’t already
    2) navigate to the directory of the script and type: ./script.py

    If the script runs fine it all comes down to cron. Unfortunately, there could be any number of small issues here, ranging from security to simply adding a new line at the very end of the cron job. This [askubuntu](https://askubuntu.com/questions/23009/why-crontab-scripts-are-not-working) post really outlines a number of common gotcha’s.

    Hope that helps!

  • Carl

    January 11, 2018 at 9:19:01 AM UTC

    Thanks for the reply Sam
    It works perfectly when using python
    I have run the chmod +x script.py command but it said ‘not possible’ until I put sudo in front (maybe this is the issue). I am logged in as pi
    When I run the script using ./ I get the following
    from: cant read /var/mail/GmailWrapper

    ./CatFeeder.py: line6: import:command not found and several other lines up to line13
    Itried making GmailWrapper.py executable as well and checked the shebang no joy
    If I run ./GmailWrapper.py i get the same errors but listing imap client.
    Searching the error brings me back to the shebang error any Ideas gratefully received
    Carl

  • Gabe Byars

    January 17, 2018 at 4:24:57 PM UTC

    I got it to work by calling calling python in my cronjob

    **** python CatFeeder.py

    Hope this helps,

    Gabe

  • Sam Storino

    January 17, 2018 at 5:30:50 PM UTC

    That’s great, thanks for sharing Gabe. I believe Carl was able to resolve his issue by ensuring the SheBang tag was first and foremost in the script. If anything is before it, the python interpreter won’t be used by default.

  • liam

    March 8, 2018 at 10:01:56 AM UTC

    Do you know how to implement a camera into this?

  • Sam Storino

    March 8, 2018 at 8:11:53 PM UTC

    Hi Liam, I haven’t hooked one up before but have thought about it using the Pi Camera (https://www.raspberrypi.org/products/camera-module-v2/).

  • Andrew

    March 17, 2018 at 7:01:18 PM UTC

    For many of us I think the issue may be we don’t know where the scripts we created are stored.

  • Jankei Shinde

    April 8, 2018 at 6:12:43 AM UTC

    Hi Sam,
    Great project. Gotten down to making.

    I’m using a 12V dc motor 3.5 rpm instead of the servo. I’ve used a driver circuit for my motor.
    I’m implementing the same code, but the motor won’t run.
    How do I fix this?

    Please Revert asap as I’m on a time crunch.

    Thanks.

  • Sam Storino

    April 8, 2018 at 4:34:50 PM UTC

    I’ve never wired up/ controlled a DC motor before, so I can’t really give much advice here. There are a lot of tutorials online that should be able to help out.

    https://medium.com/@Keithweaver_/controlling-dc-motors-using-python-with-a-raspberry-pi-40-pin-f6fa891dc3d

  • Jankei Shinde

    April 8, 2018 at 4:41:40 PM UTC

    Alright, I’ll check them out.

    Thanks.

  • Jankei Shinde

    April 9, 2018 at 2:15:55 PM UTC

    Hey Sam,

    So I changed my motor to servo motor as it was a more efficient option considering I’m on a time crunch.
    Now my entire system is up and running with the email.

    I have two issues-
    1. How do I get the motor to run a complete circle in one direction, instead of left and right?
    2. When I schedule a cron job, it shows in the status that it’s running, but it actually isn’t. The email is not getting read automatically. Can you tell me why this could be happening and what can I do to fix this?

    Thanks.

  • Sam Storino

    April 9, 2018 at 4:34:14 PM UTC

    I’m glad to hear you’re making some good progress. Assuming you purchased the continuous rotation servo, you can have it rotate one direction by replacing lines `33` through `36` in the “GmailWrapper, Meet CatFeeder: Putting it all Together” section above with:

    servo.ChangeDutyCycle(2.5)
    time.sleep(3) # this is how long to rotate for

    As for the cronjob, if setup correctly it should just be making a call to execute your `CatFeeder.py` script. It’s possible you have errors in that script. You can check that by running it manually. In your terminal, navigate to the directory where your `CatFeeder.py` script lives, and type:

    ./CatFeeder.py

    If there’s an issue, the terminal should show an error. You’ll then need to investigate what went wrong. If it runs fine but the email doesn’t get read, there may be a logical error with the code itself, at that point you’ll just have to look in the code above and ensure you didn’t miss anything.

  • Jankei Shinde

    April 9, 2018 at 6:27:05 PM UTC

    Hi,

    Alright I’ll check through this. Will revert back.

    Thank you so much!

  • Jankei Shinde

    April 10, 2018 at 4:03:16 PM UTC

    Hey Sam,

    So I followed your instruction.
    The code for the motor didnt make my motor run according to it. I guess it started drawing more current from the Pi, cause it restarted it in the middle of it.

    As for the cronjob, I ran it in the terminal and got something as below. I’m a little confused because the code works just fine when I run it in the terminal. How do I resolve this issue.
    Please do help.

    pi@raspberrypi:~ $ ./PetFeeder.py
    from: can’t read /var/mail/GmailWrapper
    ./PetFeeder.py: line 3: import: command not found
    ./PetFeeder.py: line 4: import: command not found
    ./PetFeeder.py: line 6: HOSTNAME: command not found
    ./PetFeeder.py: line 7: USERNAME: command not found
    ./PetFeeder.py: line 8: PASSWORD: command not found
    ./PetFeeder.py: line 10: syntax error near unexpected token `(‘
    ./PetFeeder.py: line 10: `def feedByGmail():’

    Thanks.

  • Jankei Shinde

    April 10, 2018 at 4:42:36 PM UTC

    Hey Sam, Carl and Gabe,

    I had the same errors. Gabe’s solution really did help.
    Thanks a ton!

  • Jankei Shinde

    April 10, 2018 at 4:44:45 PM UTC

    Hey,

    Okay, Gabe’s solution above helped resolve my issues.
    Just the motor issue is left now. Help!

    Thanks.

  • Jake C

    April 26, 2018 at 6:45:14 AM UTC

    just had to comment how amazing this project is! me and my son built one together and its running great!! Only time i had trouble was for some reason google wouldnt auth (had spaces in app key).

  • Sam Storino

    April 26, 2018 at 2:16:25 PM UTC

    I’m glad you two enjoyed the project! That’s really great. Thank you for the feedback Jake.

    I’m working on a new tutorial for a cat laser toy, which should be up in the next few days. Stay tuned.

  • Rob

    May 10, 2018 at 2:00:35 PM UTC

    Hey Sam,

    I’m loving this tutorial but I’ve hit a stumbling block. I’m not able to make the servo rotate. I’ve followed your steps to the letter but id doesn’t move. When I run CatFeeder.py the servo makes a noise but doesn’t move.

    I’m using a different servo to the one you recommended. It’s a carson reflex cs3. Will this make any difference?

    Thanks in advance,
    Rob

  • Rob

    May 10, 2018 at 2:12:35 PM UTC

    Ignore this, I did something stupid
haha

  • Sam Storino

    May 10, 2018 at 7:59:11 PM UTC

    Ha! I can certainly say I know the feeling. I’m glad you were able to get it figured out, Rob. Thanks for the feedback in your other comment, it’s nice to hear the tutorial is working out for you. Feel free to reach out if you’re stuck in the future. Enjoy!

  • G

    June 21, 2018 at 8:10:46 PM UTC

    Got it to work by using Gabe’s suggestion for the cronjob script. Very cool project and the steps were straight forward. Thanks!

  • Sam Storino

    June 22, 2018 at 8:07:40 AM UTC

    Thanks for the feedback, G!

  • Kevin Smits

    July 10, 2018 at 12:58:54 PM UTC

    Hi Sam,

    Awesome project, thanks for sharing and answering questions.

    I also have a question on the servo script, for some reason I can’t get my servo to start turning.
    The servo is the FS5113R and I’ve followed your steps above. It does not provide any errors, but there is simply no movement.
    Is there any way to troubleshoot this?

    Also, when I enable pigpiod and use “set_servo_pulsewidth(18, 1600)” it does start spinning, however it also spins randomly afterwards.
    Are there any additional librabries or deamons required?

    Thanks in advance!

    Regards,
    Kevin

  • Sam Storino

    July 17, 2018 at 5:29:23 PM UTC

    Hi Kevin,

    If you’re able to make it move using the `pigpio` module, it may be worth continuing that route. It sounds like you’ve started the necessary daemon, and were able to at least get the motor to make an initial move. I don’t have experience with the `pigpio` library, but according to their documentation it looks like you may be able to do something like this:

    set_servo_pulsewidth(18, 1000) # rotate anti-clockwise safe
    time.sleep(1)
    set_servo_pulsewidth(18, 1500) # rotate center safe
    time.sleep(1)
    set_servo_pulsewidth(18, 2000) # rotate clockwise safe
    time.sleep(1)

    Be sure you’re performing a sleep between each change to allow the motor a chance to set itself.

    Here’s a forum post related to pigpio which may be helpful.

  • Kevin Smits

    July 18, 2018 at 3:43:57 AM UTC

    Hi Sam,

    Thank you for your reply.

    This is indeed exactly what I had and it works, however the issue I had is that if I leave it at 1500 at the end of the script it doesn’t fully stop (the stop() function does nothing) and it spins randomly after the script closes.
    Reading your link, I should change it to 0. Will definitely give it a try this evening!

    Again cool post(s) and thanks for sharing.

    Regards,
    Kevin

  • Justin

    August 10, 2018 at 7:57:18 PM UTC

    Hi, so far this guide is great! I am having problem with running the servo though. I bought the one you recommended but everytime I attempt to start it, power cycles on my pi. I have confirmed that I am wired up like you said and I don’t see any visible short in the cables. How did you determine which lead on the motor was what? I can’t seem to find a wire diagram for the motor.

  • Sam Storino

    August 10, 2018 at 9:09:39 PM UTC

    I’m glad you’re enjoying the guide! This sounds like a power issue. The motor draws a decent amount, so double check you’re not skimping out on the power supply. Check out the “parts” section of part one and compare your specs with the one I’ve posted there.

    I can’t recall exactly where I obtained the wiring information, but a quick search revealed this page which is pretty useful.

    https://www.pololu.com/product/2820/faqs

  • Carl

    September 22, 2018 at 5:11:08 PM UTC

    Hi Sam,

    Fantastic job on detailing this! It works perfect with a pizero. I want to keep the rotations of the servo but want to reduce the food output by half. I suspect this has to do with line 35 but I haven’t figured out how to reduce the rotation of the servo. I keep putting too much food out.

  • Carl

    September 22, 2018 at 9:08:59 PM UTC

    Sam,

    Just figured out to just reduce the time.sleep(X). I’d still love to know how the LRL is coded. Would that be in the servo GPIO documentation or in python?

  • Richard Campbell

    September 25, 2018 at 11:22:29 PM UTC

    Sam,
    For some reason after I did the cronjob the servo will turn every 60 seconds. I haven’t sent an email in the last 30 minutes but it keeps turning every 60 seconds?? Also, you added a link with the Monitoring script. Where do we get the code for the monitoring script?

    Thanks

    Richard

  • Sam Storino

    September 26, 2018 at 7:53:16 AM UTC

    Hey Carl. Apologies for the delay. I’m glad you’re experimenting with the code a bit, it’s interesting to see what happens when you start modifying things.

    The code responsible for rotating the motor left, right, then left again is in the first block of code above, line 18:

    `dutyCycle = 2.5 if (index % 2 == 0) else 12.5`

    2.5 translated to 0 degrees, while 12.5 is 180 degrees (7.5 is 90 degrees etc
). By modifying the sleep time you’ve given the motor less time to get to its destination degree, which is why it reduced the output. It’s still trying to hit 0 and 180, but only making it a portion of the way, and that’s ok!

    I hope that helps. For further reading you can look up Pulse Width Modulation and Duty Cycle.

  • Sam Storino

    September 26, 2018 at 8:02:57 AM UTC

    Hey Richard. It sounds like your email isn’t successfully being marked as read after the script runs. Can you verify this? Make sure you don’t have any unread emails, then send yourself one with the correct subject (e.g. Feed cats). Once the servo spins, check that your email is marked read. If for some reason it isn’t, or it becomes unread (or another email is sent to that email box), you’ll see the motor continue to spin.

    As for the monitoring script, I couldn’t find a reference to that in the code above. Would you mind pointing me to it? Regardless, that script isn’t necessary for this project.

  • Richard

    September 26, 2018 at 11:59:02 AM UTC

    Sam,

    Thanks for getting back to me so quickly. I am actually trying to help a fifth grader finish this project for Maker Faire Seoul this weekend!!
    When I send a feed cats email it take a pretty long time to go through and then nothing.
    Thanks
    Richard

  • Richard

    September 26, 2018 at 12:03:44 PM UTC

    Ok, so I found a mistake in the crontab. The command I entered had Catfeeder.py (Now CatFeeder.py) So now I am back to every 60 seconds the servo turns. I sent two emails, only one came through so far and it was read. But now I don’t have any unread emails in my inbox but the servo still turns every 60 seconds???

    Thanks

    Richard

  • Sam Storino

    September 26, 2018 at 12:33:50 PM UTC

    Interesting. It sounds like you have cron figured out at this point, and marking an email as read doesn’t seem to be an issue. All signs are pointing to the steps before that responsible for determining if a valid email is found/ should the feeder be triggered. If you just run the script normally, without the help of cron, does that trigger the feeder?

  • Sam Storino

    September 26, 2018 at 12:48:29 PM UTC

    That’s fantastic! I just took a look at your linked website, you’re doing some very incredible work. If you’re still stuck after reading my response to your latest comment, send me a direct email to “sam@storiknow.com” with all the files you’re using attached. I can take a deeper looked to see if any of the code seems out of sorts.

  • Richard

    September 26, 2018 at 12:57:59 PM UTC

    Yes, when I run the python
    import CatFeeder
    CatFeeder.feedByGmail()

    It will turn the servo and read the email.

  • Sam Storino

    September 26, 2018 at 4:33:21 PM UTC

    Right, but when you don’t have any “unread” emails in your account and you run the script, does it still turn the servo?

    To avoid bloating the comments, shoot me an email (sam@storiknow.com) with the response and the code files attached, I’ll take a look and see if anything is out of sorts.

  • Richard

    September 26, 2018 at 8:01:34 PM UTC

    Sam,
    I was able to find the problem. In the last line of the CatFeeder.py code I had an extra line from the original code feed() Once I took that out everything is working fine!!
    Now on to the scheduler!!
    Thanks for your help!

    Richard

  • Sam Storino

    September 26, 2018 at 8:33:16 PM UTC

    Excellent work. Best of luck at the maker faire!

  • Dylan Eave

    January 9, 2019 at 5:12:59 PM UTC

    Hi there Sam. I am another one of your very grateful readers. I am using the your concept to override a simple borehole pump controller which pumps water for over 800 people.

    Sadly I cannot get the system working as a python script. If I run the commands individually at the python interpreter it all work just fine.

    If I have an email unread in the inbox which has a matching subject line (“Stop-Borehole-A”), the code will detect this (as evidenced by a ids number returned) but a fault occurs when trying to mark this email as read.

    Running the code below results in the following:

    pi@raspberrypi:~ $ sudo python timer_by_email.py
    Logging in as thosethreetowers
    [56]
    Low
    Failed to stop pump

    The code is pasted below — I hope you will be able to assist me in resolving this:

    #!/usr/bin/env python

    from GmailWrapper import GmailWrapper

    import RPi.GPIO as GPIO
    import time

    HOSTNAME = ‘imap.gmail.com’
    USERNAME = ‘thosethreetowers’
    PASSWORD = ‘oret pyzj czml xowv’

    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(18, GPIO.OUT)

    gmailWrapper = GmailWrapper(HOSTNAME, USERNAME, PASSWORD)

    def StartByGmail():
    ids = gmailWrapper.getIdsBySubject(‘Start-Borehole-A’)
    if(len(ids) > 0):
    print(ids)
    try:
    print “High”
    gpio.output(18, gpio.HIGH)
    sleep (5)
    gmailWrapper.markAsRead(ids)
    except:
    print(“Failed to start pump”)
    quit()

    def StopByGmail():
    ids = gmailWrapper.getIdsBySubject(‘Stop-Borehole-A’)
    if(len(ids) > 0):
    print(ids)
    try:
    print “Low”
    gpio.output(18, gpio.Low)
    sleep (5)
    gmailWrapper.markAsRead(ids)
    except:
    print(“Failed to stop pump”)
    quit()

    if __name__ == ‘__main__’:
    # kick off the feeding process (move the servo)
    # we now use our new feedByGmail method to handle the feeding
    StartByGmail()
    StopByGmail()

  • Dylan Eave

    January 9, 2019 at 5:14:45 PM UTC

    I am not concerned about the password details shared. These will be modified following resolution of this problem. 🙂

  • Dylan Eave

    January 9, 2019 at 5:15:37 PM UTC

    I also do believe that my white space in code is all correct.

  • Dylan Eave

    January 10, 2019 at 9:33:18 AM UTC

    I wish to thank Sam for contacting me directly with the solution 🙂 — A simple case of case error 😉

    Many many thanks for this well written tutorial — Your system is now used also as a means of controlling a large pump and set of solenoid valves which direct water to various places 🙂

  • EUSTACHE Thibaut

    February 15, 2019 at 5:31:27 AM UTC

    Great tutorial, it works very well.
    Is it possible to go from 60 seconds to 10 seconds for the cronjab?

  • Sam Storino

    February 15, 2019 at 4:49:11 PM UTC

    Thanks for the feedback, it’s good to hear the tutorial was easy enough to follow.

    As far as I’m aware, cron only allows minimum 1 minute intervals.

    If you need to run this more frequently, you’ll need to take a different approach to the problem. I just so happen to have taken an alternative approach in my Automatic Laser Pointer series. There, I run the script when the Raspberry Pi boots up, and have it running continuously, rather than every 60 seconds via cron. I log into Gmail initially at launch of the script, then every 30 seconds it scans for new emails.

    Technically you could alter this to check every 10 seconds. However, too much activity to a single Gmail account could look suspicious from Google’s perspective, and may result in an account lock. With that said, I haven’t tested the thresholds as I haven’t had a need for instantaneous feedback.

    Hope that helps!

  • navi

    March 11, 2019 at 2:53:08 PM UTC

    i have error on ImportError: No module named ‘GmailWrapper, can you help?

  • Sam Storino

    March 11, 2019 at 3:18:06 PM UTC

    Hi Navi,

    I can give it a shot. To avoid bloating the comments, shoot me a message through the “Contact” page with the code you’re trying to run. This way I can take a look.