Tuesday, March 05, 2013
RPIO Python module learning notes
Now I am reading about RPIO Python module.
RPIO, the Python module
http://pythonhosted.org/RPIO/rpio_py.html
RPIO.py extends RPi.GPIO in various ways, and uses the BCM GPIO numbering scheme by default.
GPIO Interrupts
TCP Socket Interrupts
GPIO Input & Output
Hardware PWM
GPIO & TCP Interrupts
RPIO can listen for two kinds of interrupts: GPIO and TCP. GPIO interrupts happen when the state on a specific GPIO input changes. TCP interrupts happen when a TCP client connects to the built-in TCP server and sends a message.
GPIO Interrupts
Interrupts are used to receive notifications from the kernel when GPIO state changes occur. Advantages include minimized cpu consumption, very fast notification times, and the ability to trigger on specific edge transitions (rising, falling or both). You can also set a software pull-up or pull-down resistor.
RPIO.add_interrupt_callback(gpio_id, callback, edge='both', pull_up_down=RPIO.PUD_OFF, threaded_callback=False)
Adds a callback to receive notifications when a GPIO changes it’s value. Possible pull_up_down values are RPIO.PUD_UP, RPIO.PUD_DOWN and RPIO.PUD_OFF (default). Possible edges are rising, falling and both (default). Note that rising and falling edges may receive values not corresponding to the edge, so be sure to double check.
TCP Socket Interrupts
Its easy to open ports for incoming TCP connections with just this one method:
RPIO.add_tcp_callback(port, callback, threaded_callback=False)
Adds a socket server callback, which will be started when a connected socket client sends something. This is implemented by RPIO creating a TCP server socket at the specified port. Incoming connections will be accepted when RPIO.wait_for_interrupts() runs. The callback must accept exactly two parameters: socket and message (eg. def callback(socket, msg)).
The callback can use the socket parameter to send values back to the client (eg. socket.send("hi there\n")). To close the connection to a client, you can use socket.close(). A client can close the connection the same way or by sending an empty message to the server.
You can test the TCP socket interrupts with $ telnet <your-ip> <your-port> (eg. $ telnet localhost 8080). An empty string tells the server to close the client connection (for instance if you just press enter in telnet, you’ll get disconnected).
Example
The following example shows how to react to events on three gpios, and one socket server on port 8080:
import RPIO
def gpio_callback(gpio_id, val):
print("gpio %s: %s" % (gpio_id, val))
def socket_callback(socket, val):
print("socket %s: '%s'" % (socket.fileno(), val))
socket.send("echo: %s\n" % val)
# Three GPIO interrupt callbacks
RPIO.add_interrupt_callback(7, gpio_callback)
RPIO.add_interrupt_callback(9, gpio_callback, pull_up_down=RPIO.PUD_UP)
# One TCP socket server callback on port 8080
RPIO.add_tcp_callback(8080, socket_callback)
# Start the blocking epoll loop, and catch Ctrl+C KeyboardInterrupt
try:
RPIO.wait_for_interrupts()
except KeyboardInterrupt:
RPIO.cleanup_interrupts()
If you want to receive a callback inside a Thread (to not block RPIO from returning to wait for interrupts), set threaded_callback to True when adding it:
# for GPIO interrupts
RPIO.add_interrupt_callback(7, do_something, threaded_callback=True)
# for socket interrupts
RPIO.add_tcp_callback(8080, socket_callback, threaded_callback=True)
To stop the wait_for_interrupts() loop you can call RPIO.stop_waiting_for_interrupts(). After using RPIO.wait_for_interrupts() you should call RPIO.cleanup_interrupts() before your program quits, to shut everything down nicely.
GPIO Input & Output
RPIO extends RPi.GPIO; all the input and output handling works just the same:
import RPIO
# set up input channel without pull-up
RPIO.setup(7, RPIO.IN)
# set up input channel with pull-up control. Can be
# PUD_UP, PUD_DOWN or PUD_OFF (default)
RPIO.setup(7, RPIO.IN, pull_up_down=RPIO.PUD_UP)
# read input from gpio 7
input_value = RPIO.input(7)
# set up GPIO output channel
RPIO.setup(8, RPIO.OUT)
# set gpio 8 to high
RPIO.output(8, True)
# set up output channel with an initial state
RPIO.setup(8, RPIO.OUT, initial=RPIO.LOW)
# change to BOARD numbering schema
RPIO.setmode(RPIO.BOARD)
# set software pullup on channel 17
RPIO.set_pullupdn(17, RPIO.PUD_UP) # new in RPIO
# get the function of channel 8
RPIO.gpio_function(8)
# reset every channel that has been set up by this program,
# and unexport interrupt gpio interfaces
RPIO.cleanup()
You can use RPIO as a drop-in replacement for RPi.GPIO in your existing code like this:
import RPIO as GPIO # (if you've previously used `import RPi.GPIO as GPIO`)
To find out more about the methods and constants in RPIO you can run $ sudo pydoc RPIO, or use the help method inside Python:
import RPIO
help(RPIO)
Log Output
To enable RPIO log output, import logging and set the loglevel to DEBUG before importing RPIO:
import logging
log_format = '%(levelname)s | %(asctime)-15s | %(message)s'
logging.basicConfig(format=log_format, level=logging.DEBUG)
import RPIO
Additions to RPi.GPIO
Additional Constants
RPIO.RPI_REVISION - the current board’s revision (either 1 or 2)
RPIO.RPI_REVISION_HEX - the cpu hex revision code (0002 .. 000f)
Additional Methods
RPIO.gpio_function(gpio_id) - returns the current setup of a gpio (IN, OUT, ALT0)
RPIO.set_pullupdn(gpio_id, pud) - set a pullup or -down resistor on a GPIO
RPIO.forceinput(gpio_id) - reads the value of any gpio without needing to call setup() first
RPIO.forceoutput(gpio_id, value) - writes a value to any gpio without needing to call setup() first (warning: this can potentially harm your Raspberry)
RPIO.sysinfo() - returns (hex_rev, model, revision, mb-ram and maker) of this Raspberry
RPIO.version() - returns (version_rpio, version_cgpio)
Interrupt Handling
RPIO.add_interrupt_callback(gpio_id, callback, edge='both', pull_up_down=RPIO.PUD_OFF, threaded_callback=False)
RPIO.add_tcp_callback(port, callback, threaded_callback=False)
RPIO.del_interrupt_callback(gpio_id)
RPIO.wait_for_interrupts(epoll_timeout=1)
RPIO.stop_waiting_for_interrupts()
implemented with epoll
.END
No comments:
Post a Comment