Commit 42cc8304 authored by julric's avatar julric

added standalone software for Adafruit LCD and AirPi

parent 09b3c302
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 operator
import datetime
import time
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
from subprocess import check_output
lcd = Adafruit_CharLCDPlate.Adafruit_CharLCDPlate()
lcd.backlight(lcd.OFF)
#########################################################
# Adafruit LCD for Raspberry Pi combined with AirPi #
#########################################################
# #
# important: you need to put the adafruit lcd library #
# in the subdirectory Adafruit_CharLCDPlate #
# and have the rrdtools package for your #
# linux installed, e.g. for debian linux #
# type: apt-get install rrdtools #
# #
#########################################################
# set some options here and the shortnames, symbols and #
# order of the displayed data in line 45 and further #
#########################################################
rrd_file_airpi = '../data_airpi.rrd' # path to your rrd-file with airpi weather data
display_time = 3 # time in seconds, each value should be displayed on lcd
display_color = lcd.GREEN # backlight-color of lcd: lcd.RED, lcd.BLUE, lcd.GREEN, lcd.VIOLETT or lcd.ON (lightblue)
#########################################################
while True:
if lcd.buttonPressed(lcd.SELECT) or lcd.buttonPressed(lcd.UP) or lcd.buttonPressed(lcd.DOWN) or lcd.buttonPressed(lcd.RIGHT) or lcd.buttonPressed(lcd.LEFT): #b[0]):
last = check_output(["rrdtool", "lastupdate", rrd_file_airpi])
lastvalues = last.split( )
# array lastvalues consists of every sensor-name, followed by the time and the sensor-values:
# ['tempbmp', 'tempdht', 'press', 'humi', 'light', 'no2', 'co', 'vol', '1403275748:', '24', 'U', '1001', 'U', '546', '98830', '161637', '235']
# (for the rrd, generated as shown in https://git.cccmz.de/julric/airpi/wikis/rrd-support )
data = []
sensors = (len(lastvalues)-1)/2
# put shortname, symbol and value in one arry and sort ist by given number
for position, value in enumerate(lastvalues):
dataPoints = {}
if 'tempbmp' in value:
dataPoints["sname"] = "Temp: "
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = chr(223)+"C"
dataPoints["number"] = 1
data.append(dataPoints)
elif 'press' in value:
dataPoints["sname"] = "Pressure:"
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = "hPa"
dataPoints["number"] = 2
data.append(dataPoints)
elif 'humi' in value:
dataPoints["sname"] = "Humidity:"
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = "%"
dataPoints["number"] = 3
data.append(dataPoints)
elif 'tempdht' in value:
dataPoints["sname"] = "Temp: "
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = chr(223)+"C"
dataPoints["number"] = 4
data.append(dataPoints)
elif 'no2' in value:
dataPoints["sname"] = "NO2: "
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = "mV"
dataPoints["number"] = 5
data.append(dataPoints)
elif 'co' in value:
dataPoints["sname"] = "CO: "
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = "mV"
dataPoints["number"] = 6
data.append(dataPoints)
elif 'light' in value:
dataPoints["sname"] = "Light: "
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = "mV"
dataPoints["number"] = 7
data.append(dataPoints)
elif 'vol' in value:
dataPoints["sname"] = "Volume:"
dataPoints["value"] = lastvalues[(position+sensors+1)]
dataPoints["symbol"] = "Ohm"
dataPoints["number"] = 8
data.append(dataPoints)
elif ':' in value:
measurementtime = value[:-1]
else:
pass
data = sorted(data, key=lambda x: x['number'])
# begin lcd-output
lcd.clear()
lcd.backlight(display_color)
lcd.message(" AirPi \n" + '{:%d.%m.%Y %H:%M}'.format(datetime.datetime.fromtimestamp(float(measurementtime))))
# show output on console
# print " AirPi \n" + '{:%d.%m.%Y %H:%M}'.format(datetime.datetime.fromtimestamp(float(measurementtime)))
time.sleep(display_time)
lcd.clear()
currentDisplay = 0
for currentDisplay in range(0, 4, 1):
data1 = data[currentDisplay*2]
if data1["value"] == "U":
data1["value"] = " "
else:
str(int(round(float(data1["value"]))))
data2 = data[currentDisplay*2 + 1]
if data2["value"] == "U":
data2["value"] = " "
else:
str(int(round(float(data2["value"]))))
lcd.clear()
lcd.message(data1["sname"] + data1["value"] + " " + data1["symbol"] + "\n" + data2["sname"] + data2["value"] + " " + data2["symbol"])
# show output on console
# print data1["sname"] + data1["value"] + " " + data1["symbol"] + "\n" + data2["sname"] + data2["value"] + " " + data2["symbol"]
time.sleep(display_time)
lcd.clear()
# clear and turn off lcd
lcd.clear()
lcd.backlight(lcd.OFF)
# lower cpu-usage in loop
else:
time.sleep(0.1)
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