first commit

This commit is contained in:
pandacraft 2025-03-21 16:04:17 +01:00
commit a5a0434432
1126 changed files with 439481 additions and 0 deletions

View file

@ -0,0 +1,161 @@
#!/usr/bin/python
import re
import smbus
# ===========================================================================
# Adafruit_I2C Class
# ===========================================================================
class Adafruit_I2C(object):
@staticmethod
def getPiRevision():
"Gets the version number of the Raspberry Pi board"
# Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
try:
with open('/proc/cpuinfo', 'r') as infile:
for line in infile:
# Match a line of the form "Revision : 0002" while ignoring extra
# info in front of the revsion (like 1000 when the Pi was over-volted).
match = re.match('Revision\s+:\s+.*(\w{4})$', line)
if match and match.group(1) in ['0000', '0002', '0003']:
# Return revision 1 if revision ends with 0000, 0002 or 0003.
return 1
elif match:
# Assume revision 2 if revision ends with any other 4 chars.
return 2
# Couldn't find the revision, assume revision 0 like older code for compatibility.
return 0
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 as 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 as err:
return self.errMsg()
def writeRaw8(self, value):
"Writes an 8-bit value on the bus"
try:
self.bus.write_byte(self.address, value)
if self.debug:
print("I2C: Wrote 0x%02X" % value)
except IOError as 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 as 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 as 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 as 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 as err:
return self.errMsg()
def readU16(self, reg, little_endian=True):
"Reads an unsigned 16-bit value from the I2C device"
try:
result = self.bus.read_word_data(self.address,reg)
# Swap bytes if using big endian because read_word_data assumes little
# endian on ARM (little endian) systems.
if not little_endian:
result = ((result << 8) & 0xFF00) + (result >> 8)
if (self.debug):
print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg))
return result
except IOError as err:
return self.errMsg()
def readS16(self, reg, little_endian=True):
"Reads a signed 16-bit value from the I2C device"
try:
result = self.readU16(reg,little_endian)
if result > 32767: result -= 65536
return result
except IOError as 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")

View file

@ -0,0 +1,310 @@
#!/usr/bin/python
# TSL2561 I2C Light-To-Digital converter library for the Raspberry Pi.
# Datasheet: https://www.adafruit.com/datasheets/TSL2561.pdf
#
# This library is based on the work by Cedric Maion https://github.com/cmaion/TSL2561
#
# Read http://www.dexterindustries.com/topic/greehouse-project/ for the forum discussion about the sensor
from time import sleep
import smbus
from Adafruit_I2C import Adafruit_I2C
import RPi.GPIO as GPIO
from smbus import SMBus
TSL2561_Control = 0x80
TSL2561_Timing = 0x81
TSL2561_Interrupt = 0x86
TSL2561_Channel0L = 0x8C
TSL2561_Channel0H = 0x8D
TSL2561_Channel1L = 0x8E
TSL2561_Channel1H = 0x8F
TSL2561_Address = 0x29 #device address
LUX_SCALE = 14 # scale by 2^14
RATIO_SCALE = 9 # scale ratio by 2^9
CH_SCALE = 10 # scale channel values by 2^10
CHSCALE_TINT0 = 0x7517 # 322/11 * 2^CH_SCALE
CHSCALE_TINT1 = 0x0fe7 # 322/81 * 2^CH_SCALE
K1T = 0x0040 # 0.125 * 2^RATIO_SCALE
B1T = 0x01f2 # 0.0304 * 2^LUX_SCALE
M1T = 0x01be # 0.0272 * 2^LUX_SCALE
K2T = 0x0080 # 0.250 * 2^RATIO_SCA
B2T = 0x0214 # 0.0325 * 2^LUX_SCALE
M2T = 0x02d1 # 0.0440 * 2^LUX_SCALE
K3T = 0x00c0 # 0.375 * 2^RATIO_SCALE
B3T = 0x023f # 0.0351 * 2^LUX_SCALE
M3T = 0x037b # 0.0544 * 2^LUX_SCALE
K4T = 0x0100 # 0.50 * 2^RATIO_SCALE
B4T = 0x0270 # 0.0381 * 2^LUX_SCALE
M4T = 0x03fe # 0.0624 * 2^LUX_SCALE
K5T = 0x0138 # 0.61 * 2^RATIO_SCALE
B5T = 0x016f # 0.0224 * 2^LUX_SCALE
M5T = 0x01fc # 0.0310 * 2^LUX_SCALE
K6T = 0x019a # 0.80 * 2^RATIO_SCALE
B6T = 0x00d2 # 0.0128 * 2^LUX_SCALE
M6T = 0x00fb # 0.0153 * 2^LUX_SCALE
K7T = 0x029a # 1.3 * 2^RATIO_SCALE
B7T = 0x0018 # 0.00146 * 2^LUX_SCALE
M7T = 0x0012 # 0.00112 * 2^LUX_SCALE
K8T = 0x029a # 1.3 * 2^RATIO_SCALE
B8T = 0x0000 # 0.000 * 2^LUX_SCALE
M8T = 0x0000 # 0.000 * 2^LUX_SCALE
K1C = 0x0043 # 0.130 * 2^RATIO_SCALE
B1C = 0x0204 # 0.0315 * 2^LUX_SCALE
M1C = 0x01ad # 0.0262 * 2^LUX_SCALE
K2C = 0x0085 # 0.260 * 2^RATIO_SCALE
B2C = 0x0228 # 0.0337 * 2^LUX_SCALE
M2C = 0x02c1 # 0.0430 * 2^LUX_SCALE
K3C = 0x00c8 # 0.390 * 2^RATIO_SCALE
B3C = 0x0253 # 0.0363 * 2^LUX_SCALE
M3C = 0x0363 # 0.0529 * 2^LUX_SCALE
K4C = 0x010a # 0.520 * 2^RATIO_SCALE
B4C = 0x0282 # 0.0392 * 2^LUX_SCALE
M4C = 0x03df # 0.0605 * 2^LUX_SCALE
K5C = 0x014d # 0.65 * 2^RATIO_SCALE
B5C = 0x0177 # 0.0229 * 2^LUX_SCALE
M5C = 0x01dd # 0.0291 * 2^LUX_SCALE
K6C = 0x019a # 0.80 * 2^RATIO_SCALE
B6C = 0x0101 # 0.0157 * 2^LUX_SCALE
M6C = 0x0127 # 0.0180 * 2^LUX_SCALE
K7C = 0x029a # 1.3 * 2^RATIO_SCALE
B7C = 0x0037 # 0.00338 * 2^LUX_SCALE
M7C = 0x002b # 0.00260 * 2^LUX_SCALE
K8C = 0x029a # 1.3 * 2^RATIO_SCALE
B8C = 0x0000 # 0.000 * 2^LUX_SCALE
M8C = 0x0000 # 0.000 * 2^LUX_SCALE
# bus parameters
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
i2c = Adafruit_I2C(TSL2561_Address)
debug = False
cooldown_time = 0.005 # measured in seconds
packageType = 0 # 0=T package, 1=CS package
gain = 0 # current gain: 0=1x, 1=16x [dynamically selected]
gain_m = 1 # current gain, as multiplier
timing = 2 # current integration time: 0=13.7ms, 1=101ms, 2=402ms [dynamically selected]
timing_ms = 0 # current integration time, in ms
channel0 = 0 # raw current value of visible+ir sensor
channel1 = 0 # raw current value of ir sensor
schannel0 = 0 # normalized current value of visible+ir sensor
schannel1 = 0 # normalized current value of ir sensor
def readRegister(address):
try:
byteval = i2c.readU8(address)
sleep(cooldown_time)
if (debug):
print("TSL2561.readRegister: returned 0x%02X from reg 0x%02X" % (byteval, address))
return byteval
except IOError:
print("TSL2561.readRegister: error reading byte from reg 0x%02X" % address)
return -1
def writeRegister(address, val):
try:
i2c.write8(address, val)
sleep(cooldown_time)
if (debug):
print("TSL2561.writeRegister: wrote 0x%02X to reg 0x%02X" % (val, address))
except IOError:
sleep(cooldown_time)
print("TSL2561.writeRegister: error writing byte to reg 0x%02X" % address)
return -1
def powerUp():
writeRegister(TSL2561_Control, 0x03)
def powerDown():
writeRegister(TSL2561_Control, 0x00)
def setTintAndGain():
global gain_m, timing_ms
if gain == 0:
gain_m = 1
else:
gain_m = 16
if timing == 0:
timing_ms = 13.7
elif timing == 1:
timing_ms = 101
else:
timing_ms = 402
writeRegister(TSL2561_Timing, timing | gain << 4)
def readLux():
sleep(float(timing_ms + 1) / 1000)
ch0_low = readRegister(TSL2561_Channel0L)
ch0_high = readRegister(TSL2561_Channel0H)
ch1_low = readRegister(TSL2561_Channel1L)
ch1_high = readRegister(TSL2561_Channel1H)
global channel0, channel1
channel0 = (ch0_high<<8) | ch0_low
channel1 = (ch1_high<<8) | ch1_low
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: channel 0 = %i, channel 1 = %i [gain=%ix, timing=%ims]" % (channel0, channel1, gain_m, timing_ms))
def readVisibleLux():
global timing, gain
powerUp()
readLux()
if channel0 < 500 and timing == 0:
timing = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Increasing integration time from 13.7ms to 101ms")
setTintAndGain()
readLux()
if channel0 < 500 and timing == 1:
timing = 2
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Increasing integration time from 101ms to 402ms")
setTintAndGain()
readLux()
if channel0 < 500 and timing == 2 and gain == 0:
gain = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Setting high gain")
setTintAndGain()
readLux()
if (channel0 > 20000 or channel1 > 20000) and timing == 2 and gain == 1:
gain = 0
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Setting low gain")
setTintAndGain()
readLux()
if (channel0 > 20000 or channel1 > 20000) and timing == 2:
timing = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Reducing integration time from 402ms to 101ms")
setTintAndGain()
readLux()
if (channel0 > 10000 or channel1 > 10000) and timing == 1:
timing = 0
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Reducing integration time from 101ms to 13.7ms")
setTintAndGain()
readLux()
powerDown()
if (timing == 0 and (channel0 > 5000 or channel1 > 5000)) or (timing == 1 and (channel0 > 37000 or channel1 > 37000)) or (timing == 2 and (channel0 > 65000 or channel1 > 65000)):
# overflow
return -1
return calculateLux(channel0, channel1)
def calculateLux(ch0, ch1):
chScale = 0
if timing == 0: # 13.7 msec
chScale = CHSCALE_TINT0
elif timing == 1: # 101 msec
chScale = CHSCALE_TINT1;
else: # assume no scaling
chScale = (1 << CH_SCALE)
if gain == 0:
chScale = chScale << 4 # scale 1X to 16X
# scale the channel values
global schannel0, schannel1
schannel0 = (ch0 * chScale) >> CH_SCALE
schannel1 = (ch1 * chScale) >> CH_SCALE
ratio = 0
if schannel0 != 0:
ratio = (schannel1 << (RATIO_SCALE+1)) / schannel0
ratio = (ratio + 1) >> 1
if packageType == 0: # T package
if ((ratio >= 0) and (ratio <= K1T)):
b=B1T; m=M1T;
elif (ratio <= K2T):
b=B2T; m=M2T;
elif (ratio <= K3T):
b=B3T; m=M3T;
elif (ratio <= K4T):
b=B4T; m=M4T;
elif (ratio <= K5T):
b=B5T; m=M5T;
elif (ratio <= K6T):
b=B6T; m=M6T;
elif (ratio <= K7T):
b=B7T; m=M7T;
elif (ratio > K8T):
b=B8T; m=M8T;
elif packageType == 1: # CS package
if ((ratio >= 0) and (ratio <= K1C)):
b=B1C; m=M1C;
elif (ratio <= K2C):
b=B2C; m=M2C;
elif (ratio <= K3C):
b=B3C; m=M3C;
elif (ratio <= K4C):
b=B4C; m=M4C;
elif (ratio <= K5C):
b=B5C; m=M5C;
elif (ratio <= K6C):
b=B6C; m=M6C;
elif (ratio <= K7C):
b=B7C; m=M7C;
temp = ((schannel0*b)-(schannel1*m))
if temp < 0:
temp = 0;
temp += (1<<(LUX_SCALE-1))
# strip off fractional portion
lux = temp>>LUX_SCALE
sleep(cooldown_time)
if debug:
print("TSL2561.calculateLux: %i" % lux)
return lux
def init():
powerUp()
setTintAndGain()
writeRegister(TSL2561_Interrupt, 0x00)
powerDown()
def main():
init()
while (True):
print("Lux: %i [Vis+IR=%i, IR=%i @ Gain=%ix, Timing=%.1fms]" % (readVisibleLux(), channel0, channel1, gain_m, timing_ms))
sleep(1)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,12 @@
This is a Python 2.7 script which can be used to get readings from the Grove Digital Light Sensor(http://www.seeedstudio.com/wiki/Grove_-_Digital_Light_Sensor) connected to the GrovePi on a Raspberry Pi.
If you set debug = 1 (standard option) it displays all calculations on screen.
If you set debug = 0, the script just runs and only displays the output.
The script get's both the IR-reading and ambient reading from the sensor. It then scales the the readings and calculates the lux-value.
the main function performs a continuous loop, gets the readings and calculated lux-value and displays the result (depending on the result the output can be normal values and a message 'it's light' or 'it's dark' or a message if the sensor is saturated and no values can be achieved. The loop is repeated with a time.sleep(10) so you can easily read the result on screen.
If your not interested in the IR or ambient values but just want the lux value, comment out the undisered output lines. Be sure not to comment out the reading and calculating lines in the different functions because you need both the IR and the ambient values in order to calculate the lux value.
September 2014.