first commit
This commit is contained in:
commit
a5a0434432
1126 changed files with 439481 additions and 0 deletions
195
Software/Python/grove_i2c_sunlight_sensor/I2C.py
Normal file
195
Software/Python/grove_i2c_sunlight_sensor/I2C.py
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# Copyright (c) 2014 Adafruit Industries
|
||||
# Author: Tony DiCola
|
||||
# Based on Adafruit_I2C.py created by Kevin Townsend.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in 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.
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
import smbus
|
||||
|
||||
import Platform
|
||||
|
||||
|
||||
def reverseByteOrder(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 get_default_bus():
|
||||
"""Return the default bus number based on the device platform. For a
|
||||
Raspberry Pi either bus 0 or 1 (based on the Pi revision) will be returned.
|
||||
For a Beaglebone Black the first user accessible bus, 1, will be returned.
|
||||
"""
|
||||
plat = Platform.platform_detect()
|
||||
if plat == Platform.RASPBERRY_PI:
|
||||
if Platform.pi_revision() == 1:
|
||||
# Revision 1 Pi uses I2C bus 0.
|
||||
return 0
|
||||
else:
|
||||
# Revision 2 Pi uses I2C bus 1.
|
||||
return 1
|
||||
elif plat == Platform.BEAGLEBONE_BLACK:
|
||||
# Beaglebone Black has multiple I2C buses, default to 1 (P9_19 and P9_20).
|
||||
return 1
|
||||
else:
|
||||
raise RuntimeError('Could not determine default I2C bus for platform.')
|
||||
|
||||
def get_i2c_device(address, busnum=None, **kwargs):
|
||||
"""Return an I2C device for the specified address and on the specified bus.
|
||||
If busnum isn't specified, the default I2C bus for the platform will attempt
|
||||
to be detected.
|
||||
"""
|
||||
if busnum is None:
|
||||
busnum = get_default_bus()
|
||||
return Device(address, busnum, **kwargs)
|
||||
|
||||
def require_repeated_start():
|
||||
"""Enable repeated start conditions for I2C register reads. This is the
|
||||
normal behavior for I2C, however on some platforms like the Raspberry Pi
|
||||
there are bugs which disable repeated starts unless explicitly enabled with
|
||||
this function. See this thread for more details:
|
||||
http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=15840
|
||||
"""
|
||||
plat = Platform.platform_detect()
|
||||
if plat == Platform.RASPBERRY_PI:
|
||||
# On the Raspberry Pi there is a bug where register reads don't send a
|
||||
# repeated start condition like the kernel smbus I2C driver functions
|
||||
# define. As a workaround this bit in the BCM2708 driver sysfs tree can
|
||||
# be changed to enable I2C repeated starts.
|
||||
subprocess.check_call('chmod 666 /sys/module/i2c_bcm2708/parameters/combined', shell=True)
|
||||
subprocess.check_call('echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined', shell=True)
|
||||
# Other platforms are a no-op because they (presumably) have the correct
|
||||
# behavior and send repeated starts.
|
||||
|
||||
|
||||
class Device(object):
|
||||
"""Class for communicating with an I2C device using the smbus library.
|
||||
Allows reading and writing 8-bit, 16-bit, and byte array values to registers
|
||||
on the device."""
|
||||
def __init__(self, address, busnum):
|
||||
"""Create an instance of the I2C device at the specified address on the
|
||||
specified I2C bus number."""
|
||||
self._address = address
|
||||
self._bus = smbus.SMBus(busnum)
|
||||
self._logger = logging.getLogger('Adafruit_I2C.Device.Bus.{0}.Address.{1:#0X}' \
|
||||
.format(busnum, address))
|
||||
|
||||
def writeRaw8(self, value):
|
||||
"""Write an 8-bit value on the bus (without register)."""
|
||||
value = value & 0xFF
|
||||
self._bus.write_byte(self._address, value)
|
||||
self._logger.debug("Wrote 0x%02X",
|
||||
value)
|
||||
|
||||
def write8(self, register, value):
|
||||
"""Write an 8-bit value to the specified register."""
|
||||
value = value & 0xFF
|
||||
self._bus.write_byte_data(self._address, register, value)
|
||||
self._logger.debug("Wrote 0x%02X to register 0x%02X",
|
||||
value, register)
|
||||
|
||||
def write16(self, register, value):
|
||||
"""Write a 16-bit value to the specified register."""
|
||||
value = value & 0xFFFF
|
||||
self._bus.write_word_data(self._address, register, value)
|
||||
self._logger.debug("Wrote 0x%04X to register pair 0x%02X, 0x%02X",
|
||||
value, register, register+1)
|
||||
|
||||
def writeList(self, register, data):
|
||||
"""Write bytes to the specified register."""
|
||||
self._bus.write_i2c_block_data(self._address, register, data)
|
||||
self._logger.debug("Wrote to register 0x%02X: %s",
|
||||
register, data)
|
||||
|
||||
def readList(self, register, length):
|
||||
"""Read a length number of bytes from the specified register. Results
|
||||
will be returned as a bytearray."""
|
||||
results = self._bus.read_i2c_block_data(self._address, register, length)
|
||||
self._logger.debug("Read the following from register 0x%02X: %s",
|
||||
register, results)
|
||||
return results
|
||||
|
||||
def readRaw8(self):
|
||||
"""Read an 8-bit value on the bus (without register)."""
|
||||
result = self._bus.read_byte(self._address) & 0xFF
|
||||
self._logger.debug("Read 0x%02X",
|
||||
result)
|
||||
return result
|
||||
|
||||
def readU8(self, register):
|
||||
"""Read an unsigned byte from the specified register."""
|
||||
result = self._bus.read_byte_data(self._address, register) & 0xFF
|
||||
self._logger.debug("Read 0x%02X from register 0x%02X",
|
||||
result, register)
|
||||
return result
|
||||
|
||||
def readS8(self, register):
|
||||
"""Read a signed byte from the specified register."""
|
||||
result = self.readU8(register)
|
||||
if result > 127:
|
||||
result -= 256
|
||||
return result
|
||||
|
||||
def readU16(self, register, little_endian=True):
|
||||
"""Read an unsigned 16-bit value from the specified register, with the
|
||||
specified endianness (default little endian, or least significant byte
|
||||
first)."""
|
||||
result = self._bus.read_word_data(self._address,register) & 0xFFFF
|
||||
self._logger.debug("Read 0x%04X from register pair 0x%02X, 0x%02X",
|
||||
result, register, register+1)
|
||||
# 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)
|
||||
return result
|
||||
|
||||
def readS16(self, register, little_endian=True):
|
||||
"""Read a signed 16-bit value from the specified register, with the
|
||||
specified endianness (default little endian, or least significant byte
|
||||
first)."""
|
||||
result = self.readU16(register, little_endian)
|
||||
if result > 32767:
|
||||
result -= 65536
|
||||
return result
|
||||
|
||||
def readU16LE(self, register):
|
||||
"""Read an unsigned 16-bit value from the specified register, in little
|
||||
endian byte order."""
|
||||
return self.readU16(register, little_endian=True)
|
||||
|
||||
def readU16BE(self, register):
|
||||
"""Read an unsigned 16-bit value from the specified register, in big
|
||||
endian byte order."""
|
||||
return self.readU16(register, little_endian=False)
|
||||
|
||||
def readS16LE(self, register):
|
||||
"""Read a signed 16-bit value from the specified register, in little
|
||||
endian byte order."""
|
||||
return self.readS16(register, little_endian=True)
|
||||
|
||||
def readS16BE(self, register):
|
||||
"""Read a signed 16-bit value from the specified register, in big
|
||||
endian byte order."""
|
||||
return self.readS16(register, little_endian=False)
|
||||
106
Software/Python/grove_i2c_sunlight_sensor/Platform.py
Normal file
106
Software/Python/grove_i2c_sunlight_sensor/Platform.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
# Copyright (c) 2014 Adafruit Industries
|
||||
# Author: Tony DiCola
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in 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.
|
||||
import platform
|
||||
import re
|
||||
|
||||
# Platform identification constants.
|
||||
UNKNOWN = 0
|
||||
RASPBERRY_PI = 1
|
||||
BEAGLEBONE_BLACK = 2
|
||||
MINNOWBOARD = 3
|
||||
|
||||
def platform_detect():
|
||||
"""Detect if running on the Raspberry Pi or Beaglebone Black and return the
|
||||
platform type. Will return RASPBERRY_PI, BEAGLEBONE_BLACK, or UNKNOWN."""
|
||||
# Handle Raspberry Pi
|
||||
pi = pi_version()
|
||||
if pi is not None:
|
||||
return RASPBERRY_PI
|
||||
|
||||
# Handle Beaglebone Black
|
||||
# TODO: Check the Beaglebone Black /proc/cpuinfo value instead of reading
|
||||
# the platform.
|
||||
plat = platform.platform()
|
||||
if plat.lower().find('armv7l-with-debian') > -1:
|
||||
return BEAGLEBONE_BLACK
|
||||
elif plat.lower().find('armv7l-with-ubuntu') > -1:
|
||||
return BEAGLEBONE_BLACK
|
||||
elif plat.lower().find('armv7l-with-glibc2.4') > -1:
|
||||
return BEAGLEBONE_BLACK
|
||||
|
||||
# Handle Minnowboard
|
||||
# Assumption is that mraa is installed
|
||||
try:
|
||||
import mraa
|
||||
if mraa.getPlatformName()=='MinnowBoard MAX':
|
||||
return MINNOWBOARD
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Couldn't figure out the platform, just return unknown.
|
||||
return UNKNOWN
|
||||
|
||||
|
||||
def pi_revision():
|
||||
"""Detect the revision number of a Raspberry Pi, useful for changing
|
||||
functionality like default I2C bus based on revision."""
|
||||
# Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
|
||||
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, flags=re.IGNORECASE)
|
||||
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, throw an exception.
|
||||
raise RuntimeError('Could not determine Raspberry Pi revision.')
|
||||
|
||||
|
||||
def pi_version():
|
||||
"""Detect the version of the Raspberry Pi. Returns either 1, 2 or
|
||||
None depending on if it's a Raspberry Pi 1 (model A, B, A+, B+),
|
||||
Raspberry Pi 2 (model B+), or not a Raspberry Pi.
|
||||
"""
|
||||
# Check /proc/cpuinfo for the Hardware field value.
|
||||
# 2708 is pi 1
|
||||
# 2709 is pi 2
|
||||
# Anything else is not a pi.
|
||||
with open('/proc/cpuinfo', 'r') as infile:
|
||||
cpuinfo = infile.read()
|
||||
# Match a line like 'Hardware : BCM2709'
|
||||
match = re.search('^Hardware\s+:\s+(\w+)$', cpuinfo,
|
||||
flags=re.MULTILINE | re.IGNORECASE)
|
||||
if not match:
|
||||
# Couldn't find the hardware, assume it isn't a pi.
|
||||
return None
|
||||
if match.group(1) == 'BCM2708':
|
||||
# Pi 1
|
||||
return 1
|
||||
elif match.group(1) == 'BCM2709':
|
||||
# Pi 2
|
||||
return 2
|
||||
else:
|
||||
# Something else, not a pi.
|
||||
return None
|
||||
7
Software/Python/grove_i2c_sunlight_sensor/README.md
Normal file
7
Software/Python/grove_i2c_sunlight_sensor/README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Grove I2C Touch Sensor
|
||||
======================
|
||||
Raspberry Pi Python i2c library for Grove I2C Touch sensor (http://www.seeedstudio.com/depot/Grove-I2C-Touch-Sensor-p-840.html)
|
||||
|
||||
The I2C Touch Sensor is based on FreeScale MPR121, it feels the touch or proximity of human being fingers.
|
||||
|
||||
The python library used for this sensor is based on the Python_SI1145 library by THP-JOE(https://github.com/THP-JOE/Python_SI1145)
|
||||
264
Software/Python/grove_i2c_sunlight_sensor/SI1145.py
Normal file
264
Software/Python/grove_i2c_sunlight_sensor/SI1145.py
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
|
||||
# Author: Joe Gutting
|
||||
# With use of Adafruit SI1145 library for Arduino, Adafruit_GPIO.I2C & BMP Library by Tony DiCola
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in 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.
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
import I2C
|
||||
|
||||
# COMMANDS
|
||||
SI1145_PARAM_QUERY = 0x80
|
||||
SI1145_PARAM_SET = 0xA0
|
||||
SI1145_NOP = 0x0
|
||||
SI1145_RESET = 0x01
|
||||
SI1145_BUSADDR = 0x02
|
||||
SI1145_PS_FORCE = 0x05
|
||||
SI1145_ALS_FORCE = 0x06
|
||||
SI1145_PSALS_FORCE = 0x07
|
||||
SI1145_PS_PAUSE = 0x09
|
||||
SI1145_ALS_PAUSE = 0x0A
|
||||
SI1145_PSALS_PAUSE = 0xB
|
||||
SI1145_PS_AUTO = 0x0D
|
||||
SI1145_ALS_AUTO = 0x0E
|
||||
SI1145_PSALS_AUTO = 0x0F
|
||||
SI1145_GET_CAL = 0x12
|
||||
|
||||
# Parameters
|
||||
SI1145_PARAM_I2CADDR = 0x00
|
||||
SI1145_PARAM_CHLIST = 0x01
|
||||
SI1145_PARAM_CHLIST_ENUV = 0x80
|
||||
SI1145_PARAM_CHLIST_ENAUX = 0x40
|
||||
SI1145_PARAM_CHLIST_ENALSIR = 0x20
|
||||
SI1145_PARAM_CHLIST_ENALSVIS = 0x10
|
||||
SI1145_PARAM_CHLIST_ENPS1 = 0x01
|
||||
SI1145_PARAM_CHLIST_ENPS2 = 0x02
|
||||
SI1145_PARAM_CHLIST_ENPS3 = 0x04
|
||||
|
||||
SI1145_PARAM_PSLED12SEL = 0x02
|
||||
SI1145_PARAM_PSLED12SEL_PS2NONE = 0x00
|
||||
SI1145_PARAM_PSLED12SEL_PS2LED1 = 0x10
|
||||
SI1145_PARAM_PSLED12SEL_PS2LED2 = 0x20
|
||||
SI1145_PARAM_PSLED12SEL_PS2LED3 = 0x40
|
||||
SI1145_PARAM_PSLED12SEL_PS1NONE = 0x00
|
||||
SI1145_PARAM_PSLED12SEL_PS1LED1 = 0x01
|
||||
SI1145_PARAM_PSLED12SEL_PS1LED2 = 0x02
|
||||
SI1145_PARAM_PSLED12SEL_PS1LED3 = 0x04
|
||||
|
||||
SI1145_PARAM_PSLED3SEL = 0x03
|
||||
SI1145_PARAM_PSENCODE = 0x05
|
||||
SI1145_PARAM_ALSENCODE = 0x06
|
||||
|
||||
SI1145_PARAM_PS1ADCMUX = 0x07
|
||||
SI1145_PARAM_PS2ADCMUX = 0x08
|
||||
SI1145_PARAM_PS3ADCMUX = 0x09
|
||||
SI1145_PARAM_PSADCOUNTER = 0x0A
|
||||
SI1145_PARAM_PSADCGAIN = 0x0B
|
||||
SI1145_PARAM_PSADCMISC = 0x0C
|
||||
SI1145_PARAM_PSADCMISC_RANGE = 0x20
|
||||
SI1145_PARAM_PSADCMISC_PSMODE = 0x04
|
||||
|
||||
SI1145_PARAM_ALSIRADCMUX = 0x0E
|
||||
SI1145_PARAM_AUXADCMUX = 0x0F
|
||||
|
||||
SI1145_PARAM_ALSVISADCOUNTER = 0x10
|
||||
SI1145_PARAM_ALSVISADCGAIN = 0x11
|
||||
SI1145_PARAM_ALSVISADCMISC = 0x12
|
||||
SI1145_PARAM_ALSVISADCMISC_VISRANGE = 0x20
|
||||
|
||||
SI1145_PARAM_ALSIRADCOUNTER = 0x1D
|
||||
SI1145_PARAM_ALSIRADCGAIN = 0x1E
|
||||
SI1145_PARAM_ALSIRADCMISC = 0x1F
|
||||
SI1145_PARAM_ALSIRADCMISC_RANGE = 0x20
|
||||
|
||||
SI1145_PARAM_ADCCOUNTER_511CLK = 0x70
|
||||
|
||||
SI1145_PARAM_ADCMUX_SMALLIR = 0x00
|
||||
SI1145_PARAM_ADCMUX_LARGEIR = 0x03
|
||||
|
||||
|
||||
|
||||
# REGISTERS
|
||||
SI1145_REG_PARTID = 0x00
|
||||
SI1145_REG_REVID = 0x01
|
||||
SI1145_REG_SEQID = 0x02
|
||||
|
||||
SI1145_REG_INTCFG = 0x03
|
||||
SI1145_REG_INTCFG_INTOE = 0x01
|
||||
SI1145_REG_INTCFG_INTMODE = 0x02
|
||||
|
||||
SI1145_REG_IRQEN = 0x04
|
||||
SI1145_REG_IRQEN_ALSEVERYSAMPLE = 0x01
|
||||
SI1145_REG_IRQEN_PS1EVERYSAMPLE = 0x04
|
||||
SI1145_REG_IRQEN_PS2EVERYSAMPLE = 0x08
|
||||
SI1145_REG_IRQEN_PS3EVERYSAMPLE = 0x10
|
||||
|
||||
|
||||
SI1145_REG_IRQMODE1 = 0x05
|
||||
SI1145_REG_IRQMODE2 = 0x06
|
||||
|
||||
SI1145_REG_HWKEY = 0x07
|
||||
SI1145_REG_MEASRATE0 = 0x08
|
||||
SI1145_REG_MEASRATE1 = 0x09
|
||||
SI1145_REG_PSRATE = 0x0A
|
||||
SI1145_REG_PSLED21 = 0x0F
|
||||
SI1145_REG_PSLED3 = 0x10
|
||||
SI1145_REG_UCOEFF0 = 0x13
|
||||
SI1145_REG_UCOEFF1 = 0x14
|
||||
SI1145_REG_UCOEFF2 = 0x15
|
||||
SI1145_REG_UCOEFF3 = 0x16
|
||||
SI1145_REG_PARAMWR = 0x17
|
||||
SI1145_REG_COMMAND = 0x18
|
||||
SI1145_REG_RESPONSE = 0x20
|
||||
SI1145_REG_IRQSTAT = 0x21
|
||||
SI1145_REG_IRQSTAT_ALS = 0x01
|
||||
|
||||
SI1145_REG_ALSVISDATA0 = 0x22
|
||||
SI1145_REG_ALSVISDATA1 = 0x23
|
||||
SI1145_REG_ALSIRDATA0 = 0x24
|
||||
SI1145_REG_ALSIRDATA1 = 0x25
|
||||
SI1145_REG_PS1DATA0 = 0x26
|
||||
SI1145_REG_PS1DATA1 = 0x27
|
||||
SI1145_REG_PS2DATA0 = 0x28
|
||||
SI1145_REG_PS2DATA1 = 0x29
|
||||
SI1145_REG_PS3DATA0 = 0x2A
|
||||
SI1145_REG_PS3DATA1 = 0x2B
|
||||
SI1145_REG_UVINDEX0 = 0x2C
|
||||
SI1145_REG_UVINDEX1 = 0x2D
|
||||
SI1145_REG_PARAMRD = 0x2E
|
||||
SI1145_REG_CHIPSTAT = 0x30
|
||||
|
||||
# I2C Address
|
||||
SI1145_ADDR = 0x60
|
||||
|
||||
class SI1145(object):
|
||||
def __init__(self, address=SI1145_ADDR, busnum=I2C.get_default_bus()):
|
||||
|
||||
self._logger = logging.getLogger('SI1145')
|
||||
|
||||
# Create I2C device.
|
||||
self._device = I2C.Device(address, busnum)
|
||||
|
||||
#reset device
|
||||
self._reset()
|
||||
|
||||
# Load calibration values.
|
||||
self._load_calibration()
|
||||
|
||||
# device reset
|
||||
def _reset(self):
|
||||
self._device.write8(SI1145_REG_MEASRATE0, 0)
|
||||
self._device.write8(SI1145_REG_MEASRATE1, 0)
|
||||
self._device.write8(SI1145_REG_IRQEN, 0)
|
||||
self._device.write8(SI1145_REG_IRQMODE1, 0)
|
||||
self._device.write8(SI1145_REG_IRQMODE2, 0)
|
||||
self._device.write8(SI1145_REG_INTCFG, 0)
|
||||
self._device.write8(SI1145_REG_IRQSTAT, 0xFF)
|
||||
|
||||
self._device.write8(SI1145_REG_COMMAND, SI1145_RESET)
|
||||
time.sleep(.01)
|
||||
self._device.write8(SI1145_REG_HWKEY, 0x17)
|
||||
time.sleep(.01)
|
||||
|
||||
# write Param
|
||||
def writeParam(self, p, v):
|
||||
self._device.write8(SI1145_REG_PARAMWR, v)
|
||||
self._device.write8(SI1145_REG_COMMAND, p | SI1145_PARAM_SET)
|
||||
paramVal = self._device.readU8(SI1145_REG_PARAMRD)
|
||||
return paramVal
|
||||
|
||||
# load calibration to sensor
|
||||
def _load_calibration(self):
|
||||
# /***********************************/
|
||||
# Enable UVindex measurement coefficients!
|
||||
self._device.write8(SI1145_REG_UCOEFF0, 0x29)
|
||||
self._device.write8(SI1145_REG_UCOEFF1, 0x89)
|
||||
self._device.write8(SI1145_REG_UCOEFF2, 0x02)
|
||||
self._device.write8(SI1145_REG_UCOEFF3, 0x00)
|
||||
|
||||
# Enable UV sensor
|
||||
self.writeParam(SI1145_PARAM_CHLIST, SI1145_PARAM_CHLIST_ENUV | SI1145_PARAM_CHLIST_ENALSIR | SI1145_PARAM_CHLIST_ENALSVIS | SI1145_PARAM_CHLIST_ENPS1)
|
||||
|
||||
# Enable interrupt on every sample
|
||||
self._device.write8(SI1145_REG_INTCFG, SI1145_REG_INTCFG_INTOE)
|
||||
self._device.write8(SI1145_REG_IRQEN, SI1145_REG_IRQEN_ALSEVERYSAMPLE)
|
||||
|
||||
# /****************************** Prox Sense 1 */
|
||||
|
||||
# Program LED current
|
||||
self._device.write8(SI1145_REG_PSLED21, 0x03) # 20mA for LED 1 only
|
||||
self.writeParam(SI1145_PARAM_PS1ADCMUX, SI1145_PARAM_ADCMUX_LARGEIR)
|
||||
|
||||
# Prox sensor #1 uses LED #1
|
||||
self.writeParam(SI1145_PARAM_PSLED12SEL, SI1145_PARAM_PSLED12SEL_PS1LED1)
|
||||
|
||||
# Fastest clocks, clock div 1
|
||||
self.writeParam(SI1145_PARAM_PSADCGAIN, 0)
|
||||
|
||||
# Take 511 clocks to measure
|
||||
self.writeParam(SI1145_PARAM_PSADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
|
||||
|
||||
# in prox mode, high range
|
||||
self.writeParam(SI1145_PARAM_PSADCMISC, SI1145_PARAM_PSADCMISC_RANGE | SI1145_PARAM_PSADCMISC_PSMODE)
|
||||
self.writeParam(SI1145_PARAM_ALSIRADCMUX, SI1145_PARAM_ADCMUX_SMALLIR)
|
||||
|
||||
# Fastest clocks, clock div 1
|
||||
self.writeParam(SI1145_PARAM_ALSIRADCGAIN, 0)
|
||||
|
||||
# Take 511 clocks to measure
|
||||
self.writeParam(SI1145_PARAM_ALSIRADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
|
||||
|
||||
# in high range mode
|
||||
self.writeParam(SI1145_PARAM_ALSIRADCMISC, SI1145_PARAM_ALSIRADCMISC_RANGE)
|
||||
|
||||
# fastest clocks, clock div 1
|
||||
self.writeParam(SI1145_PARAM_ALSVISADCGAIN, 0)
|
||||
|
||||
# Take 511 clocks to measure
|
||||
self.writeParam(SI1145_PARAM_ALSVISADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
|
||||
|
||||
# in high range mode (not normal signal)
|
||||
self.writeParam(SI1145_PARAM_ALSVISADCMISC, SI1145_PARAM_ALSVISADCMISC_VISRANGE)
|
||||
|
||||
# measurement rate for auto
|
||||
self._device.write8(SI1145_REG_MEASRATE0, 0xFF) # 255 * 31.25uS = 8ms
|
||||
|
||||
# auto run
|
||||
self._device.write8(SI1145_REG_COMMAND, SI1145_PSALS_AUTO)
|
||||
|
||||
# returns the UV index * 100 (divide by 100 to get the index)
|
||||
def readUV(self):
|
||||
return self._device.readU16LE(0x2C)
|
||||
|
||||
#returns visible + IR light levels
|
||||
def readVisible(self):
|
||||
return self._device.readU16LE(0x22)
|
||||
|
||||
#returns IR light levels
|
||||
def readIR(self):
|
||||
return self._device.readU16LE(0x24)
|
||||
|
||||
# Returns "Proximity" - assumes an IR LED is attached to LED
|
||||
def readProx(self):
|
||||
return self._device.readU16LE(0x26)
|
||||
|
||||
53
Software/Python/grove_i2c_sunlight_sensor/simpletest.py
Normal file
53
Software/Python/grove_i2c_sunlight_sensor/simpletest.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Author: Joe Gutting
|
||||
# With use of Adafruit SI1145 library for Arduino, Adafruit_GPIO.I2C & BMP Library by Tony DiCola
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in 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.
|
||||
|
||||
# Can enable debug output by uncommenting:
|
||||
#import logging
|
||||
#logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
import time
|
||||
import SI1145
|
||||
|
||||
# Default constructor will pick a default I2C bus.
|
||||
#
|
||||
# For the Raspberry Pi this means you should hook up to the only exposed I2C bus
|
||||
# from the main GPIO header and the library will figure out the bus number based
|
||||
# on the Pi's revision.
|
||||
|
||||
|
||||
sensor = SI1145.SI1145()
|
||||
|
||||
print('Press Cntrl + Z to stop')
|
||||
print('')
|
||||
|
||||
while True:
|
||||
vis = sensor.readVisible()
|
||||
IR = sensor.readIR()
|
||||
UV = sensor.readUV()
|
||||
uvIndex = UV / 100.0
|
||||
print('Vis: ' + str(vis))
|
||||
print('IR: ' + str(IR))
|
||||
print('UV Index: ' + str(uvIndex))
|
||||
print('')
|
||||
time.sleep(1)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue