{"id":79,"date":"2013-03-26T23:58:11","date_gmt":"2013-03-26T23:58:11","guid":{"rendered":"http:\/\/nofl.biz\/blog\/?p=79"},"modified":"2022-03-29T20:51:42","modified_gmt":"2022-03-29T20:51:42","slug":"rgpio-and-piboard","status":"publish","type":"post","link":"https:\/\/beneford.com\/Blog\/index.php\/2013\/03\/26\/rgpio-and-piboard\/","title":{"rendered":"RGPIO and PiBoard"},"content":{"rendered":"<div>How to use <a title=\"Raspberry Pi \u2013 RGPIO\" href=\"\/?p=56\">RGPIO<\/a> with <a title=\"PiBoard \u2013 an expansion board for Raspberry Pi\" href=\"\/?p=69\">PiBoard<\/a>.<\/div>\n<div>This guide uses a PiBoard with the following components:<\/div>\n<ul>\n<li>EA DOG-M LCD (on pins 17,0,11,22,23,24,25) in 3.3V mode)<\/li>\n<li>LCD Backlight (on pin 18)<\/li>\n<li>Buttons connecting pins 7,8,9,10 to ground when pressed<\/li>\n<li>PCF8563 I2C Real time clock (with super-capacitor power backup)<\/li>\n<li>DS1621 I2C Temperature device<\/li>\n<li>DS18B20 1-Wire Temperature device<\/li>\n<\/ul>\n<div>To use RGPIO from python, we open the \/dev\/rgpio device as an unbuffered file in r\/w mode:<\/div>\n<pre>rgpio=open('\/dev\/rgpio','r+',0)\n# r+ means read\/write; 0 means unbuffered<\/pre>\n<div>we can then write to and read from this file to control the PiBoard.<\/div>\n<h2><a title=\"EA DOGM163-A\" href=\"http:\/\/uk.rs-online.com\/web\/p\/lcd-monochrome-displays\/7588611\/\" target=\"_blank\" rel=\"noopener\">LCD &#8211; EA-DOG-M<\/a><\/h2>\n<div>RGPIO does the basic initialization from the C command to get the LCD running in 4-bit mode with the appropriate pins, but the EADOG-M screens need additional initialization according to whether you run in 3.3V or 5V mode.<br \/>\n\\C29 &#8211; Set 4-bit mode and instruction set 1<br \/>\n\\C15 &#8211; Set bias for 3-line LCD<br \/>\n\\C55 &#8211; Booster (for 3.3V) on, Contrast in follower mode<br \/>\n\\C6E&nbsp;&#8211; Follower ccontrol<br \/>\n\\C72 &#8211; Set Contrast<br \/>\n\\C28 &#8211; Set 4-bit more and instruction set 0<\/div>\n<pre>rgpio.write('L17,0,11,22,23,24,25C')\nrgpio.write('LD\\C29\\C15\\C55\\C6E\\C72\\C28')<\/pre>\n<h2>LED Backlight (<a href=\"http:\/\/uk.rs-online.com\/web\/p\/display-backlighting\/7588658\/\" target=\"_blank\" rel=\"noopener\">EA LED55x31-G<\/a>)<\/h2>\n<div>The EA LEDs are coordinated with the LCDs but use completely separate pins. The PiBoard lets you choose between&nbsp;a 3.3V or a 5V supply using the appropriate current-limiting resistor.<br \/>\nThe LED is controlled through a NPN transisitor driven by pin 18. The Raspberry Pi has hardware PWM enabled on pin 18 and this can be used to control the LED brightness. RGPIO supports both software and hardware (pin 18 only) PWM, but the hardware version is much more efficient.<\/div>\n<pre>#Set LED to 50%\nrgpio.write('W50,18C')<\/pre>\n<h2>Buttons (<a title=\"Tyco 6x6mm switch\" href=\"http:\/\/uk.rs-online.com\/web\/p\/tactile-switches\/4791441\/\" target=\"_blank\" rel=\"noopener\">Tyco 6x6mm<\/a>)<\/h2>\n<div>When the buttons are pressed, the GPIO port is shorted to GND. For the buttons to work, they need a pull-up resistor.&nbsp;The PiBoard has space for a separate pull-up resistor, or we can use the CPU&#8217;s internal pull-up capability using&nbsp;P7U8U9U10U.<br \/>\nTo get the pin settings we use RGPIO&#8217;s pin change interrupt to tell us when the pin is grounded.<\/div>\n<pre>rgpio.write('P7U1,7L')&nbsp; # Initialize pull\nrgpio.write('P8U1,7L')  # up and get repeated notifications\nrgpio.write('P9U1,7L')  # when pin Lo\nrgpio.write('P10U1,7L')<\/pre>\n<div>To see what is going on, we have two options:&nbsp;read in a polling loop, knowing we may get a blank line because there is nothing waiting:<\/div>\n<pre>while True:\n    inLine=rgpio.readline()\n    # Now process the line<\/pre>\n<div>Or we can get RGPIO to send us a signal to tell us something is waiting.<\/div>\n<pre>import signal,os\ndef IOSignal(signum,frame):\n    inLine=rgpio.readline()\n    # Now process the line\n\nsignal.signal(signal.SIGIO,IOSignal) # call IOSignal on SIGIO\npid=os.getpid()                      # Get PID of this process\nrgpio.write('%dS'%pid)               # tell RGPIO to send SIGIO here\nwhile True:\n    time.sleep(1)                    # just loop asleep waiting...<\/pre>\n<h2>I2C Clock<\/h2>\n<p>To give the Raspberry Pi a clock, you can either be connected to the internet (in which case, the very accurate internet time is available), or you need to provide an external clock. We do this with an I2C Real Time Clock chip.<br \/>\nThe I2C bus is a very convenient mechanism to communicate between components. It needs 4 connections: VDD, GND, SCL, SLA. Many CPUs (including the Raspberry Pi&#8217;s) have&nbsp;I2C communications built in. On the Raspberry Pi the I2C components are connected to I2C channel 1. Each I2C component has an Id: the <a href=\"http:\/\/uk.rs-online.com\/web\/p\/real-time-clocks\/5402726\/\" target=\"_blank\" rel=\"noopener\">DS1307<\/a> and <a href=\"http:\/\/uk.farnell.com\/maxim-integrated-products\/ds1337\/rtc-serial-alarm-low-power-1337\/dp\/1379812\" target=\"_blank\" rel=\"noopener\">DS1337<\/a> are on 0x68, the <a href=\"http:\/\/uk.rs-online.com\/web\/p\/real-time-clocks\/4837288\/\" target=\"_blank\" rel=\"noopener\">PCF8563<\/a> is on 0x51.<br \/>\nThere are device drivers for many of the available RTC chips (and other I2C chips), and you can use these if you want to, but they are not always as flexible as you might want. RGPIO provides another interface.<br \/>\nTo set the clock on PCF8563 from the system time, use:<\/p>\n<pre>t=datetime.datetime.today()\nsec=toBCD(t.second)\nmin=toBCD(t.minute)\nhour=toBCD(t.hour)\ndate=toBCD(t.day)\nmonth=toBCD(t.month)\nyear=toBCD(t.year % 100)\nday=t.weekday()\nrgpio.write(\"I1N0x51D2,%d,%d,%d,%d,%d,%d,%dW\"%(sec,min,hour,date,day,month,year))<\/pre>\n<div>To get the clock from PCF8563 and set the system time, use:<\/div>\n<pre>import re, os\nrgpio.write(\"I1N0x51D2,7R\")\nreI2C=re.compile('I2C *([^@]*)@([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*)')\ninLine=rgpio.readline()    # If using signal handling, this code goes there\nevent=reI2C.search(inLine) # Use Regular expressions to unpack the input\nsec=int(g(3))&amp;0x7f         # The PC8563 doesn't leave the unused bits zero\nmin=int(g(4))&amp;0x7f         # so we have to clear them ourselves\nhour=int(g(5))&amp;0x1f\ndate=int(g(7))&amp;0x3f\nmonth=int(g(8))&amp;0x1f\nyear=int(g(9))+2000\nnewDate=datetime.datetime(year,month,date,hour,min,sec)\nos.popen(\"date -s %s\"%newDate)<\/pre>\n<div>The DS13x7 series are similar but some detail differences. There are other I2C Real-time-clocks that can be used.<\/div>\n<h2>I2C Thermometer (<a href=\"http:\/\/uk.rs-online.com\/web\/p\/temperature-humidity-sensors\/5405264\/\" target=\"_blank\" rel=\"noopener\">DS1621<\/a>)<\/h2>\n<div>The DS1621 needs initializing so it starts measuring the temperature. Thereafter the temperature can be read whenever required.<\/div>\n<pre>rgpio.write('I1N0x48D0xEEW') # Command 0xEE starts conversion\nrgpio.write('I1N0x48D0xAA,2R') # Read 2 bytes to get the temperature\ninLine=rgpio.readline()\nevent=reI2C.search(inLine) # Use Regular expressions to unpack the input\ntemp=(event.group(3)+256*event.group(4))\/256<\/pre>\n<p>This temperature is accurate to 0.5C, and you can greater accuracy (about 1\/16C) by reading from locations A8 and A9 and using a formula in the specification.<br \/>\nNote: PiBoard has the DS1621 located next to the Timekeeping Crystal. Time Crystals typically have a fixed frequency that varies according to the temperature. This thermometer can be used to improve the accuracy of the clock.<\/p>\n<h2>1-Wire Temperator sensor (<a href=\"http:\/\/uk.rs-online.com\/web\/p\/temperature-humidity-sensors\/5402805\/\" target=\"_blank\" rel=\"noopener\">DS18B20<\/a>)<\/h2>\n<p>The 1-Wire bus uses VDD, GND and DQ (the signal wire). (And some devices will work without the VDD connection.) Linux has 1-Wire modules available and you can use these, however, there are some problems with usability:<\/p>\n<ol>\n<li>The w1-therm module requires reading a file \/sys\/bus\/w1\/devices\/28-xxxxxxxxxxxx\/w1-slave. The problem is that reading this file takes a long time (about 1 second) &#8211; this is because it has to initiate a temperature conversion, and must when way for the conversion to complete &#8211; which is between 94ms and 750ms, depending on the conversion accuracy. 1 second is much too long to wait for a system with a user interface.<\/li>\n<li>the w1-gpio module can also be used but writing to and reading from \/sys\/bus\/w1\/devices\/28-xxxxxxxxxxxx\/rw. The problem here is that if the sensor goes off line, file operations to the rw file hang.<\/li>\n<li>The built-in support for 1-wire is only available on pin 4. You can have multiple devices on that one pin, but a single pin is still a little limiting.<\/li>\n<\/ol>\n<p>RGPIO provides an alternative interface to 1-Wire devices.<\/p>\n<pre>rgpio.write('P4U')&nbsp;&nbsp;&nbsp;   # Set pin 4's pullup - essential for 1-wire operation\nrgpio.write('O4P')&nbsp;&nbsp;&nbsp;   #&nbsp;Set pin 4 as 1-Wire pin\nrgpio.write('O0D')      # Tell RGPIO there is only one 1-Wire device\nrgpio.write('O0x44C')   # Start temperature convertion\nrgpio.write('O0xBEC2W')&nbsp;# Read the temperature\nreW1=re.compile('W1(:[0-9a-fA-F\\-\\.]*)* *(=*) *([^ ]*) *([^ ]*) *([^ ]*)')\ninLine=rgpio.readline() # Get the result\nevent=reW1.search(inLine)\ntemp=(int(event.group(3),16)+256*int(event.group(4),16))\/16.0<\/pre>\n<p>If you have more than one device on the bus, you can do the following:<\/p>\n<pre>rgpio.write('P4U')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set pin 4's pullup - essential for 1-wire operation\nrgpio.write('O4P')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set pin 4 as 1-Wire pin\nrgpio.write('OL')       # List available devices\ninLine=rgpio.readline() # Get the first found device (blank if none)\nevent=reW1.search(inLine)\nw1Device=event.group(1)[1:]  # Get the device name\n                             # format is ff-nnnnnnnnnnnn.cc\n                             # ff is family, n..n is number, cc is checksum\nw1Family=w1Device[0:2]\nw1NC=w1Device[3:7]\nw1NB=w1Device[7:11]\nw1NC=w2Device[11:15]\nw1Id=\"%x,0x%x,0x%x,0x%xD\"\nrgpio.write(\"O%s\"%w1Id)      # Set this device as the one to use\nrgpio.write('O0x44C')&nbsp;&nbsp;      # proceed as above\n...<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>How to use RGPIO with PiBoard. This guide uses a PiBoard with the following components: EA DOG-M LCD (on pins 17,0,11,22,23,24,25) in 3.3V mode) LCD Backlight (on pin 18) Buttons connecting pins 7,8,9,10 to ground when pressed PCF8563 I2C Real time clock (with super-capacitor power backup) DS1621 I2C Temperature device DS18B20 1-Wire Temperature device To [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,5],"tags":[],"class_list":["post-79","post","type-post","status-publish","format-standard","hentry","category-piboard","category-rgpio"],"_links":{"self":[{"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/posts\/79","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/comments?post=79"}],"version-history":[{"count":2,"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/posts\/79\/revisions"}],"predecessor-version":[{"id":241,"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/posts\/79\/revisions\/241"}],"wp:attachment":[{"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/media?parent=79"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/categories?post=79"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/beneford.com\/Blog\/index.php\/wp-json\/wp\/v2\/tags?post=79"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}