I'm attempting to use ESP32 in order to create a WiFi MQTT controlled LED Strip. At this point in time, I've successfully got all of the pieces working and can control the light strip via my home automation platform, OpenHAB. However, I'm running into an issue with consistent performance.
The High Level: When ESP32 is connected to WiFi or I use Serial commands, my LED Strip commands doesn't behave consistently. For example, if I send a command to every LED to be off, 1 or 2 might turn on. If I send the exact command again, 1 or 2 different ones may turn on (and the others off). This occurs even when turning LEDs on. If I turn the first 5 on, a couple other ones down the line may turn on.
If I comment out all of my WiFi and Serial and invoke the LED commands manually everything works perfectly.
Is there something special I need to do to prevent this type of behavior?
The Detail:
My Hardware
Espressif ESP32 - https://www.amazon.com/gp/product/B01N0SB08Q/
LED Strip: WS2812B - 16ft 30leds/m - https://www.amazon.com/gp/product/B019HAAVLQ/
Power Supply for LED Strip: https://www.amazon.com/gp/product/B01M0KLECZ/
My Software
Arduino 1.8.3
Adafruit NeoPixel Library
My Code
This is my first project with Arduino, so most of this is just a combination of online tutorials for the various pieces I'm trying to get working. Also, I'm using placeholders for some of the parameters. All my connections and such are working properly.
Code: Select all
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include <ArduinoJson.h>
#include <WiFi.h>
#include <PubSubClient.h>
#define DATA_PIN 12
#define NUM_LEDS 150
//Wifi and MQTT Setup
const char* ssid = "SSID";
const char* password = "PASSWORD";
const char* mqttServer = "HOST";
const int mqttPort = 1883;
const char* mqttUser = "USER";
const char* mqttPassword = "PASSWORD";
WiFiClient espClient;
PubSubClient client(espClient);
//LED Strip setup
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
int delayval = 100;
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
StaticJsonBuffer<300> JSONBuffer; //Memory pool
JsonObject& parsed = JSONBuffer.parseObject(payload); //Parse message
if (!parsed.success()) { //Check for errors in parsing
Serial.println("Parsing failed");
delay(5000);
return;
}
const char* functionType = parsed["function"];
Serial.print("Function Requested: ");
Serial.println(functionType);
if((String)functionType == "single") {
LEDSingle(parsed);
} else if((String)functionType == "zone") {
LEDZone(parsed);
} else if((String)functionType == "total") {
LEDTotal(parsed);
}
}
void setup() {
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
pixels.begin(); // This initializes the NeoPixel library.
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
//Serial.println("Connecting to MQTT...");
if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
//Serial.println("connected");
} else {
//Serial.print("failed with state ");
//Serial.print(client.state());
delay(2000);
}
}
client.subscribe("home/dinning/table/ledstrip");
//client.publish("esp/test", "Hello from RSP32");
}
void loop() {
client.loop();
}
void LEDSingle(JsonObject& parsed) {
int ledTarget = parsed["target"];
int red = parsed["red"];
int green = parsed["green"];
int blue = parsed["blue"];
Serial.print("Single function call to LED: ");
Serial.println(ledTarget);
pixels.setPixelColor(ledTarget, pixels.Color(red,green,blue));
pixels.show();
}
void LEDZone(JsonObject& parsed) {
int ledTargetStart = parsed["targetStart"];
int ledTargetEnd = parsed["targetEnd"];
int red = parsed["red"];
int green = parsed["green"];
int blue = parsed["blue"];
if(ledTargetStart < ledTargetEnd && ledTargetEnd <= (NUM_LEDS-1)) {
for(int i = ledTargetStart; i <= ledTargetEnd; i++) {
pixels.setPixelColor(i, pixels.Color(red,green,blue));
}
pixels.show();
} else {
Serial.println("Invalid values passed to Zone function");
}
}
void LEDTotal(JsonObject& parsed) {
const char* ledTarget = parsed["target"];
if((String)ledTarget == "ON") {
Serial.println("MQTT Request: Total ON");
for(int i = 0; i < NUM_LEDS; i++) {
pixels.setPixelColor(i, pixels.Color(10,10,10));
}
} else {
Serial.println("MQTT Request: Total OFF");
for(int i = 0; i < NUM_LEDS; i++) {
pixels.setPixelColor(i, pixels.Color(0,0,0));
}
}
pixels.show();
}
Code: Select all
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include <ArduinoJson.h>
#include <WiFi.h>
#include <PubSubClient.h>
#define DATA_PIN 12
#define NUM_LEDS 150
//Wifi and MQTT Setup
const char* ssid = "SSID";
const char* password = "PASSWORD";
const char* mqttServer = "HOST";
const int mqttPort = 1883;
const char* mqttUser = "USER";
const char* mqttPassword = "PASSWORD";
WiFiClient espClient;
PubSubClient client(espClient);
//LED Strip setup
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
int delayval = 100;
void setup() {
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
pixels.begin(); // This initializes the NeoPixel library.
//Serial.begin(115200);
//WiFi.begin(ssid, password);
//Serial.println("Connected to the WiFi network");
}
void loop() {
//Serial.println("Starting LEDs Run");
for(int i=0;i<NUM_LEDS;i++){
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(0,50,0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(delayval); // Delay for a period of time (in milliseconds).
pixels.setPixelColor(i, pixels.Color(0,0,0)); // Moderately bright green color.
}
}