Using the RPi.GPIO module with Python 3

As stated in the previous article of our furnace control project, Raspian comes pre-installed with a Python module to interact with the GPIO header. However, this module is installed for Python 2.7 only; trying to import RPi.GPIO using Python3 raises an ImportError.

Installing the RPi.GPIO module for Python 3 is actually quite simple.

First of all, before installing any software it’s always a good idea to update repository information. Run this command:

sudo apt update

This updates software repository information: ensures package lists are up to date, and so on. When this command completes, go ahead and install available updates:

sudo apt upgrade

Confirm upgrades when prompted, by entering Y for yes; let it proceed. When updates are finished running, it’s time to install the GPIO module for Python 3:

sudo apt install python3-rpi.gpio

The appropriate packages should download and install. When done, verify that you can import the module using Python 3:

$ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170124] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO
>>>

As you can see, the “import RPi.GPIO” command returned no output. This is a good sign; it means the module was imported successfully. Now quit the Python prompt:

quit()

Now you can run your GPIO projects with Python 3 if you prefer.

My furnace control script’s Print statements needed some help. One of the most obvious differences (to a beginner like me, at least) between Python 2 and Python 3 lies in the format of print statements. In Python 2, this works:

$ python
Python 2.7.13 (default, Nov 24 2017, 17:33:09)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "hello world"
hello world
>>>

Using Python 3, the same command fails.

$ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170124] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print "hello world"
  File "<stdin>", line 1
    print "hello world"
                      ^
SyntaxError: Missing parentheses in call to 'print'
>>>

The error message is helpful: we’re missing parentheses. Let’s modify our print statement so Python 3 is happy.

>>> print ("hello world")
hello world
>>>

 

So basically, Python 3 requires you to enclose print statements in parentheses to be more consistent with syntax of other functions. There’s no reason not to do this even when using Python 2.7 though; it accepts them either way, and using parentheses is good form and ensures your code is more readily portable to version 3.

Now, back to the first version of the furnace control script. My print statements looked like this one:

print("Furnace turned on for %d seconds. Cycle %d of %d.") % (ontime, cycle, runcycles)

See a problem? The entire print statement is not enclosed in parentheses. For python3 compatibility, I had to modify my statements like so:

print("Furnace turned on for %d seconds. Cycle %d of %d." %(ontime, cycle, runcycles))

Very simple modification, but that’s all it took to make it work. Presently the whole script is as follows:

# Import necessary modules
import RPi.GPIO as GPIO
import time

# Set up GPIO pins
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
pins = [17,18]
for pin in pins:
    GPIO.setup(pin,GPIO.OUT)
    GPIO.output(pin,1)

# Set variables (change these to change behaviour as desired)
runcycles = 2
ontime = 45 # minutes
offtime = 20 #  minutes

# Convert run times from minutes to seconds for sleep function
ontime *= 60
offtime *= 60

# Run furnace on cycle
cycle = 0

try:
    while cycle < runcycles:
        cycle += 1
        GPIO.output(17,0)
        print("Furnace turned on for %d seconds. Cycle %d of %d." %(ontime, cycle, runcycles))
        time.sleep(ontime)
        GPIO.output(17,1)
        if cycle == runcycles:
            break
        print("Furnace paused for %s seconds. %s heat cycles remaining." %(offtime, runcycles - cycle))
        time.sleep(offtime)

except KeyboardInterrupt: # if Ctrl C is pressed...
    GPIO.output(17,1) # shut off the boiler
    print("Program stopped and furnace shut off.") # print a clean exit message

print("Heat cycles completed.")

And now I can run the script using python2 or python3 and it makes no difference either way.

You may also like...

Leave a Reply