Using Arduino to Develop Badge Apps
PLEASE BE AWARE THAT THE ARDUINO SDK IS NOT FULLY SUPPORTED!!
YOU MAY RUN INTO SOME ISSUES
Introduction to Arduino
The ESP32 on the badge can be programmed using the Aduino IDE.
- Install the Arduino IDE if you haven’t already.
- Install ESP32 support using these instructions
- Install PyUSB for Python 3 using pip or the package manager provided by your distro. On Debian you can run
sudo apt install python3-usb
- Download mch2022-tools
Now write your Arduino sketch as usual, by selecting the ESP32 wrover module.
But instead of uploading your sketch, use Sketch > Export compiled binary
(ctrl+alt+s)
Now you need to plug in the badge, turn it on, and launch webusb_push.py
from
the mch2022-tools repo with the
path of the binary that Arduino generate in your sketch folder.
python path/to/webusb_push.py "my cool app" path/to/my_app.ino.esp32.bin --run
After a few seconds your app should be running on the badge.
Controlling the display
The easiest way to control the display is by using the Adafruit ILI9341
library. Go to Tools > Manage Libraries...
and search for the Adafruit GFX
library and the Adafruit ILI9341 library and install both. Include them as
follows
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define PIN_LCD_CS 32
#define PIN_LCD_DC 33
#define PIN_LCD_RST 25
Adafruit_ILI9341 tft = Adafruit_ILI9341(PIN_LCD_CS, PIN_LCD_DC, PIN_LCD_RST);
And then add the following lines to the setup
function.
tft.begin(LCD_FREQ);
tft.setRotation(1);
And now you can use regular GFX commands like so:
tft.fillScreen(ILI9341_PURPLE);
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_YELLOW);
tft.setTextSize(3);
tft.println("MCH2022");
Controlling the LEDs
The LEDs are controlled using the FastLED library, which can once again be installed from the library manager.
First define and include all the things.
#include <FastLED.h>
#define PIN_LED_DATA 5
#define PIN_LED_ENABLE 19
#define NUM_LEDS 5
CRGB leds[NUM_LEDS];
And then run the following setup code:
FastLED.addLeds<SK6812, PIN_LED_DATA, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(96);
// This has to be placed after SPI (LCD) has been initialized (Arduino wants to use this pin as SPI MISO...)
pinMode(PIN_LED_ENABLE, OUTPUT);
digitalWrite(PIN_LED_ENABLE, HIGH);
And you can now just set the LED colors as follows:
leds[i] = CRGB::Purple;
Reading the buttons
The buttons are controller by the RP2040, and can be read over I2C. Here is a simple example.
#include <Wire.h>
#define PIN_I2C_SDA 22
#define PIN_I2C_SCL 21
#define PIN_RP2040_INT 34
#define RP2040_ADDR 0x17 // RP2040 co-processor
#define BNO055_ADDR 0x28 // BNO055 position sensor
#define BME680_ADDR 0x77 // BME680 environmental sensor
#define RP2040_REG_LCD_BACKLIGHT 4
#define RP2040_REG_INPUT1 0x06
#define RP2040_REG_INPUT2 0x07
void set_backlight(uint8_t brightness) {
Wire.beginTransmission(RP2040_ADDR);
Wire.write(RP2040_REG_LCD_BACKLIGHT);
Wire.write(brightness);
Wire.endTransmission();
}
uint16_t read_inputs() {
Wire.beginTransmission(RP2040_ADDR);
Wire.write(RP2040_REG_INPUT1);
Wire.endTransmission();
Wire.requestFrom(RP2040_ADDR, 4);
uint16_t input = Wire.read() | (Wire.read()<<8);
uint16_t interrupt = Wire.read() | (Wire.read()<<8);
return interrupt;
}
void setup() {
Serial.begin(115200);
Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL);
pinMode(PIN_RP2040_INT, INPUT);
read_inputs();
}
uint8_t brightness = 0;
void loop() {
if (!digitalRead(PIN_RP2040_INT)) {
Serial.println(read_inputs(), BIN);
}
set_backlight(brightness);
brightness++;
//delay(500);
}
A full list of all the registers can be found here
Reset the ESP32
Restting the ESP32 can be done using the following snippet.
#include <esp_system.h>
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
void return_to_launcher() {
REG_WRITE(RTC_CNTL_STORE0_REG, 0);
esp_restart();
}
You can now trigger this when the home button is pressed like so:
if (!digitalRead(PIN_RP2040_INT)) {
if (read_inputs() & (1<<0)) {
return_to_launcher();
}
}