Commit e6758b0e authored by julric's avatar julric

added support for adafruit raspberry pi lcd shields 1109, 1110 and 1115

parent 31c93144
......@@ -20,3 +20,7 @@ enabled=off
filename=rrd
enabled=on
rrd_file=rrd/data_airpi.rrd
[LCD]
filename=lcd
enabled=on
This diff is collapsed.
#!/usr/bin/python
import smbus
# ===========================================================================
# Adafruit_I2C Class
# ===========================================================================
class Adafruit_I2C :
@staticmethod
def getPiRevision():
"Gets the version number of the Raspberry Pi board"
# Courtesy quick2wire-python-api
# https://github.com/quick2wire/quick2wire-python-api
try:
with open('/proc/cpuinfo','r') as f:
for line in f:
if line.startswith('Revision'):
return 1 if line.rstrip()[-1] in ['1','2'] else 2
except:
return 0
@staticmethod
def getPiI2CBusNumber():
# Gets the I2C bus number /dev/i2c#
return 1 if Adafruit_I2C.getPiRevision() > 1 else 0
def __init__(self, address, busnum=-1, debug=False):
self.address = address
# By default, the correct I2C bus is auto-detected using /proc/cpuinfo
# Alternatively, you can hard-code the bus version below:
# self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
# self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
self.bus = smbus.SMBus(
busnum if busnum >= 0 else Adafruit_I2C.getPiI2CBusNumber())
self.debug = debug
def reverseByteOrder(self, data):
"Reverses the byte order of an int (16-bit) or long (32-bit) value"
# Courtesy Vishal Sapre
byteCount = len(hex(data)[2:].replace('L','')[::2])
val = 0
for i in range(byteCount):
val = (val << 8) | (data & 0xff)
data >>= 8
return val
def errMsg(self):
print "Error accessing 0x%02X: Check your I2C address" % self.address
return -1
def write8(self, reg, value):
"Writes an 8-bit value to the specified register/address"
try:
self.bus.write_byte_data(self.address, reg, value)
if self.debug:
print "I2C: Wrote 0x%02X to register 0x%02X" % (value, reg)
except IOError, err:
return self.errMsg()
def write16(self, reg, value):
"Writes a 16-bit value to the specified register/address pair"
try:
self.bus.write_word_data(self.address, reg, value)
if self.debug:
print ("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
(value, reg, reg+1))
except IOError, err:
return self.errMsg()
def writeList(self, reg, list):
"Writes an array of bytes using I2C format"
try:
if self.debug:
print "I2C: Writing list to register 0x%02X:" % reg
print list
self.bus.write_i2c_block_data(self.address, reg, list)
except IOError, err:
return self.errMsg()
def readList(self, reg, length):
"Read a list of bytes from the I2C device"
try:
results = self.bus.read_i2c_block_data(self.address, reg, length)
if self.debug:
print ("I2C: Device 0x%02X returned the following from reg 0x%02X" %
(self.address, reg))
print results
return results
except IOError, err:
return self.errMsg()
def readU8(self, reg):
"Read an unsigned byte from the I2C device"
try:
result = self.bus.read_byte_data(self.address, reg)
if self.debug:
print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
(self.address, result & 0xFF, reg))
return result
except IOError, err:
return self.errMsg()
def readS8(self, reg):
"Reads a signed byte from the I2C device"
try:
result = self.bus.read_byte_data(self.address, reg)
if result > 127: result -= 256
if self.debug:
print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
(self.address, result & 0xFF, reg))
return result
except IOError, err:
return self.errMsg()
def readU16(self, reg):
"Reads an unsigned 16-bit value from the I2C device"
try:
result = self.bus.read_word_data(self.address,reg)
if (self.debug):
print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg)
return result
except IOError, err:
return self.errMsg()
def readS16(self, reg):
"Reads a signed 16-bit value from the I2C device"
try:
result = self.bus.read_word_data(self.address,reg)
if (self.debug):
print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg)
return result
except IOError, err:
return self.errMsg()
if __name__ == '__main__':
try:
bus = Adafruit_I2C(address=0)
print "Default I2C bus is accessible"
except:
print "Error accessing default I2C bus"
#!/usr/bin/python
# Copyright 2012 Daniel Berlin (with some changes by Adafruit Industries/Limor Fried)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal MCP230XX_GPIO(1, 0xin
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from Adafruit_I2C import Adafruit_I2C
import smbus
import time
MCP23017_IODIRA = 0x00
MCP23017_IODIRB = 0x01
MCP23017_GPIOA = 0x12
MCP23017_GPIOB = 0x13
MCP23017_GPPUA = 0x0C
MCP23017_GPPUB = 0x0D
MCP23017_OLATA = 0x14
MCP23017_OLATB = 0x15
MCP23008_GPIOA = 0x09
MCP23008_GPPUA = 0x06
MCP23008_OLATA = 0x0A
class Adafruit_MCP230XX(object):
OUTPUT = 0
INPUT = 1
def __init__(self, address, num_gpios):
assert num_gpios >= 0 and num_gpios <= 16, "Number of GPIOs must be between 0 and 16"
self.i2c = Adafruit_I2C(address=address)
self.address = address
self.num_gpios = num_gpios
# set defaults
if num_gpios <= 8:
self.i2c.write8(MCP23017_IODIRA, 0xFF) # all inputs on port A
self.direction = self.i2c.readU8(MCP23017_IODIRA)
self.i2c.write8(MCP23008_GPPUA, 0x00)
elif num_gpios > 8 and num_gpios <= 16:
self.i2c.write8(MCP23017_IODIRA, 0xFF) # all inputs on port A
self.i2c.write8(MCP23017_IODIRB, 0xFF) # all inputs on port B
self.direction = self.i2c.readU8(MCP23017_IODIRA)
self.direction |= self.i2c.readU8(MCP23017_IODIRB) << 8
self.i2c.write8(MCP23017_GPPUA, 0x00)
self.i2c.write8(MCP23017_GPPUB, 0x00)
def _changebit(self, bitmap, bit, value):
assert value == 1 or value == 0, "Value is %s must be 1 or 0" % value
if value == 0:
return bitmap & ~(1 << bit)
elif value == 1:
return bitmap | (1 << bit)
def _readandchangepin(self, port, pin, value, currvalue = None):
assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
#assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
if not currvalue:
currvalue = self.i2c.readU8(port)
newvalue = self._changebit(currvalue, pin, value)
self.i2c.write8(port, newvalue)
return newvalue
def pullup(self, pin, value):
if self.num_gpios <= 8:
return self._readandchangepin(MCP23008_GPPUA, pin, value)
if self.num_gpios <= 16:
lvalue = self._readandchangepin(MCP23017_GPPUA, pin, value)
if (pin < 8):
return
else:
return self._readandchangepin(MCP23017_GPPUB, pin-8, value) << 8
# Set pin to either input or output mode
def config(self, pin, mode):
if self.num_gpios <= 8:
self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
if self.num_gpios <= 16:
if (pin < 8):
self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
else:
self.direction |= self._readandchangepin(MCP23017_IODIRB, pin-8, mode) << 8
return self.direction
def output(self, pin, value):
# assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
if self.num_gpios <= 8:
self.outputvalue = self._readandchangepin(MCP23008_GPIOA, pin, value, self.i2c.readU8(MCP23008_OLATA))
if self.num_gpios <= 16:
if (pin < 8):
self.outputvalue = self._readandchangepin(MCP23017_GPIOA, pin, value, self.i2c.readU8(MCP23017_OLATA))
else:
self.outputvalue = self._readandchangepin(MCP23017_GPIOB, pin-8, value, self.i2c.readU8(MCP23017_OLATB)) << 8
return self.outputvalue
self.outputvalue = self._readandchangepin(MCP23017_IODIRA, pin, value, self.outputvalue)
return self.outputvalue
def input(self, pin):
assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
assert self.direction & (1 << pin) != 0, "Pin %s not set to input" % pin
if self.num_gpios <= 8:
value = self.i2c.readU8(MCP23008_GPIOA)
elif self.num_gpios > 8 and self.num_gpios <= 16:
value = self.i2c.readU8(MCP23017_GPIOA)
value |= self.i2c.readU8(MCP23017_GPIOB) << 8
return value & (1 << pin)
def readU8(self):
result = self.i2c.readU8(MCP23008_OLATA)
return(result)
def readS8(self):
result = self.i2c.readU8(MCP23008_OLATA)
if (result > 127): result -= 256
return result
def readU16(self):
assert self.num_gpios >= 16, "16bits required"
lo = self.i2c.readU8(MCP23017_OLATA)
hi = self.i2c.readU8(MCP23017_OLATB)
return((hi << 8) | lo)
def readS16(self):
assert self.num_gpios >= 16, "16bits required"
lo = self.i2c.readU8(MCP23017_OLATA)
hi = self.i2c.readU8(MCP23017_OLATB)
if (hi > 127): hi -= 256
return((hi << 8) | lo)
def write8(self, value):
self.i2c.write8(MCP23008_OLATA, value)
def write16(self, value):
assert self.num_gpios >= 16, "16bits required"
self.i2c.write8(MCP23017_OLATA, value & 0xFF)
self.i2c.write8(MCP23017_OLATB, (value >> 8) & 0xFF)
# RPi.GPIO compatible interface for MCP23017 and MCP23008
class MCP230XX_GPIO(object):
OUT = 0
IN = 1
BCM = 0
BOARD = 0
def __init__(self, busnum, address, num_gpios):
self.chip = Adafruit_MCP230XX(busnum, address, num_gpios)
def setmode(self, mode):
# do nothing
pass
def setup(self, pin, mode):
self.chip.config(pin, mode)
def input(self, pin):
return self.chip.input(pin)
def output(self, pin, value):
self.chip.output(pin, value)
def pullup(self, pin, value):
self.chip.pullup(pin, value)
if __name__ == '__main__':
# ***************************************************
# Set num_gpios to 8 for MCP23008 or 16 for MCP23017!
# ***************************************************
mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 8) # MCP23008
# mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 16) # MCP23017
# Set pins 0, 1 and 2 to output (you can set pins 0..15 this way)
mcp.config(0, mcp.OUTPUT)
mcp.config(1, mcp.OUTPUT)
mcp.config(2, mcp.OUTPUT)
# Set pin 3 to input with the pullup resistor enabled
mcp.config(3, mcp.INPUT)
mcp.pullup(3, 1)
# Read input pin and display the results
print "Pin 3 = %d" % (mcp.input(3) >> 3)
# Python speed test on output 0 toggling at max speed
print "Starting blinky on pin 0 (CTRL+C to quit)"
while (True):
mcp.output(0, 1) # Pin 0 High
time.sleep(1);
mcp.output(0, 0) # Pin 0 Low
time.sleep(1);
#!/usr/bin/python
from time import sleep
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
# Initialize the LCD plate. Should auto-detect correct I2C bus. If not,
# pass '0' for early 256 MB Model B boards or '1' for all later versions
lcd = Adafruit_CharLCDPlate()
# Clear display and show greeting, pause 1 sec
lcd.clear()
lcd.message("Adafruit RGB LCD\nPlate w/Keypad!")
sleep(1)
# Cycle through backlight colors
col = (lcd.RED , lcd.YELLOW, lcd.GREEN, lcd.TEAL,
lcd.BLUE, lcd.VIOLET, lcd.ON , lcd.OFF)
for c in col:
lcd.backlight(c)
sleep(.5)
# Poll buttons, display message & set backlight accordingly
btn = ((lcd.LEFT , 'Red Red Wine' , lcd.RED),
(lcd.UP , 'Sita sings\nthe blues' , lcd.BLUE),
(lcd.DOWN , 'I see fields\nof green' , lcd.GREEN),
(lcd.RIGHT , 'Purple mountain\nmajesties', lcd.VIOLET),
(lcd.SELECT, '' , lcd.ON))
prev = -1
while True:
for b in btn:
if lcd.buttonPressed(b[0]):
if b is not prev:
lcd.clear()
lcd.message(b[1])
lcd.backlight(b[2])
prev = b
break
import output
import datetime
import time
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
def shortname(name):
sname = "error"
if name == "TemperatureBMP":
sname = "Temp "
elif name == "Pressure":
sname = "Press"
elif name == "Relative_Humidity":
sname = "Humidity"
elif name == "TemperatureDHT":
sname = "Temp "
elif name == "Light_Level":
sname = "Light"
elif name == "Nitrogen_Dioxide":
sname = "NO2 "
elif name == "Carbon_Monoxide":
sname = "CO "
elif name == "Volume":
sname = "Vol"
return sname
class LCD(output.Output):
requiredData = []
optionalData = []
def __init__(self,data):
pass
def outputData(self,dataPoints):
lcd = Adafruit_CharLCDPlate.Adafruit_CharLCDPlate()
lcd.clear()
lcd.backlight(lcd.ON)
lcd.message("weather forecast\n" + '{:%d.%m.%Y %H:%M}'.format(datetime.datetime.now()))
time.sleep(5)
lcd.clear()
currentDisplay = 0
for currentDisplay in range(0, 4, 1):
data1 = dataPoints[currentDisplay*2]
data2 = dataPoints[currentDisplay*2 + 1]
lcd.clear()
lcd.message(shortname(data1["name"]) + ": " + str(int(round(data1["value"]))) + " " + data1["symbol"] + "\n" + shortname(data2["name"]) + ": " + str(int(round(data2["value"]))) + " " + data2["symbol"])
time.sleep(5)
lcd.clear()
lcd.backlight(lcd.OFF)
return True
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment