Skip to content

GPIO / Qwiic

RoboBoard X4 GPIO

RoboBoard contains GPIO pins for hooking up external electronics. Can be used for simple input, output operations or with communication protocols (UART, I2C, SPI, ...).
Works same as any other Arduino development board (like TotemDuino).
Additional Qwiic port is available to connect external I2C modules.

Picture above example code
void setup() {
  Serial.begin(115200); // Start serial at 115200 baud rate
  pinMode(GPIOC, OUTPUT); // Set GPIOC to OUTPUT (HIGH or LOW)
  pinMode(GPIOD, INPUT_PULLUP); // Set GPIOD to INPUT (pull HIGH)
}
void loop() {
  // If RoboBoard button is pressed - pulsate LED on GPIOC pin 
  if (Button.isPressed()) {
    for(int i=0; i<255; i+=15) { analogWrite(GPIOC, i); delay(10); }
    for(int i=255; i>0; i-=15) { analogWrite(GPIOC, i); delay(10); }
    return;
  }
  // Check if button is pressed (connects to GND)
  if (digitalRead(GPIOD) == LOW) Serial.print("Button press, ");
  // Read potentiometer position 0-4095
  Serial.println(analogRead(GPIOA)); // Read pin GPIOA analog
  delay(100); // Wait 100ms
  digitalWrite(GPIOC, LOW); // Turn LED on
  delay(100); // Wait 100ms
  digitalWrite(GPIOC, HIGH); // Turn LED off
}

Arduino pin names

RoboBoard X4 GPIO
Arduino pins: GPIOA, GPIOB, GPIOC, GPIOD.
VCC: 3.3V output (2A max), GND: Ground pin.

Name Pin Exclusive function
GPIOA 14 MOSI, Analog, Touch
GPIOB 23 MISO
GPIOC 25 SCK, Analog, DAC
GPIOD 26 SS, Analog, DAC
- 21 SDA
- 22 SCL
  • GPIOB does not support analogRead()!
  • SPI can be mapped to any pin (MOSI, MISO, SCK, SS only shows default mapping).
  • All pin definitions can be found in pins_arduino.h file.

RoboBoard X3 v3.1 GPIO
Arduino pins: IO26, IO32, IO33.
Servo pins: SIGA, SIGB, SIGC, SIGD.
3V3: 3.3V output (0.8A max), GND: Ground pin.
Qwiic port right: Control Qwiic I2C modules over Wire object. I2C pins SDA, SCL.
Yellow port left: Control Qwiic I2C modules over Wire1 object. I2C pins SDA1, SCL1.
Or access pins IO32, IO33, 3V3, GND using "Qwiic jumper cable".

Name Pin Exclusive function
IO26 26 Analog, Touch, DAC, MOSI
IO32 32 Analog, Touch, SCL1, MISO
IO33 33 Analog, Touch, SDA1, SCK
- 15 SDA
- 5 SCL
SIGA 25 DAC
SIGB 14 Touch, SS
SIGC 16 Touch
SIGD 17 -
  • Output power 3V3 can be turned off with function Board.setEnable3V3().
  • SIGx pins can be used when motor is not connected. Contains 120 Ohm resistor!
  • Left yellow port does not have pull-up resistors!
  • SPI can be mapped to any pin (MOSI, MISO, SCK, SS only shows default mapping).
  • All pin definitions can be found in pins_arduino.h file.

RoboBoard X3 v3.0 GPIO
Arduino pins: IO26, IO32, IO33.
Servo pins: SIGA, SIGB.
3V3: 3.3V (0.5A max), GND: Ground pin.
Qwiic port right: Control Qwiic I2C modules over Wire object. I2C pins SDA, SCL.

Name Pin Exclusive function
IO26 26 Analog, Touch, DAC, MOSI
IO32 32 Analog, Touch, SCL1, MISO
IO33 33 Analog, Touch, SDA1, SCK
- 15 SDA
- 5 SCL
SIGA 25 DAC
SIGB 14 Touch, SS
  • Output power 3V3 can be turned off with function Board.setEnable3V3().
  • SIGx pins can be used when motor is not connected. Contains 120 Ohm resistor!
  • SPI can be mapped to any pin (MOSI, MISO, SCK, SS only shows default mapping).
  • All pin definitions can be found in pins_arduino.h file.

Using I2C

RoboBoard X4 GPIO

I2C (Inter-Integrated Circuit) / TWI (Two-wire Interface) communication protocol used for controlling many different devices and modules. Main communication protocol of Qwiic port.
In Arduino environment it is called "Wire".

General I2C documentation | examples

Wire object is mapped to pins of Qwiic port and IMU sensor.
To start I2C - include Wire.h file and call Wire.begin() inside setup() function to run with default parameters. A few more options available:

  • Wire.begin() - set default pins and frequency (speed) to 100kHz.
  • Wire.begin(SDA, SCL, 400000) - set default pins with 400kHz speed.
  • Wire.begin(GPIOA, GPIOB, 400000) - set to GPIOA, GPIOB pins with 400kHz speed.
  • Wire.begin(GPIOA, GPIOB) - set to GPIOA, GPIOB pins with 100kHz speed.
  • Wire.setPins(GPIOA, GPIOB) - set to GPIOA, GPIOB pins before calling Wire.begin(). Used to change SDA, SCL pins for libraries that calls Wire.begin() internally.
#include <Wire.h>
#include <Adafruit_GFX.h> // (1) Adafruit-GFX library
#include <Adafruit_SSD1306.h> // (2) Adafruit_SSD1306 library

Adafruit_SSD1306 display(128, 64);

void setup() {
  delay(500); // Wait for display to turn on
  // Set I2C SDA pin to GPIOA
  // Set I2C SCL pin to GPIOB
  // (other pins can be used also)
  Wire.setPins(GPIOA, GPIOB);
  // Initialize display (Wire.begin() is called inside library)
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for(;;); // Don't proceed, loop forever
  }
  // Print text
  display.clearDisplay(); // Clear the buffer
  display.setTextSize(2); // Change text size
  display.setTextColor(SSD1306_WHITE); // Set color
  display.setCursor(10, 25); // Center
  display.println("RoboBoard"); // Set text
  display.display(); // Write to display
}

void loop() {

}
  1. https://github.com/adafruit/Adafruit-GFX-Library
  2. https://github.com/adafruit/Adafruit_SSD1306

ESP32 has two I2C channels: Wire (mapped to Qwiic port) and Wire1 (free to use).
It's recommended to use Wire1 with GPIO pins, as it allows simultaneous use of Qwiic port and GPIO pins. Most Arduino libraries expects to communicate over Wire.

Example using Wire1 with GPIO
#include <Wire.h>
#include <Adafruit_GFX.h> // (1) Adafruit-GFX library
#include <Adafruit_SSD1306.h> // (2) Adafruit_SSD1306 library
// Change to second "Wire1" I2C peripheral
Adafruit_SSD1306 display(128, 64, &Wire1);

void setup() {
  delay(500); // Wait for display to turn on
  // Set Wire1 I2C SDA pin to GPIOA
  // Set Wire1 I2C SCL pin to GPIOB
  // (other pins can be used also)
  Wire1.setPins(GPIOA, GPIOB);
  // Initialize display (Wire1.begin() is called inside library)
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for(;;); // Don't proceed, loop forever
  }
  // Print text
  display.clearDisplay(); // Clear the buffer
  display.setTextSize(2); // Change text size
  display.setTextColor(SSD1306_WHITE); // Set color
  display.setCursor(10, 25); // Center
  display.println("RoboBoard"); // Set text
  display.display(); // Write to display
}

void loop() {

}
  1. https://github.com/adafruit/Adafruit-GFX-Library
  2. https://github.com/adafruit/Adafruit_SSD1306

Using UART (Serial)

RoboBoard X4 UART

UART (Universal Asynchronous Receiver / Transmitter) protocol is a base of most Serial communications. Can be used to communicate with external devices or printing debug messages inside Serial Monitor. Uses two wires TX, RX for transmit and receive. Both devices (on both ends) has to use same baud rate (communication speed).
In Arduino environment it is called "Serial".

Serial API documentation | examples

ESP32 has three separate UART channels:

  • Serial - standard one, mapped to USB (for printing to Serial Monitor).
  • Serial1 - free to use. Recommended with GPIO pins.
  • Serial2 - not available on X4, but may be used with X3.

Serial object can be also mapped to GPIO pins if required.

Example using Serial1 with GPIO pins
void setup() {
  // Map GPIOC to TX <-> FTDI RX
  // Map GPIOD to RX <-> FTDI TX
  // (other pins can be used also)
  // Begin UART over GPIO pins (config: 8bit data, 1 stop bit, no parity)
  Serial1.begin(115200, SERIAL_8N1, GPIOD, GPIOC); // baud, config, rx, tx
}
int counter;
void loop() {
  // Use "Serial1" to print over GPIO pins
  Serial1.print("Test ");
  Serial1.println(counter++);
  delay(100);
}

Using SPI

RoboBoard X4 SPI

Serial Peripheral Interface is commonly used for fast communication speed (up to 40 MHz). Uses 4 wires (CS, SCK, MISO, MOSI).
In Arduino environment it is called "SPI".

SPI documentation

#include <SPI.h>

// Set GPIOD pin as "CS"
const static int CS = GPIOD;

void setup() {
  // Set CS pin as output
  pinMode(CS, OUTPUT);
  // Set SPI pins SCK, MISO, MOSI
  // (other pins can be used also)
  SPI.begin(GPIOC, GPIOB, GPIOA);
  // Write byte 0x55 over SPI
  SPI.beginTransaction(SPISettings()); // Transaction settings can be added
  digitalWrite(CS, LOW); // Pull CS pin LOW to initiate transfer
  SPI.transfer(0x55); // Transfer byte 0x55
  digitalWrite(CS, HIGH); // Pull CS pin HIGH to end transfer
  SPI.endTransaction(); // End transaction
}

void loop() {

}

Using other peripherals

GPIO pins can be used with multiple peripherals. Each one has its own advantages and use cases. View full list:

Qwiic port

RoboBoard X3 Qwiic port

A connection system to attach third-party I2C modules. This allows to choose from many available sensors and other interface devices. Small and sturdy connector eliminates need for soldering and enables plug-and-play style modular systems. Each module comes with its own Arduino library (supplied by manufacturer).

This port is compatible with SparkFun Qwiic and Adafruit STEMMA QT modules.

Connector

Standard "Qwiic" connector with I2C communication and 3.3V power line. Modules usually contain 2 connectors for joining multiple of them (daisy-chaining).
Single RoboBoard Qwiic port can host multiple modules.

Qwiic connector

Standard I2C Qwiic port. Controlled with Wire object. I2C pins SDA, SCL.

X3 v3.1 JST ports

Contains 2 distinctive ports:
Qwiic - standard I2C Qwiic port. Controlled with Wire object. I2C pins SDA, SCL.
GPIO - optional I2C port. Controlled with Wire1 object. I2C pins SDA1, SCL1.
"GPIO" does not have pull-up resistors!.

X3 v3.0 JST port

Standard I2C Qwiic port. Controlled with Wire object. I2C pins SDA, SCL.

Wires:
• Black = GND
• Red = 3.3V
• Blue = SDA
• Yellow = SCL

Cable: standard "Qwiic cable". Can be found in local electronics store.
Connector: SM04B-SRSS-TB 4-pin

Installing modules

When module is connected to the RoboBoard - it will simply power on but won't do anything. To make any use of it - you need to install Arduino library, specific to connected module. It should be provided by manufacturer. Libraries also contain example code, explaining how to use it.

Usage example

X4 qwiic

Code example to display text as in picture:

#include <Wire.h>
#include <SFE_MicroOLED.h> // (1) SparkFun Micro OLED Breakout library

#define PIN_RESET GPIOA    // Not used
MicroOLED oled(PIN_RESET); // I2C declaration

void setup() {
  Wire.begin(); // Initialize I2C

  oled.begin(0x3D, Wire); // Initialize OLED

  oled.clear(ALL); // Clear display internal memory
  oled.clear(PAGE); // Clear buffer

  oled.setFontType(1); // Change font for bigger letters

  oled.setCursor(0, 0); // Set cursor to top-left

  oled.println("Robo"); // Print text
  oled.println("Board");
  oled.println("X4");

  oled.display();  // Display what's in the buffer
}

void loop() {

}
  1. https://github.com/sparkfun/SparkFun_Micro_OLED_Arduino_Library

Qwiic vs STEMMA QT

A different brand names describing same connector and pin order. One is introduced by SparkFun, another by - Adafruit.

  • STEMMA QT modules - works with 3.3V and 5V microcontrollers (like Arduino UNO).
  • Qwiic modules - works with 3.3V microcontrollers only! (can't use with Arduino UNO).

Totem RoboBoard is 3.3V so both brand modules can be used.

Internal pin mapping

A list of ESP32 pins that are assigned to specific functions inside RoboBoard. Only for reference and shouldn't be accessed directly. Used internally by RoboBoard API.

Number Name Description
1 Serial TX UART communication over USB
3 Serial RX UART communication over USB
15 SDA I2C bus pin routed to IMU and Qwiic port. Has external 2k2 Ohm pull-up
5 SCL I2C bus pin routed to IMU and Qwiic port. Has external 2k2 Ohm pull-up
26 IO26 GPIO pin
32 IO32 GPIO pin
33 IO33 GPIO pin
22 MOTORA_INA DC motor port A pin 0
12 MOTORA_INB DC motor port A pin 1
23 MOTORB_INA DC motor port B pin 0
19 MOTORB_INB DC motor port B pin 1
18 MOTORC_INA DC motor port C pin 0
21 MOTORC_INB DC motor port C pin 1
4 MOTORD_INA DC motor port D pin 0
2 MOTORD_INB DC motor port D pin 1
25 SERVOA_IN Servo motor port A (SIG)
14 SERVOB_IN Servo motor port B (SIG)
16 SERVOC_IN Servo motor port C (SIG)
17 SERVOD_IN Servo motor port D (SIG)
0 BUTTON BOOT button
13 RGB RGB light strip data pin
27 3V3_EN Peripheral 3.3V LDO enable pin
34 VERSION_DETECT Detect board revision
35 BATTERY_CHARGE State of battery charging (if charging)
36 BATTERY_CURRENT Battery current measurement
37 BATTERY_VOLTAGE Battery voltage measurement
38 USB_DETECT State of USB port (is plugged in)
39 IMU_INT IMU chip interrupt pin
Number Name Description
1 Serial TX UART communication over USB
3 Serial RX UART communication over USB
21 SDA I2C bus pin routed to IMU and Qwiic port. Has external 2k2 Ohm pull-up
22 SCL I2C bus pin routed to IMU and Qwiic port. Has external 2k2 Ohm pull-up
14 GPIOA GPIO pin
23 GPIOB GPIO pin
25 GPIOC GPIO pin
26 GPIOD GPIO pin
17 CAN_TX CAN bus transmit pin routed to TotemBUS
34 CAN_RX CAN bus receive pin routed to TotemBUS
5 CAN_EN CAN bus transceiver enable (active LOW)
4 DRIVER_DFU Device Firmware Update pin of STM32 co-processor
15 DRIVER_RESET Reset pin of STM32 co-processor
16 DRIVER_RX UART RX pin of STM32 co-processor
27 DRIVER_TX UART TX pin of STM32 co-processor
13 LED Status LED bellow ESP32
18 BUTTON User button below ESP32
39 USB_DETECT State of USB port (is plugged in)
36 BATTERY_VOLTAGE Battery voltage measurement
35 IMU_INT IMU chip interrupt pin (v1.1 only)
14 IMU_INT IMU chip interrupt pin (v1.0 only)

RoboBoard X4 v1.0 GPIO

First revision of RoboBoard X4 had GPIO pins connected to co-processor instead of ESP32. For this reason Arduino API can't be used and special commands are required to interact. This also limits to digital read / write and analog read / write only.

GPIO control functions (click to expand)
X410_digitalWrite(pin, state)
Set GPIO pin state. Works similar like Arduino function digitalWrite().
Calling this function will reconfigure pin to output.
Parameter:
pin - pin number [0:3]
state - GND (0V) or VCC (3.3V) [LOW:HIGH]
(state) X410_digitalRead(pin)
Read GPIO pin state. Works similar like Arduino function digitalRead().
Calling this function will reconfigure pin to input.
Returns:
pin - pin number [0:3]
state - GND (0V) or VCC (3.3V) [LOW:HIGH]
X410_analogWrite(pin, value)
Set GPIO pin analog value. Works similar like Arduino function analogWrite(). Calling this function will reconfigure pin to output.
Parameter:
pin - pin number [0:3]
value - analog value [0:20]. (0, 10, 20) = (0V, 1.65V, 3.3V).
(value) X410_analogRead(pin)
Read GPIO pin analog value. Works similar like Arduino function analogRead(). Calling this function will reconfigure pin to output.
Returns:
pin - pin number [0:3]
value - analog value [0:1023]. (0, 512, 1023) = (0V, 1.65V, 3.3V).
X410_pinMode(pin, mode)
Turn on GPIO pin pulldown or pullup resistor. Works similar like Arduino function pinMode(pin, INPUT_PULLUP).
Parameter:
pin - pin number [0:3]
mode - turn on pulldown or pullup [LOW:HIGH]. (LOW, HIGH) = (GND (0V), VCC (3.3V)).

Example:

void loop() {
  // Toggle GPIOA pin
  X410_digitalWrite(GPIOA, HIGH);
  delay(1000);
  X410_digitalWrite(GPIOA, LOW);
  delay(1000);
}