Monday, 25 April 2016

Upto 64 programmable digital I/O for the Raspberry Pi

The newly launched Custard Pi 4 provides 8 digital I/O per board. Each board can be set to one of 8 seperate I2C addresses. When you use 8 Custard Pi 4s you can get upto 64 digital I/O with each pin individually programmable as an input or an output.

Each Custard Pi 4 allows the user complete flexibility in how each Digital I/O is configured. So for example with a single card the user can have 8 inputs, 8 outputs, 4 inputs & 4 outputs or indeed any other combination just by setting up the I/O expander IC (MCP23008) as required.

As the I2C address on each card be changed the user can use upto 8 of these with a single Raspberry Pi. This allows the user even more flexibility and some of the possible combinations are shown below.
*             64 digital outputs
*             64 digital inputs
*             32 digital outputs and 32 digital inputs

 The image above shows 4 x Custard Pi 4 boards giving the user upto 32 digital I/O to play with. 

The Custard Pi 4 uses a stacking 26 way connector. What this means is that when it is plugged into the Raspberry Pi GPIO, these pins are still available for other accessories. The Custard Pi 4 can also be plugged into the 40 pin GPIO provided on the later raspberry Pi’s such as the A+. B+, Raspberry Pi 2,3  and Zero models.

When using the I2C bus of the MCP23008 the 3 key registers are as follows.

IODIR - this sets which bit is an output and which one is an input
GPIO - this reads the status of the inputs
OLAT - this sets the output latch


The Custard Pi 4 uses the I2C bus and provides plenty of I/O for projects. Sample code is presented below.

Appendix : Sample code for setting up and using the Custard Pi 4

There are two programs listed below. One has some functions defined which is then used by the second program to test out the Custard Pi 4.

The functions -

This program defines the I2C bus addresses that are available. It sets up the I2C 8 port buffer (MCP23008) as 4 inputs and 4 outputs. Bits 0 to 3 are set as inputs and bits 4 to 7 are set as outputs. It then defines the values to set each output as a High or a Low (ONbit and OFFbit). Then it defines functions which can be called from the test routine.

#1/usr/bin/env python
import time
import smbus

# Custard Pi 4 resources v1.0 22nd April 2016

#I2C addresses
#Set suitable address on Custard Pi 4

add0= 0x20
add1= 0x21
add2= 0x22
add3= 0x23
add4= 0x24
add5= 0x25
add6= 0x26
add7= 0x27


#set IODIR register
iodir= 0x00
#set bit 0 to 3 as inputs, bits 4 to 7 as outputs
inout= 0x0F
#set GPIO register
gpio= 0x09
#set output latch

#set output HIGH
ONbit4= 0x10
ONbit5= 0x20
ONbit6= 0x40
ONbit7= 0x80

#set output LOW
OFFbit4= 0xEF
OFFbit5= 0xDF
OFFbit6= 0xBF
OFFbit7= 0x7F

def setbit(address, byte):
    #sets selected port pin
    outstatus = bus.read_byte_data(address, olat) | byte
    bus.write_byte_data(address, gpio, outstatus)

def clrbit(address, byte):
    #clears selected port pin
    outstatus = bus.read_byte_data(address, olat) & byte
    bus.write_byte_data (address, gpio, outstatus)

def readbit(address, bit):
    #read status of bit 0 to 3
    bitvalue = bus.read_byte_data(address, gpio) & bit
    return bitvalue

def setinandout(address):           
    #set inputs & outputs
    bus.write_byte_data(address, iodir, inout)

def setpullups(address):           
    #set inputs & outputs
    bus.write_byte_data(address, 0x06, 0xFF)

def alloff(address):
    #clear all outputs low
    bus.write_byte_data (address, gpio, 0x00)


The test routine -

This test routine defines the I2C address to be used (add0. It then uses the command ‘setinandout’ to set bit 0 to 3 as inputs and bit 4 to 7 as outputs. All the outputs have pullups enabled and then switched to zero as default.

The test routine then sets each output High in turn and then Low again after a 0.5S pause. It then reads each of the 4 input in turn and prints out the status to the screen

#1/usr/bin/env python

import time
import cpi4

#start program





while True:
    cpi4.setbit(board1, cpi4.ONbit4)
    time.sleep (0.2)
    cpi4.setbit(board1, cpi4.ONbit5)
    time.sleep (0.2)
    cpi4.setbit(board1, cpi4.ONbit6)
    time.sleep (0.2)
    cpi4.setbit(board1, cpi4.ONbit7)
    time.sleep (0.5)

    cpi4.clrbit(board1, cpi4.OFFbit4)
    cpi4.clrbit(board1, cpi4.OFFbit5)
    cpi4.clrbit(board1, cpi4.OFFbit6)
    cpi4.clrbit(board1, cpi4.OFFbit7)

    time.sleep (0.5)

    bit0 = (cpi4.readbit (board1, 0x01))
    bit1 = (cpi4.readbit (board1, 0x02))
    bit2 = (cpi4.readbit (board1, 0x04))
    bit3 = (cpi4.readbit (board1, 0x08))

    if bit0 == 0:
        print "bit0 low"
        print "bit0 high"

    if bit1 == 0:
        print "bit1 low"
        print "bit1 high"
    if bit2 == 0:
        print "bit2 low"
        print "bit2 high"

    if bit3 == 0:
        print "bit3 low"
        print "bit3 high"

    print "***************************"

import sys

No comments:

Post a Comment