Check out the new MinnowBoard.org website for the most up-to-date information on the MinnowBoard Turbot and the MinnowBoard.org Community.

Projects/AdaFruit GPIO

From MinnowBoard Wiki
Revision as of 16:07, 14 May 2015 by Dbkinder (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Adafruit Python GPIO

This document describes the capabilities of the Adafruit Industries Python GPIO library for use on embedded devices. It will focus on how to configure the library for use with the Raspberry Pi, Beaglebone Black, and Minnowboard MAX. This document is not yet fully complete. Currently, it only focuses around the GPIO and SPI implementations for the three aforementioned devices. Additional documents for PWM and other features will be added as they are ported over to the Minnowboard MAX, as this document follows development for that device.

Introduction

Purpose

The purpose of the Adafruit Python GPIO library is to provide ease of use and cross-compatability to embedded devices when working with their GPIO features. The library does not require special kernel drivers or modifications, only depending on pre-existing low-level libraries in each device. These dependencies are (click to go to download link):

Raspberry Pi
RPi.GPIO Library
Beaglebone Black
Adafruit Beaglebone Library
Minnowboard MAX
mraa Library

These dependencies are subject to change, and the library will be expanded in the future to incorporate new developments. They may already be present in your operating system, or you may need to install them.

Checking Dependencies

Now that you've installed the correct GPIO library for your system, open a Python interpreter with the python command, to get this prompt:

$ python
Python 2.7.3 (default, Apr 13 2015, 19:12:05) 
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

With your shell open, attempt to import the correct GPIO library into your shell to confirm that you have it installed correctly.

For RPI.GPIO:

>>> import RPi.GPIO

For Adafruit_BBIO:

>>> import Adafruit_BBIO.GPIO

For mraa:

>>> import mraa

Should the one for your platform fail to import, make sure you installed it correctly.

Using the Library

No matter which platform you're using, the Adafruit GPIO Python library can detect and adapt, allowing you to use the same API across any platform. While some exceptions exist, this holds true for most of the library.

GPIO

Here are the basic functions that you can use to access the GPIO pins:

GPIO.setup(pin,mode)
Define a pin to use for GPIO. Make sure you follow your library convention for pin names. For instance, mraa uses the physical pin identifiers, whereas RPi.GPIO may refer to them by the system numbers or physical numbers depending on configuration. The mode can either be OUT (for pin output) or IN (for pin input)
GPIO.output(pin,value)
Set the specified in to the provided value. Valid values are HIGH (True or 1) or LOW (False or 0), pin needs to be set up for output.
GPIO.input(pin)
Read the specified pin and return the value of the pin. It will return HIGH/True if the pin returns high, or LOW/False if it returned low.
GPIO.set_high(pin)
Set the specified in to HIGH. Equivalent to GPIO.output(pin,HIGH)
GPIO.set_low(pin)
Set the specified in to HIGH. Equivalent to GPIO.output(pin,LOW)
GPIO.is_high(pin)
Returns TRUE if the pin is HIGH. Equivalent to GPIO.input(pin) if the pin was HIGH.
GPIO.output_pins(pins)
Set a set of pins to HIGH or LOW at once. Pins should be input as a dictionary of pins to pin values, being HIGH or LOW. Each pin in the set will be set to the given value.
GPIO.setup_pins(pins)
Define a set of pins at once with the indicated directions. Pins should be input as a dictionary of pins to pin directions, being IN or OUT. Each pin in the set will be setup with the given value.
GPIO.add_event_detect(pin,edge)
Enable edge detection events for the specified pin. Pin needs to be defined for IN. Edge monitoring can be defined as RISING, FALLING, or BOTH.
GPIO.remove_event_detect(pin,edge)
Disable edge detection events for the specified pin. Pin needs to be defined for IN.
GPIO.add_event_callback(pin, callback)
Add a callback for an enabled pin. Pin needs to be defined for IN and enabled for edge detection.
GPIO.event_detected(pin)
Returns TRUE when edge has occured on the given pin. Pin needs to be defined for IN and enabled for edge detection.
GPIO.wait_for_edge(pin, edge)
Wait until an edge occurs on the specified pin. Pin needs to be defined for IN and enabled for edge detection. Edge monitoring can be defined as RISING, FALLING, or BOTH.
GPIO.cleanup(pin)
Clean up GPIO event detection for the specified pin. If no pin is specified, all pins will be affected.

GPIO Sample Code

Run these examples simply by placing the code in a python script and running python example.py from the command line. Although these functions are for the Minnowboard MAX, the library allows you to use these scripts on other platforms such as the Raspberry Pi and Beaglebone Black, just change the pin numbers to suit your setup.

Blink an LED connected to Minnowboard GPIO pin 23:

import time
import Adafruit_GPIO as GPIO

# Pin configuration.
pin = 23 

# Create instance of GPIO for our platform 
myGPIO = GPIO.get_platform_gpio()

# Setup the pin for signal going out
myGPIO.setup(pin,GPIO.OUT)

# Start infinite loop
while True:
    
    # Turn the pin on, wait for half a second, turn it off, wait half a second
    myGPIO.output(pin,1)
    time.sleep(0.5)
    myGPIO.output(pin,0)
    time.sleep(0.5)

Set an interrupt to trigger when Minnowboard GPIO pin 25 receives power from a button press:

import time
import Adafruit_GPIO as GPIO

def test(args):
    print "Interrupted!" 

# Pin configuration.
myGPIO = GPIO.get_platform_gpio()
PIN = 25

myGPIO.add_event_detect(PIN,GPIO.BOTH,test,None)

time.sleep(10)
myGPIO.remove_event_detect(PIN)

SPI

The library also provides an easy to use interface to access the Serial Peripheral Interface (SPI) through both software and hardware. In order to read and write using native SPI hardware, your board needs to support it, either through the firmware or a module, and you'll need the Linux spidev or the mraa library.

To check to see if you have any SPI devices, just run

# ls /dev/spi*

If SPI is working, you'll see this:

/dev/spidev0.0

The first digit is the port, and the second one is the device

If it is not, probably because you don't have it enabled in software or you don't have the module installed, you'll see this:

ls: cannot access /dev/spi*: No such file or directory

To create a hardware instance of SPI, create an object like this:

# Import the needed libraries
import Adafruit_GPIO.GPIO as GPIO
import Adafruit_GPIO.SPI as SPI

# You'll need to note the device and port
SPI_PORT = 0
SPI_DEVICE = 0

# Create an object, be sure to change the max speed to match your board)
spi = SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=64000000)

If you don't have SPI available, you can also create an object using GPIO like so:

# Import the needed libraries
import Adafruit_GPIO.GPIO as GPIO
import Adafruit_GPIO.SPI as SPI

# You'll need to note the clock, the master-out-slave-in, 
# the master-in-slave-out, and the chip select pins here
SCLK = 23
MOSI = 21
MISO = 20
SS = 18

# Create the object
spi = SPI.BitBang(GPIO.AdafruitMinnowAdapter(mraa), SCLK, MOSI, MISO, SS)

In order to use BitBang, you need to pass the correct GPIO adapter as the first argument to the BitBang method. The example above was for the Minnowboard MAX, but you can do the same for other boards like so:

Raspberry Pi

GPIO.RPiGPIOAdapter(RPi.GPIO)

Beaglebone Black

GPIO.AdafruitBBIOAdatper(Adafruit_BBIO.GPIO)

Now you can use the following methods:

SPI.set_clock_hz(hz)
Sets the clock speed of the SPI bus in hertz. Check your board for the correct speed or you may fail to communicate with the device. This method does nothing in BitBang mode.
SPI.set_mode(mode)
Sets the SPI mode, which controls the clock polarity and phase. The valid values are 0, 1, 2, or 3. For more information, see this page.
SPI.set_bit_order(order)
Sets the order to read bits over the serial interface. Your two options are MSBFIRST (most-significant first) or LSBFIRST (for least-significant first).
SPI.close()
Closes communication with SPI device.
SPI.write(data)
Writes specified array of bytes to the master-out-slave-in line.
SPI.read(length)
Reads data of specified length as a bytearray through the master-in-slave-out line.
SPI.transfer(data)
This is a full-duplex read/write, so you can transfer a bytearray and get a bytearray back of the same size as your sent bytearray. Both data transfer lines will be used.

SPI Sample Code

SPI code is heavily dependent on the device you're communicating with, so we'll put some code here once we've decided on a device to focus on.