This package provides the necessary code to interface the Raspberry Pi HATs(add-on boards) from raspihats.com:
Typical usage often looks like this:
#!/usr/bin/env python
# In this setup there are two I2C-HATs stacked, one DI16ac and one DQ10rly.
from raspihats.i2c_hats import DI16ac, DQ10rly
di16ac = DI16ac(0x40) # 0x40 is the I2C bus address
dq10rly = DQ10rly(0x50) # 0x50 is the I2C bus address
while True:
state = di16ac.di.channels[0] # get digital input channel 0
dq10rly.dq.channels[0] = state # set digital output channel 0
dq10rly.dq.channels[1] = not state # set digital output channel 1
Starting from hardware revision 2.0, DI16ac and DI6acDQ6rly boards can trigger an IRQ line that's connected to GPIO21 of the Raspberry Pi.
try:
import Queue as queue
except ImportError:
import queue
from time import sleep
import RPi.GPIO as GPIO
from raspihats.i2c_hats import DI16ac, DI6acDQ6rly
IRQ_PIN = 21
GPIO.setmode(GPIO.BCM)
# IRQ pin setup as input with pull-up enabled
GPIO.setup(IRQ_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# this queue is used to safely exchange information between threads
event_queue = queue.Queue(maxsize = 20)
def isr(pin):
event_queue.put(pin)
GPIO.add_event_detect(IRQ_PIN, GPIO.FALLING, callback=isr)
# b = DI16ac(0x40) # 0x40 is the I2C bus address
b = DI6acDQ6rly(0x60) # 0x60 is the I2C bus address
print(str(b.name) + ' ' + str(b.fw_version))
print('Use Ctrl+C to stop program.')
# enable rising edge IRQs for Digital Input channels 0 and 2
b.di.irq_reg.rising_edge_control = 0x05
# enable falling edge IRQs for Digital Input channels 1 and 2
b.di.irq_reg.falling_edge_control = 0x06
# dump DigitalInputs IRQ CaptureQueue contents and release IRQ line by
# writing 0 to DigitalInputs IRQ Capture Register
b.di.irq_reg.capture = 0
while True:
try:
# wait until there is something in the queue, timeout is here because a
# queue.get without a timeout can't be interrupted with a KeyboardInterrupt
pin = event_queue.get(block=True, timeout=0.2)
if pin == IRQ_PIN:
# read the DigitalInputs IRQ Capture Register(to read the values
# stored in the DigitalInputs IRQ CaptureQueue) until the
# returned value is 0, this means DigitalInputs IRQ CaptureQueue
# is empty and the IRQ line is released
while True:
capture = b.di.irq_reg.capture
if capture == 0:
break
status = capture & 0xFFFF
states = (capture >> 16) & 0xFFFF
for channel in range(0, 16):
mask = 0x01 << channel
if (status & mask) > 0:
print('IRQ detected on channel: %d, state: %d' %(channel, (states & mask) >> channel))
except queue.Empty:
pass
except KeyboardInterrupt:
# disable rising edge IRQs for Digital Input channels
b.di.irq_reg.rising_edge_control = 0
# disable falling edge IRQs for Digital Input channels
b.di.irq_reg.falling_edge_control = 0
GPIO.remove_event_detect(IRQ_PIN)
GPIO.cleanup()
break
#!/usr/bin/env python
from raspihats.i2c_hats import DI6acDQ6rly
board = DI6acDQ6rly(0x60) # 0x60 is the I2C bus address
board.name # get board name, in this case 'DI6acDQ6rly'
board.status.value # get status word
board.reset() # reset board
# cwdt - Communication WatchDog Timer
board.cwdt.period # get CommunicationWatchDogTimer(CWDT) period
board.cwdt.period = 1 # set CWDT period, any value greather than 0 enables the CWDT
board.cwdt.period = 0 # 0 disables the CWDT
# di - Digital Inputs
board.di.value # get all digital input channel states, bit 0 represents channel 0 state and so on ..
board.di.channels[0] # get digital input channel 0 state, access using channel index
board.di.channels['I0'] # get digital input channel 0 state, access using channel label
board.di.r_counters[0] # get digital input channel 0 rising edge counter
board.di.r_counters['I0'] # get digital input channel 0 rising edge counter
board.di.r_counters[0] = 0 # reset digital input channel 0 rising edge counter
board.di.r_counters['I0'] = 0 # reset digital input channel 0 rising edge counter
board.di.f_counters[0] # get digital input channel 0 falling edge counter
board.di.f_counters['I0'] # get digital input channel 0 falling edge counter
board.di.f_counters[0] = 0 # reset digital input channel 0 falling edge counter
board.di.f_counters['I0'] = 0 # reset digital input channel 0 falling edge counter
board.di.reset_counters() # reset all counters(rising and falling edge) for all channels
board.di.labels # get digital input labels
# dq - Digital Outputs
board.dq.value # get all digital output channel states, bit 0 represents channel 0 and so on ..
board.dq.value = 0 # set all digital output channel states
board.dq.channels[0] # get digital output channel 0 state, access using channel index
board.dq.channels[0] = 0 # set digital output channel 0 state
board.dq.channels['Q0'] # get digital output channel 0 state, access using channel label
board.dq.channels['Q0'] = 0 # set digital output channel 0 state
# PowerOnValue -- loaded to Digital Outputs at board power on
board.dq.power_on_value # get digital output channels PowerOnValue, bit 0 represents channel 0 and so on ..
board.dq.power_on_value = 0 # set digital output channels PowerOnValue
# SafetyValue -- loaded to Digital Outputs at CWDT timeout
board.dq.safety_value # get digital output channels SafetyValue, bit 0 represents channel 0 and so on ..
board.dq.safety_value = 0 # set digital output channels SafetyValue
board.dq.labels # get digital output labels
- Added IRQ support
- enum34 is loaded for python<3.4
- Setup script warning if it's not run with sudo(used to setup I2C ClockStretchTimeout)
- Bug fix in setup script, BCM2835 platform hardware is now recognized.
- Bug fix in robotframework interface, status.value is now returned by get_status()
- Added StatusWord class. To get raw int value use board.status.value, to get beautiful string representation use str(board.status).
- String representation of I2CHat object doesn't use an I2C bus transfer any more.
- Improved exception messages
- Improved exception handling
- Fixed I2C clock stretch timeout setup script
#!/usr/bin/env python
# In this setup there are two I2C-HATs stacked, one Di16 and one Rly10.
from raspihats.i2c_hats import Di16, Rly10
di16 = Di16(0x40) # 0x40 is the I2C bus address
rly10 = Rly10(0x50) # 0x50 is the I2C bus address
# The I2C-HAT address high nibble is fixed(0x4 for Di16, 0x5 for Rly10), the low nibble
# value is set using the on-board address jumper, range is [0x0 .. 0xF].
while True:
state = di16.di_get_channel_state('Di1.1')
rly10.do_set_channel_state('Rly1', state)
rly10.do_set_channel_state('Rly2', not state)
The python-smbus package
$ sudo apt-get install python-smbus
# or if using python 3
$ sudo apt-get install python3-smbus
# Make sure you have git, pip and setuptools installed
$ git clone git@github.com:raspihats/raspihats.git
$ cd raspihats
$ sudo python setup.py install
# or if using python 3
$ sudo python3 setup.py install
# Make sure you have pip and setuptools installed
$ sudo pip install raspihats
# or if using python 3
$ sudo pip3 install raspihats
Checkout raspihats.com