Skip to content

Multiplexers

SensorIO is extremely flexible and supports majority of Arduino shields and Grove extensions. This is achieved with hardware multiplexers and switches that can be controlled by firmware.

Multiplexer driver

There are two ways to set multiplexers:

  1. By directly controlling appropriate pins (see Pin Definitions sections) with Mbed OS built-in DigitalOut class
  2. By using a simple wrappers with more verbose, one-line settings from Github

Arduino

Multiplexer for Arduino selects which analog input pin on Arduino port (A0 to A5) is connected to main MCU analog input (PC_0/ARD_ANALOG_IN).

Pin definitions

1
2
3
4
5
6
    /**** Arduino analog multiplexer ***/
    ARD_MUX_A   = PG_6,
    ARD_MUX_B   = PG_7,
    ARD_MUX_C   = PG_8,

    ARD_ANALOG_IN = PC_0,

Pin settings

ARD_MUX_C ARD_MUX_B ARD_MUX_A Selection
0 0 0 A0
0 0 1 A1
0 1 0 A2
0 1 1 A3
1 0 0 A4
1 0 1 A5
1 1 0 CALIB_HIGH
1 1 1 CALIB_LOW

A4 and A5

Pins A4 and A5 are internally connected to D14 and D15 in some shields, therefore, remember to configure D14 (PB4) and D15 (PA8) in high impedance mode (set as INPUT) to use these analog inputs.

CALIB_HIGH and CALIB_LOW

MUX values 6 and 7 can be used to calibrate the Analog Inputs to the Max and Min values respectively.

Example

This snippet shows how to route pin A3 from Arduino port to MCU analog input (PC_0/ARD_ANALOG_IN) with DigitalOut class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "DigitalOut.h"
#include "AnalogIn.h"
#include "Serial.h"

mbed::Serial console(SERIAL_TX, SERIAL_RX, 115200);

int main(int argc, char **argv)
{
    console.printf("This is SensorIO\r\n");

    mbed::DigitalOut ardMuxA(ARD_MUX_A);
    mbed::DigitalOut ardMuxB(ARD_MUX_B);
    mbed::DigitalOut ardMuxC(ARD_MUX_C);

    mbed::AnalogIn ardAnalogIn(ARD_ANALOG_IN);

    // select pin A3 with multiplexer
    ardMuxA = 0;
    ardMuxB = 1;
    ardMuxC = 1;

    // read value
    float analogValue = ardAnalogIn.read();

    console.printf("analogValue is %f\r\n", analogValue);
}

This file can be downloaded here.

This snippet shows the same functionality, but with ArduinoMultiplexer wrapper:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include "arduinomultiplexer.h"
#include "AnalogIn.h"
#include "Serial.h"

mbed::Serial console(SERIAL_TX, SERIAL_RX, 115200);

int main(int argc, char **argv)
{
    console.printf("This is SensorIO\r\n");

    ArduinoMultiplexer multiplexer;
    mbed::AnalogIn ardAnalogIn(ARD_ANALOG_IN);

    // select pin A3 with multiplexer
    multiplexer.select(ArduinoMultiplexer::Input::SELECT_A3);

    // read value
    float analogValue = ardAnalogIn.read();

    console.printf("analogValue is %f\r\n", analogValue);
}

This file can be downloaded here.

Grove

Each Grove connector has a voltage level switch and mode selection multiplexer. Voltage level switch can be used to select between 3.3V and 5V on Vcc pin. Mode multiplexer selects function of two signal pins, from PWM, to UART, to I2C to analog input.

Pin definitions

  1. Grove 1 connector:

    1
    2
    3
    4
    5
    6
        /**** Grove 1 multiplexer pins ****/
        GROVE1_MUX_A    = PD_10,
        GROVE1_MUX_B    = PD_11,
    
        /**** Grove 1 3V3/5V switch pin ****/
        GROVE1_SW_5V = PG_9,
    
  2. Grove 2 connector:

    1
    2
    3
    4
    5
    6
        /**** Grove 2 multiplexer pins ****/
        GROVE2_MUX_A    = PG_4,
        GROVE2_MUX_B    = PG_5,
    
        /**** Grove 2 3V3/5V switch pin ****/
        GROVE2_SW_5V = PG_10,
    

Pin settings

  1. Mode multiplexer:

    GROVEX_MUX_A GROVEX_MUX_B Mode
    0 0 PWM
    0 1 UART
    1 0 I2C
    1 1 ANALOG_IN
  2. Voltage switch:

    GROVEX_SW_5V Vcc [V]
    0 3.3
    1 5

I2C on Grove

Driver for I2C on Grove connectors (both connectors share the same I2C bus) is not yet ready.

Example

This snippet shows how to configure Grove 1 connector as UART with 3.3V Vcc and Grove 2 connector as analog input with 5V Vcc:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "grovemultiplexer.h"
#include "grovetwomultiplexer.h"
#include "AnalogIn.h"
#include "Serial.h"

mbed::Serial console(SERIAL_TX, SERIAL_RX, 115200);

int main(int argc, char **argv)
{
    console.printf("This is SensorIO\r\n");

    // using generic Grove multiplexer class
    GroveMultiplexer grove1Multiplexer(GROVE1_MUX_A, GROVE1_MUX_B, GROVE1_SW_5V);
    // using SensorIO Grove 2 multiplexer class
    GroveTwoMultiplexer grove2Multiplexer;

    // select voltage (3.3V is default, so no need to change Grove 1)
    grove2Multiplexer.select(GroveMultiplexer::Voltage::VCC_5V);

    grove1Multiplexer.select(GroveMultiplexer::Mode::UART);
    grove2Multiplexer.select(GroveMultiplexer::Mode::ANALOG_IN);


    mbed::AnalogIn grove2AnalogIn(GROVE2_AI2);
    mbed::Serial grove1Uart(GROVE1_TX, GROVE1_RX, 9600);

    // read value
    float analogValue = grove2AnalogIn.read();
    console.printf("analogValue is %f\r\n", analogValue);

    // send data over Grove 1 UART
    grove1Uart.puts("From SensorIO to Grove");
}

This file can be downloaded here.

Grove multiplexers can also be used with just DigitalOut instead of GroveMultiplexer class. For this please refer to Arduino example.