first commit
This commit is contained in:
commit
a5a0434432
1126 changed files with 439481 additions and 0 deletions
195
Software/Python/grove_i2c_touch/I2C.py
Normal file
195
Software/Python/grove_i2c_touch/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)
|
||||
188
Software/Python/grove_i2c_touch/MPR121.py
Normal file
188
Software/Python/grove_i2c_touch/MPR121.py
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
# 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 time
|
||||
|
||||
|
||||
# Register addresses.
|
||||
MPR121_I2CADDR_DEFAULT = 0x5A
|
||||
MPR121_TOUCHSTATUS_L = 0x00
|
||||
MPR121_TOUCHSTATUS_H = 0x01
|
||||
MPR121_FILTDATA_0L = 0x04
|
||||
MPR121_FILTDATA_0H = 0x05
|
||||
MPR121_BASELINE_0 = 0x1E
|
||||
MPR121_MHDR = 0x2B
|
||||
MPR121_NHDR = 0x2C
|
||||
MPR121_NCLR = 0x2D
|
||||
MPR121_FDLR = 0x2E
|
||||
MPR121_MHDF = 0x2F
|
||||
MPR121_NHDF = 0x30
|
||||
MPR121_NCLF = 0x31
|
||||
MPR121_FDLF = 0x32
|
||||
MPR121_NHDT = 0x33
|
||||
MPR121_NCLT = 0x34
|
||||
MPR121_FDLT = 0x35
|
||||
MPR121_TOUCHTH_0 = 0x41
|
||||
MPR121_RELEASETH_0 = 0x42
|
||||
MPR121_DEBOUNCE = 0x5B
|
||||
MPR121_CONFIG1 = 0x5C
|
||||
MPR121_CONFIG2 = 0x5D
|
||||
MPR121_CHARGECURR_0 = 0x5F
|
||||
MPR121_CHARGETIME_1 = 0x6C
|
||||
MPR121_ECR = 0x5E
|
||||
MPR121_AUTOCONFIG0 = 0x7B
|
||||
MPR121_AUTOCONFIG1 = 0x7C
|
||||
MPR121_UPLIMIT = 0x7D
|
||||
MPR121_LOWLIMIT = 0x7E
|
||||
MPR121_TARGETLIMIT = 0x7F
|
||||
MPR121_GPIODIR = 0x76
|
||||
MPR121_GPIOEN = 0x77
|
||||
MPR121_GPIOSET = 0x78
|
||||
MPR121_GPIOCLR = 0x79
|
||||
MPR121_GPIOTOGGLE = 0x7A
|
||||
MPR121_SOFTRESET = 0x80
|
||||
|
||||
MAX_I2C_RETRIES = 5
|
||||
|
||||
|
||||
class MPR121(object):
|
||||
"""Representation of a MPR121 capacitive touch sensor."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create an instance of the MPR121 device."""
|
||||
# Nothing to do here since there is very little state in the class.
|
||||
pass
|
||||
|
||||
def begin(self, address=MPR121_I2CADDR_DEFAULT, i2c=None, **kwargs):
|
||||
"""Initialize communication with the MPR121.
|
||||
|
||||
Can specify a custom I2C address for the device using the address
|
||||
parameter (defaults to 0x5A). Optional i2c parameter allows specifying a
|
||||
custom I2C bus source (defaults to platform's I2C bus).
|
||||
|
||||
Returns True if communication with the MPR121 was established, otherwise
|
||||
returns False.
|
||||
"""
|
||||
# Assume we're using platform's default I2C bus if none is specified.
|
||||
if i2c is None:
|
||||
import I2C
|
||||
i2c = I2C
|
||||
# Require repeated start conditions for I2C register reads. Unfortunately
|
||||
# the MPR121 is very sensitive and requires repeated starts to read all
|
||||
# the registers.
|
||||
I2C.require_repeated_start()
|
||||
# Save a reference to the I2C device instance for later communication.
|
||||
self._device = i2c.get_i2c_device(address, **kwargs)
|
||||
return self._reset()
|
||||
|
||||
def _reset(self):
|
||||
# Soft reset of device.
|
||||
self._i2c_retry(self._device.write8, MPR121_SOFTRESET, 0x63)
|
||||
time.sleep(0.001) # This 1ms delay here probably isn't necessary but can't hurt.
|
||||
# Set electrode configuration to default values.
|
||||
self._i2c_retry(self._device.write8, MPR121_ECR, 0x00)
|
||||
# Check CDT, SFI, ESI configuration is at default values.
|
||||
c = self._i2c_retry(self._device.readU8, MPR121_CONFIG2)
|
||||
if c != 0x24:
|
||||
return False
|
||||
# Set threshold for touch and release to default values.
|
||||
self.set_thresholds(12, 6)
|
||||
# Configure baseline filtering control registers.
|
||||
self._i2c_retry(self._device.write8, MPR121_MHDR, 0x01)
|
||||
self._i2c_retry(self._device.write8, MPR121_NHDR, 0x01)
|
||||
self._i2c_retry(self._device.write8, MPR121_NCLR, 0x0E)
|
||||
self._i2c_retry(self._device.write8, MPR121_FDLR, 0x00)
|
||||
self._i2c_retry(self._device.write8, MPR121_MHDF, 0x01)
|
||||
self._i2c_retry(self._device.write8, MPR121_NHDF, 0x05)
|
||||
self._i2c_retry(self._device.write8, MPR121_NCLF, 0x01)
|
||||
self._i2c_retry(self._device.write8, MPR121_FDLF, 0x00)
|
||||
self._i2c_retry(self._device.write8, MPR121_NHDT, 0x00)
|
||||
self._i2c_retry(self._device.write8, MPR121_NCLT, 0x00)
|
||||
self._i2c_retry(self._device.write8, MPR121_FDLT, 0x00)
|
||||
# Set other configuration registers.
|
||||
self._i2c_retry(self._device.write8, MPR121_DEBOUNCE, 0)
|
||||
self._i2c_retry(self._device.write8, MPR121_CONFIG1, 0x10) # default, 16uA charge current
|
||||
self._i2c_retry(self._device.write8, MPR121_CONFIG2, 0x20) # 0.5uS encoding, 1ms period
|
||||
# Enable all electrodes.
|
||||
self._i2c_retry(self._device.write8, MPR121_ECR, 0x8F) # start with first 5 bits of baseline tracking
|
||||
# All done, everything succeeded!
|
||||
return True
|
||||
|
||||
def _i2c_retry(self, func, *params):
|
||||
# Run specified I2C request and ignore IOError 110 (timeout) up to
|
||||
# retries times. For some reason the Pi 2 hardware I2C appears to be
|
||||
# flakey and randomly return timeout errors on I2C reads. This will
|
||||
# catch those errors, reset the MPR121, and retry.
|
||||
count = 0
|
||||
while True:
|
||||
try:
|
||||
return func(*params)
|
||||
except IOError as ex:
|
||||
# Re-throw anything that isn't a timeout (110) error.
|
||||
if ex.errno != 110:
|
||||
raise ex
|
||||
# Else there was a timeout, so reset the device and retry.
|
||||
self._reset()
|
||||
# Increase count and fail after maximum number of retries.
|
||||
count += 1
|
||||
if count >= MAX_I2C_RETRIES:
|
||||
raise RuntimeError('Exceeded maximum number or retries attempting I2C communication!')
|
||||
|
||||
def set_thresholds(self, touch, release):
|
||||
"""Set the touch and release threshold for all inputs to the provided
|
||||
values. Both touch and release should be a value between 0 to 255
|
||||
(inclusive).
|
||||
"""
|
||||
assert touch >= 0 and touch <= 255, 'touch must be between 0-255 (inclusive)'
|
||||
assert release >= 0 and release <= 255, 'release must be between 0-255 (inclusive)'
|
||||
# Set the touch and release register value for all the inputs.
|
||||
for i in range(12):
|
||||
self._i2c_retry(self._device.write8, MPR121_TOUCHTH_0 + 2*i, touch)
|
||||
self._i2c_retry(self._device.write8, MPR121_RELEASETH_0 + 2*i, release)
|
||||
|
||||
def filtered_data(self, pin):
|
||||
"""Return filtered data register value for the provided pin (0-11).
|
||||
Useful for debugging.
|
||||
"""
|
||||
assert pin >= 0 and pin < 12, 'pin must be between 0-11 (inclusive)'
|
||||
return self._i2c_retry(self._device.readU16LE, MPR121_FILTDATA_0L + pin*2)
|
||||
|
||||
def baseline_data(self, pin):
|
||||
"""Return baseline data register value for the provided pin (0-11).
|
||||
Useful for debugging.
|
||||
"""
|
||||
assert pin >= 0 and pin < 12, 'pin must be between 0-11 (inclusive)'
|
||||
bl = self._i2c_retry(self._device.readU8, MPR121_BASELINE_0 + pin)
|
||||
return bl << 2
|
||||
|
||||
def touched(self):
|
||||
"""Return touch state of all pins as a 12-bit value where each bit
|
||||
represents a pin, with a value of 1 being touched and 0 not being touched.
|
||||
"""
|
||||
t = self._i2c_retry(self._device.readU16LE, MPR121_TOUCHSTATUS_L)
|
||||
return t & 0x0FFF
|
||||
|
||||
def is_touched(self, pin):
|
||||
"""Return True if the specified pin is being touched, otherwise returns
|
||||
False.
|
||||
"""
|
||||
assert pin >= 0 and pin < 12, 'pin must be between 0-11 (inclusive)'
|
||||
t = self.touched()
|
||||
return (t & (1 << pin)) > 0
|
||||
106
Software/Python/grove_i2c_touch/Platform.py
Normal file
106
Software/Python/grove_i2c_touch/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_touch/README.md
Normal file
7
Software/Python/grove_i2c_touch/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 for this sensor is based on the Python library for interfacing with a MPR121 by Adafruit (https://github.com/adafruit/Adafruit_Python_MPR121)
|
||||
77
Software/Python/grove_i2c_touch/touchtest.py
Normal file
77
Software/Python/grove_i2c_touch/touchtest.py
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# 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 sys
|
||||
import time
|
||||
|
||||
import MPR121
|
||||
|
||||
|
||||
print('MPR121 Capacitive Touch Sensor Test')
|
||||
|
||||
# Create MPR121 instance.
|
||||
cap = MPR121.MPR121()
|
||||
|
||||
# Initialize communication with MPR121 using default I2C bus of device, and
|
||||
# default I2C address (0x5A). On BeagleBone Black will default to I2C bus 0.
|
||||
if not cap.begin():
|
||||
print('Error initializing MPR121. Check your wiring!')
|
||||
sys.exit(1)
|
||||
|
||||
# Alternatively, specify a custom I2C address such as 0x5B (ADDR tied to 3.3V),
|
||||
# 0x5C (ADDR tied to SDA), or 0x5D (ADDR tied to SCL).
|
||||
#cap.begin(address=0x5B)
|
||||
|
||||
# Also you can specify an optional I2C bus with the bus keyword parameter.
|
||||
#cap.begin(bus=1)
|
||||
|
||||
# Main loop to print a message every time a pin is touched.
|
||||
print('Press Ctrl-C to quit.')
|
||||
last_touched = cap.touched()
|
||||
while True:
|
||||
current_touched = cap.touched()
|
||||
# Check each pin's last and current state to see if it was pressed or released.
|
||||
for i in range(12):
|
||||
# Each pin is represented by a bit in the touched value. A value of 1
|
||||
# means the pin is being touched, and 0 means it is not being touched.
|
||||
pin_bit = 1 << i
|
||||
# First check if transitioned from not touched to touched.
|
||||
if current_touched & pin_bit and not last_touched & pin_bit:
|
||||
print('{0} touched!'.format(i))
|
||||
# Next check if transitioned from touched to not touched.
|
||||
if not current_touched & pin_bit and last_touched & pin_bit:
|
||||
print('{0} released!'.format(i))
|
||||
# Update last state and wait a short period before repeating.
|
||||
last_touched = current_touched
|
||||
time.sleep(0.1)
|
||||
|
||||
# Alternatively, if you only care about checking one or a few pins you can
|
||||
# call the is_touched method with a pin number to directly check that pin.
|
||||
# This will be a little slower than the above code for checking a lot of pins.
|
||||
#if cap.is_touched(0):
|
||||
# print 'Pin 0 is being touched!'
|
||||
|
||||
# If you're curious or want to see debug info for each pin, uncomment the
|
||||
# following lines:
|
||||
#print '\t\t\t\t\t\t\t\t\t\t\t\t\t 0x{0:0X}'.format(cap.touched())
|
||||
#filtered = [cap.filtered_data(i) for i in range(12)]
|
||||
#print 'Filt:', '\t'.join(map(str, filtered))
|
||||
#base = [cap.baseline_data(i) for i in range(12)]
|
||||
#print 'Base:', '\t'.join(map(str, base))
|
||||
Loading…
Add table
Add a link
Reference in a new issue