Remarks

Mcp23x08
Status
Source code GitHub
NuGet package

The MCP23008 chip is an 8-bit (8 port) digital I/O expander chip that uses I2C to communicate. It can be used to add additional digital input and output ports to Meadow and can be combined with up to eight MCP23008 chips in total, providing 64 additional ports.

MCP23008 is a ubiquitous chip in the hardware world and is the typical interface chip for common I2C LCD backpacks, with the 74595 chip being the typical interface chip for SPI LCD backpacks.

NOTE This is a pre-release driver, and interrupts have not been implemented yet.

MCP Chip Family

In addition to the MCP23008, the MCP family of chips includes; the MCP23017, which is a 16-bit version of the MCP23008, offering 16 digital ports in total, and the MCP23S08 and MCP23S017 which are SPI versions of the MCP23008 and MCP23017, respectively.

Chip Addressing

The I2C address of the chip is configurable via the address pins and is in the binary form of 0100[A2][A1][A0], where A2, A1, and A0 refer to the three address pins on the chip:

For example, if all address pins were tied to ground, then the address of the chip would be 0100000 in binary, or 0x20 in hex, and 32 in decimal.

The I2C addresses can then be as follows, where 0 represents an address pin connected to ground, and 1 represents an address pin connected to 3.3V:

Address Header A2 A1 A0 Resulting Hex Address Resulting Decimal Address
0100 0 0 0 0x20 32
0100 0 0 1 0x21 33
0100 0 1 0 0x22 34
0100 0 1 1 0x23 35
0100 1 0 0 0x24 36
0100 1 0 1 0x25 37
0100 1 1 0 0x26 38
0100 1 1 1 0x27 39

Because there are 8 address possibilities, it's possible to put 8 MCP23008 chips on a single I2C bus.

To make this simpler, when instantiating an MCP23008 object, there is a constructor overload that takes the address pin configurations instead of an address, so that Meadow.Foundation uses the appropriate address based on the pins, instead of requiring a pre-computed address.

Other Pins

In addition to the address pins, there are a number of other pins that must be connected up:

  • Not Reset - The RESET pin is actually a "Not Reset." The line above "Reset" means "not." So unless that pin is pulled high (3.3V), the chip will reset itself at random times and you'll get connection errors.
  • SCL and SDA - The SCL and SDA pins are the I2C clock and data pins and go to the SC and SD pins on the Meadow, respectively. Each of these should also generally be pulled high (3.3V) via a 4.7kΩ resistor. See the I2C guide for more information.
  • INT - The INT pin is for interrupt notifications, and is only necessary when using the GPIO pins in input mode and you want an event raised when the input value changes.
  • VSS and VDD - These go to ground and 3.3V power, respectively, and power the chip.

Wiring Example

Characteristic Locus
Inheritance System.Object > Mcp23x08
Namespace Meadow.Foundation.ICs.IOExpanders
Assembly Mcp23x08.dll

Syntax

public class Mcp23x08 : IIODevice

Constructors

Mcp23x08()

Declaration
protected Mcp23x08()

Mcp23x08(II2cBus, Boolean, Boolean, Boolean, IDigitalInputPort)

Instantiates an Mcp23008 on the specified I2C bus using the appropriate peripheral address based on the pin settings. Use this method if you don't want to calculate the address.

Declaration
public Mcp23x08(II2cBus i2cBus, bool pinA0, bool pinA1, bool pinA2, IDigitalInputPort interruptPort = null)

Parameters

Type Name Description
II2cBus i2cBus
System.Boolean pinA0

Whether or not Address0 pin is pulled high.

System.Boolean pinA1

Whether or not Address1 pin is pulled high.

System.Boolean pinA2

Whether or not Address2 pin is pulled high.

IDigitalInputPort interruptPort

Optional IDigitalInputPort used to support interrupts. The MCP will notify a single port for an interrupt on any input configured pin. The driver takes care of looking up which pin the interrupt occurred on, and will raise it on that port, if a port is used.

Mcp23x08(II2cBus, Byte, IDigitalInputPort)

Instantiates an Mcp23008 on the specified I2C bus, with the specified peripheral address.

Declaration
public Mcp23x08(II2cBus i2cBus, byte address = 32, IDigitalInputPort interruptPort = null)

Parameters

Type Name Description
II2cBus i2cBus
System.Byte address
IDigitalInputPort interruptPort

Fields

_lock

object for using lock() to do thread synch

Declaration
protected object _lock

Field Value

Type Description
System.Object

Properties

Capabilities

Declaration
public DeviceCapabilities Capabilities { get; }

Property Value

Type Description
DeviceCapabilities

Pins

Declaration
public Mcp23x08.PinDefinitions Pins { get; }

Property Value

Type Description
Mcp23x08.PinDefinitions

Methods

ConfigureInputPort(IPin, Boolean, InterruptMode)

Declaration
public void ConfigureInputPort(IPin pin, bool enablePullUp = false, InterruptMode interruptMode = null)

Parameters

Type Name Description
IPin pin
System.Boolean enablePullUp
InterruptMode interruptMode

CreateAnalogInputPort(IPin, Single)

Declaration
public IAnalogInputPort CreateAnalogInputPort(IPin pin, float voltageReference = 3.3F)

Parameters

Type Name Description
IPin pin
System.Single voltageReference

Returns

Type Description
IAnalogInputPort

CreateBiDirectionalPort(IPin, Boolean, InterruptMode, ResistorMode, PortDirectionType, Double, Double, OutputType)

Declaration
public IBiDirectionalPort CreateBiDirectionalPort(IPin pin, bool initialState = false, InterruptMode interruptMode = null, ResistorMode resistorMode = null, PortDirectionType initialDirection = null, double debounceDuration = 0, double glitchDuration = 0, OutputType outputType = null)

Parameters

Type Name Description
IPin pin
System.Boolean initialState
InterruptMode interruptMode
ResistorMode resistorMode
PortDirectionType initialDirection
System.Double debounceDuration
System.Double glitchDuration
OutputType outputType

Returns

Type Description
IBiDirectionalPort

CreateDigitalInputPort(IPin, InterruptMode, ResistorMode, Double, Double)

Declaration
public IDigitalInputPort CreateDigitalInputPort(IPin pin, InterruptMode interruptMode = null, ResistorMode resistorMode = null, double debounceDuration = 0, double glitchFilterCycleCount = 0)

Parameters

Type Name Description
IPin pin
InterruptMode interruptMode
ResistorMode resistorMode
System.Double debounceDuration
System.Double glitchFilterCycleCount

Returns

Type Description
IDigitalInputPort

CreateDigitalOutputPort(IPin, Boolean, OutputType)

Creates a new DigitalOutputPort using the specified pin and initial state.

Declaration
public IDigitalOutputPort CreateDigitalOutputPort(IPin pin, bool initialState = false, OutputType outputType = null)

Parameters

Type Name Description
IPin pin

The pin number to create the port on.

System.Boolean initialState

Whether the pin is initially high or low.

OutputType outputType

Returns

Type Description
IDigitalOutputPort

CreateI2cBus(IPin, IPin, Int32)

Declaration
public II2cBus CreateI2cBus(IPin clock, IPin data, int frequencyHz = 100000)

Parameters

Type Name Description
IPin clock
IPin data
System.Int32 frequencyHz

Returns

Type Description
II2cBus

CreateI2cBus(IPin, IPin, UInt16)

Declaration
public II2cBus CreateI2cBus(IPin clock, IPin data, ushort speed = 100)

Parameters

Type Name Description
IPin clock
IPin data
System.UInt16 speed

Returns

Type Description
II2cBus

CreateI2cBus(IPin[], Int32)

Declaration
public II2cBus CreateI2cBus(IPin[] pins, int frequencyHz = 100000)

Parameters

Type Name Description
IPin[] pins
System.Int32 frequencyHz

Returns

Type Description
II2cBus

CreateI2cBus(IPin[], UInt16)

Declaration
public II2cBus CreateI2cBus(IPin[] pins, ushort speed = 100)

Parameters

Type Name Description
IPin[] pins
System.UInt16 speed

Returns

Type Description
II2cBus

CreatePwmPort(IPin, Single, Single, Boolean)

Declaration
public IPwmPort CreatePwmPort(IPin pin, float frequency = 100F, float dutyCycle = 0.5F, bool invert = false)

Parameters

Type Name Description
IPin pin
System.Single frequency
System.Single dutyCycle
System.Boolean invert

Returns

Type Description
IPwmPort

CreateSerialPort(SerialPortName, Int32, Int32, Parity, StopBits, Int32)

Declaration
public ISerialPort CreateSerialPort(SerialPortName portName, int baudRate, int dataBits = 8, Parity parity = null, StopBits stopBits = null, int readBufferSize = 4096)

Parameters

Type Name Description
SerialPortName portName
System.Int32 baudRate
System.Int32 dataBits
Parity parity
StopBits stopBits
System.Int32 readBufferSize

Returns

Type Description
ISerialPort

CreateSpiBus(IPin, IPin, IPin, SpiClockConfiguration)

Declaration
public ISpiBus CreateSpiBus(IPin clock, IPin mosi, IPin miso, SpiClockConfiguration config)

Parameters

Type Name Description
IPin clock
IPin mosi
IPin miso
SpiClockConfiguration config

Returns

Type Description
ISpiBus

CreateSpiBus(IPin, IPin, IPin, Int64)

Declaration
public ISpiBus CreateSpiBus(IPin clock, IPin mosi, IPin miso, long speed)

Parameters

Type Name Description
IPin clock
IPin mosi
IPin miso
System.Int64 speed

Returns

Type Description
ISpiBus

CreateSpiBus(IPin[], Int64)

Declaration
public ISpiBus CreateSpiBus(IPin[] pins, long speed)

Parameters

Type Name Description
IPin[] pins
System.Int64 speed

Returns

Type Description
ISpiBus

HandleChangedInterrupt(Object, EventArgs)

Declaration
protected void HandleChangedInterrupt(object sender, EventArgs e)

Parameters

Type Name Description
System.Object sender
System.EventArgs e

Initialize()

Initializes the chip for use:

  • Puts all IOs into an input state
  • zeros out all setting and state registers
Declaration
protected void Initialize()

IsValidPin(IPin)

Checks whether or not the pin passed in exists on the chip.

Declaration
protected bool IsValidPin(IPin pin)

Parameters

Type Name Description
IPin pin

Returns

Type Description
System.Boolean

RaiseInputChanged(Byte, Byte)

Declaration
protected void RaiseInputChanged(byte interruptPins, byte currentStates)

Parameters

Type Name Description
System.Byte interruptPins
System.Byte currentStates

ReadFromPorts()

Reads a byte value from all of the pins. little-endian; the least significant bit is the value of GP0. So a byte value of 0x60, or 0110 0000, means that pins GP5 and GP6 are high.

Declaration
public byte ReadFromPorts()

Returns

Type Description
System.Byte

A little-endian byte mask of the pin values.

ReadPort(IPin)

Gets the value of a particular port. If the port is currently configured as an output, this will change the configuration.

Declaration
public bool ReadPort(IPin pin)

Parameters

Type Name Description
IPin pin

Returns

Type Description
System.Boolean

ResetPin(IPin)

Sets the pin back to an input

Declaration
protected void ResetPin(IPin pin)

Parameters

Type Name Description
IPin pin

SetClock(DateTime)

Declaration
public void SetClock(DateTime dateTime)

Parameters

Type Name Description
System.DateTime dateTime

SetPortDirection(IPin, PortDirectionType)

Sets the direction of a particular port.

Declaration
public void SetPortDirection(IPin pin, PortDirectionType direction)

Parameters

Type Name Description
IPin pin
PortDirectionType direction

WriteToPort(IPin, Boolean)

Sets a particular pin's value. If that pin is not in output mode, this method will first set its mode to output.

Declaration
public void WriteToPort(IPin pin, bool value)

Parameters

Type Name Description
IPin pin

The pin to write to.

System.Boolean value

The value to write. True for high, false for low.

WriteToPorts(Byte)

Outputs a byte value across all of the pins by writing directly to the output latch (OLAT) register.

Declaration
public void WriteToPorts(byte mask)

Parameters

Type Name Description
System.Byte mask

Events

InputChanged

Raised when the value of a pin configured for input changes. Use in conjunction with parallel port reads via ReadFromPorts(). When using individual DigitalInputPort objects, each one will have their own Changed event

Declaration
public event EventHandler<IOExpanderInputChangedEventArgs> InputChanged

Event Type

Type Description
System.EventHandler<IOExpanderInputChangedEventArgs>