The Expander class constructs objects that represent a single I2C IO Expander attached to the physical board. Expansion chips are useful for adding additional I/O to a project. In certain cases, I/O expansion chips can be used to provide capabilities on platforms that don't support natively support them. A couple examples:

  • To add "Analog Read" (ADC) capabilities to your Raspberry Pi project, use either:
    • PCF8591
    • GROVEPI
  • To add "Servo Write" (60Hz PWM) capabilities to your Raspberry Pi or pcDuino project, use either:
    • PCA9685
    • GROVEPI
  • To add "Ping Read" capabilities (Proximity instances for HCSR04, Ultrasonic Ping, Parallax Ping, etc.) to your Raspberry Pi project, use:
    • GROVEPI
  • Control a shift register as a "sub" board, use:
    • 74HC595

Supported Expanders:

This list will continue to be updated as more component support is implemented.

Parameters

  • Controller String When using just the controller name as an argument, the default I2C bus address will be used.

    • MCP23017
    • MCP23008
    • PCF8574
    • PCF8574A
    • PCF8575
    • PCF8591
    • PCA9685
    • MUXSHIELD2
    • GROVEPI
    • 74HC595
    • CD74HC4067
    // Examples:
    new five.Expander("MCP23017");
    
    new five.Expander("PCF8574");
    
    new five.Expander("PCF8575");
    
  • General Options

    PropertyTypeValue/DescriptionDefaultRequired
    controllerstringMCP23017, MCP23008, PCF8574, PCF8574A, PCF8575, PCF8591, PCA9685, MUXSHIELD2, GROVEPI, 74HC595, CD74HC4067. The Name of the controller to useYes
    addressNumberAddress for I2C device.By Deviceno

    new five.Expander({
      controller: "MCP23017"
    });
    
    // or
    
    new five.Expander({
      controller: "MCP23017",
      address: 0x??
    });
    
    Expander Capabilities
    ChipPinsModes
    MCP2301716INPUT, OUTPUT
    MCP230088INPUT, OUTPUT
    PCF85748INPUT, OUTPUT
    PCF8574A8INPUT, OUTPUT
    PCF857516INPUT, OUTPUT
    PCF85914ANALOG
    PCA968516OUTPUT, PWM, SERVO
    MUXSHIELD248INPUT, OUTPUT, ANALOG *
    GROVEPI10 **INPUT, OUTPUT, ANALOG, PWM, SERVO
    CD74HC406716ANALOG
    LIS3DH2ANALOG, I2C

* Modes limited to one per row

** 7 Digital, 3 Analog

Default Addresses
ChipRangeDefault
MCP230170x20-0x270x20
MCP230080x20-0x270x20
PCF85740x20-0x270x20
PCF8574A0x38-0x3F0x38
PCF85750x20-0x270x20
PCF85910x48-0x4F0x48
PCA96850x40-0x4F0x40
GROVEPI0x040x04
CD74HC40670x0A-0x0D0x0A
LIS3DH0x180x18

Shape

Property NameDescriptionRead Only
idA user definable id value. Defaults to a generated uidNo
pinsAn array of pin objects, containing capability data.No
MODESAn object containing supported modes.No

Component Initialization

MCP23017

// Create a MCP23017 Expander object:
//
//  - attach SDA and SCL to the I2C pins on
//     your board (A4 and A5 for the Uno)
//  - specify the MCP23017 controller

new five.Expander("MCP23017");

// or

new five.Expander({
  controller: "MCP23017"
});

// or

new five.Expander({
  controller: "MCP23017",
  address: 0x??
});

MCP23017

MCP23008

// Create a MCP23008 Expander object:
//
//  - attach SDA and SCL to the I2C pins on
//     your board (A4 and A5 for the Uno)
//  - specify the MCP23008 controller

new five.Expander("MCP23008");

// or

new five.Expander({
  controller: "MCP23008"
});

// or

new five.Expander({
  controller: "MCP23008",
  address: 0x??
});

MCP23008

PCF8574

// Create a PCF8574 Expander object:
//
//  - attach SDA and SCL to the I2C pins on
//     your board (A4 and A5 for the Uno)
//  - specify the PCF8574 controller

new five.Expander("PCF8574");

// or

new five.Expander({
  controller: "PCF8574"
});

// or

new five.Expander({
  controller: "PCF8574",
  address: 0x??
});

PCF8574

PCF8575

// Create a PCF8575 Expander object:
//
//  - attach SDA and SCL to the I2C pins on
//     your board (A4 and A5 for the Uno)
//  - specify the PCF8575 controller

new five.Expander("PCF8575");

// or

new five.Expander({
  controller: "PCF8575"
});

// or

new five.Expander({
  controller: "PCF8575",
  address: 0x??
});

PCF8575

PCA9685

// Create a PCA9685 Expander object:
//
//  - attach SDA and SCL to the I2C pins on
//     your board (A4 and A5 for the Uno)
//  - specify the PCA9685 controller

new five.Expander("PCA9685");

// or

new five.Expander({
  controller: "PCA9685"
});

// or

new five.Expander({
  controller: "PCA9685",
  address: 0x??
});

PCA9685

PCF8591

// Create a PCF8591 Expander object:
//
//  - attach SDA and SCL to the I2C pins on
//     your board (A4 and A5 for the Uno)
//  - specify the PCF8591 controller

new five.Expander("PCF8591");

// or

new five.Expander({
  controller: "PCF8591"
});

// or

new five.Expander({
  controller: "PCF8591",
  address: 0x??
});

PCF8591

74HC595

// Create a 74HC595 Expander object:
// (change pins to appropriate pins for board)
new five.Expander({
  controller: "74HC595",
  pins: {
    data: 2,
    clock: 3,
    latch: 4
  }
});

74HC595

CD74HC4067

// Create a CD74HC4067 Expander object:
//
//  - attach SDA and SCL to the I2C pins on
//     your board (A4 and A5 for the Uno)
//  - specify the CD74HC4067 controller

new five.Expander("CD74HC4067");

// or

new five.Expander({
  controller: "CD74HC4067"
});

// or

new five.Expander({
  controller: "CD74HC4067",
  address: 0x??
});

CD74HC4067

Usage

Expander objects have the same surface API as an IO Plugin, which allows them to be optionally used as an IO Plugin themselves. The usage examples here show how an Expander can be used to create a virtual board with Board.Virtual that can be passed to any Johnny-Five component class initialization.

Example: Digital or PWM Output

var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var expander = new five.Expander({
    controller: "PCA9685"
  });

  var virtual = new five.Board.Virtual({
    io: expander
  });

  var led = new five.Led({
    pin: 0,
    board: virtual
  });

  led.on();
  // or
  // led.pulse();
});

PCA9685

Example: Digital Input & Output

var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  // An Expander instance can also be passed
  // directly as an argument to Virtual
  var virtual = new five.Board.Virtual(
    new five.Expander("PCF8575")
  );

  var led = new five.Led({
    board: virtual,
    pin: 0,
  });

  var button = new five.Button({
    board: virtual,
    pin: 17,
  });

  button.on("press", function() {
    led.on();
  });

  button.on("release", function() {
    led.off();
  });
});

PCF8575 Led & Button

API

While the API of an Expander instance will be the same as a Board instance, not all capabilities will always be supported. In latter cases, attempts to call methods that would result in attempting an unsupported operation will throw an exception.

  • normalize(pin) Provides pin value normalization. In most cases, this will simply return the value it was passed. It exists to override the default Firmata-centric normalization.

    expander.normalize(1); // 1;
    
  • pinMode(pin, mode) Set the mode of a pin. Must correspond to a mode listed in the MODES property. Expander Capabilities

    expander.pinMode(0, expander.MODES.INPUT);
    
  • analogRead(pin, handler) Read an ANALOG pin. Expander Capabilities

    expander.analogRead(0, function(value) { ... });
    
  • digitalRead(pin, handler) Read an INPUT pin. Expander Capabilities

    expander.digitalRead(0, function(value) { ... });
    
  • analogWrite(pin, 0-255) An alias to pwmWrite, for backward compat only. Use pwmWrite instead.

  • digitalWrite(pin, HIGH | LOW) Write a HIGH or LOW value to an OUTPUT pin. Expander Capabilities

    expander.digitalWrite(0, 1);
    
  • pwmWrite(pin, 0-255) Write an 8-bit PWM value to a PWM pin. Expander Capabilities

    expander.pwmWrite(0, 255);
    
  • servoWrite(pin, 0-180) Write a 0-180° value to a SERVO pin. Expander Capabilities

    expander.servoWrite(0, 180);
    

Events

  • digital-read-# Whenever digitalRead(pin, ...) is called, an event handler with naming form of digital-read-# (where # is the pin number) is registered.

  • analog-read-# Whenever analogRead(pin, ...) is called, an event handler with naming form of analog-read-# (where # is the pin number) is registered.

  • ready For compatibility with IO Plugins only. This event is meaningless, so don't use it.

Examples

Hi! The Johnny-Five community is building new projects every day. We made this newsletter to tell you about what's new, what's good, and what's next for Open Source robotics. Join us in exploring what we can make together.

Fork me on GitHub