Create the rotation script in Python

Now let’s get back to our servo ! We need to build the script that is going to trigger it. While the RaspberryPi (& Raspian) run Python out-of-the-box, you need to install pip for easy installation/removal of packages. On your raspberry Pi, type :



curl # Install python pip package managercurl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

Thanks to pip, we are now able to download and use a super usefull library to manipulate by code the raspberry PI electronic pins.

pip install RPi.GPIO

Now lets create our servo script !

# Create the directory

mkdir pet-feeder

cd pet-feeder # Create the file with execution rights

touch feed.py

chmod +x feed.py

How to use the servo controller

Everything is ready, we can start coding. What we want to do is control the servo by sending electricity pulses into the control wire of the servo. That’s the way is works. Referring to Adafruit documentation we have this :

Position "90" (1.5ms pulse) is stop, "180" (2ms pulse) is full speed forward, "0" (1ms pulse) is full speed backwards

This means that, as long as the control wire is receiving electricity pulses (with a duration of 2ms each), the servo will continuously go forward at full speed.

But.. the Pi is only capable of delivering a constant current of 3V through the GPIOs, how am I going to make pulses ?

The library RPi.GPIO that we installed earlier has everything we need ! What we want to use is called “Pulse wave modulation”. You can import it in your Python script like this.

##!/usr/bin/env python

import RPi.GPIO as GPIO

Now, let’s configure the library with our plugged servo. First, set the mode to BCM in order to have your pins matching the GPIO names and NOT the physical locations.

GPIO.setmode(GPIO.BCM)

Next, let’s setup which pin is going under our control. If you took the BCM18 like in the picture above, then :

FEED_SERVO_CONTROL_PIN = 18

GPIO.setup(FEED_SERVO_CONTROL_PIN, GPIO.OUT)

Finally, let’s initiate the pulse wave modulations to activate the servo forward movement. To do this, you’ll have to play with two variables : frequency and duty cycle in order to reach the required pulses. (1.5ms pulse is stop, 2ms pulse is forward, 1ms pulse is backwards)

Frequency is the amount of pulses there are going to be per second. It is always expressed in Hertz. Example :

1 hertz = 1 pulse / second → 1 pulse = 1 second

100 hertz = 100 pulse per second → 1 pulse = 10ms

Duty cycle is the fraction of one period in which a signal is active. In simple terms, the percentage of active signal during a pulse. Example :

A pulse of 10ms with a 10% duty cycle is 1ms of active signal

A pulse of 10ms with a 20% duty cycle is 2ms of active signal

Wait… isn’t it the exact pulses we’re looking for ? Yes !! we have our variables all set !

# Import time to manage servo activation duration

import time # Let's set the frequency and dutycycle

PWM_FREQUENCY = 100

FULL_SPEED_FORWARD_DC = 20

FULL_SPEED_BACKWARD_DC = 10 # Activate the servo !

pwm = GPIO.PWM(FEED_SERVO_CONTROL_PIN, PWM_FREQUENCY)

pwm.start(FULL_SPEED_FORWARD_DC) # Let it run for 3 seconds

time.sleep(3) # Let's go backward now !

pwm.ChangeDutyCycle(FULL_SPEED_BACKWARD_DC)

time.sleep(3) # Stop and Clean everything

pwm.stop()

time.sleep(0.5)

GPIO.cleanup() # Very important !

Ready to try out your script ? Save your code and launch it using :

# and the magic appears

python feed.py

Script summary

Launch your script from a browser

Let’s move further and launch our script though a browser instead of typing command lines in the terminal. First of all, we need to have a local server on our Pi, capable of running python scripts.

Download and install Apache on Raspberry Pi

# Install apache

sudo apt-get install apache2

# Make it Python friendly

sudo a2enmod cgid

By default, Apache will create a test file under /var/www/html/index.html. Copy paste your directory next to that file.

mv ~/pet-feeder /var/www/html

Finally, make Apache able to read our script inside this particular folder.

# open the file as root

sudo vim /etc/apache2/sites-enabled/000-default

Add the python cgi-script handler to it.

Finally restart apache and test everything in your computer browser directly !

# Restart Apache

sudo service apache2 reload # Find out your Pi IP address

ip addr show wlan0 | grep inet # Go to your computer browser

http:<IP_ADDR>/pet-feeder/feed.py

Launching the script through my browser

Launch the script from internet (router and server configurations)

If you didn’t follow the previous tutorial, I strongly recommend you to check it out. You’ll have to do exactly the same thing ! However this time, we will change the redirection port. Previously, we were handling request from port 8081 because it is the camera stream server. Now, we also want to handle requests from port 80, simply because it is apache default port.

To do that, we simply add another Port Forwarding rule to our router. Please find all the explanations on the “Configure the port forwarding to your PI” section. At the end, that’s how it should look like.

The important part here is the redirecting rule 80:80

We are actually telling our router: Please redirect all outside world request coming in with port 80 to the raspberry Pi on port 80.

Reboot your router to take account of the new port forwarding rule. and let’s find out if it works !

https://<your_ddns_name>.dyndns.com:80/pet-feeder/feed.py

Just like on the previous tutorial, try this with a different connection than your home. For example, on your smartphone 4G. When being inside your local network, trying to use the DDNS may not work. This is a limitation with routers.

VICTORY !

(Optional) Want a little extra ?

What about making a daily task that will give a treat to our pet every couple hours ? Does that sounds cool 🐇? Here you go !

Crontasks

Crontasks are instructions that you can configure to execute desired tasks (in the background) at designated times.

# Open the crontab panel

crontab -e # Add your feeding task

# FEED PET EVERY DAY AT 9AM AND 6PM

0 9,18 * * * python /var/www/html/pet-feeder/feed.py >/dev/null 2>&1

The five time-and-date fields are as follows: minute (0–59), hour (0–23, 0 = midnight), day (1–31), month (1–12), weekday (0–6, 0 = Sunday).