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

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *