Turn an ESP32-C3FH4-RGB board into a Cheerlight using Arduino IDE

While playing around trying to get this board going on Windows using Micropython (and failing quite a lot), I decided to get it going using Arduino IDE and prove that the hardware itself was OK.
So I followed @andypiper@macaw.social guides at https://github.com/andypiper/ESP32-C3FH4-RGB/tree/62d5b4af4be39be90401bf4eb50072b3ed292fcf and got it the strandtest example working.
Note: To get the serial monitor to work – make sure you set USB CDC On Boot to Enabled and set JTAG Adaptor to ESP USB Serial

I then merged in Nick O’Leary’s PubSubClient #MQTT library and got it working as a Cheerlights receiver.
I also, added in the code to use the watchdog hardware timer to make it a hopefully very robust solution.
Note: the code uses data from my own broker. The topic cheerlights/rgb echoes the current cheerlight as a 3 byte payload, which makes it a bit easier to use that having to parse a hex string
//#include <ESP8266WiFi.h>
#include <WiFi.h>
#include <esp_task_wdt.h>
#include <PubSubClient.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// Update these with values suitable for your network.
const char* ssid = "xxx";
const char* password = "xxx";
const char* mqtt_server = "simplesi.cloud";
int cheerColour = 255;
int loopCount = 0;
#define mqtt_port 1883
#define MQTT_SERIAL_RECEIVER_CH "cheerlights/rgb"
//ESP32 Only but safe to leave in for all devices
#define WDT_TIMEOUT 10
//Uncomment for ESP32-C3FH4-RGB
#define LED_PIN 8
#define LED_COUNT 25
#define HEARTBEAT_PIN 10
// Uncomment for WEMOS D1 mini with 4 NEOpixels
//#define LED_PIN 4
//#define LED_COUNT 4
//#define HEARTBEAT_PIN 2
// How many NeoPixels are attached?
// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 10 // Set BRIGHTNESS to about 1/5 (max = 255)
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
WiFiClient wifiClient;
PubSubClient client(wifiClient);
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.print(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.print("WiFi connected. ");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
//Once connected,...
// ... and resubscribe
client.subscribe(MQTT_SERIAL_RECEIVER_CH);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void callback(char* topic, byte *payload, unsigned int length) {
Serial.print("message on topic: ");
Serial.println(topic);
Serial.print("data:");
Serial.write(payload, length);
Serial.print(" == ");
cheerColour = strip.Color(payload[0], payload[1], payload[2]);
Serial.println(cheerColour);
strip.fill(cheerColour);
strip.show();
Serial.println();
}
void setup() {
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
strip.setBrightness(BRIGHTNESS);
pinMode(HEARTBEAT_PIN, OUTPUT);
Serial.begin(115200);
Serial.println("starting....");
Serial.setTimeout(500);// Set time out for
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
reconnect();
Serial.begin(115200);
//Serial.println("Configuring WDT...");
esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
esp_task_wdt_add(NULL); //add current thread to WDT watch
}
int last = millis();
void loop() {
client.loop();
loopCount += 1;
if (loopCount == 20000) {
digitalWrite(HEARTBEAT_PIN, HIGH); // turn the LED on (HIGH is the voltage level)
}
if (loopCount == 40000) {
digitalWrite(HEARTBEAT_PIN, LOW); // turn the LED off by making the voltage LOW
loopCount = 0;
}
// resetting WDT every 5s
if (millis() - last >= 5000) { // && i < 3) {
//Serial.println("Resetting WDT...");
esp_task_wdt_reset();
last = millis();
}
}
The code will work on an ESP8266 device as well if you comment/uncomment the marked lines
1 Response
[…] Turn an ESP32-C3FH4-RGB board into a Cheerlight using Arduino IDE […]