Serial and WiFi LED Strip Unreliability

tjohnson
Posts: 3
Joined: Sun Aug 20, 2017 5:08 pm

Serial and WiFi LED Strip Unreliability

Postby tjohnson » Sun Aug 20, 2017 5:38 pm

Hello All,

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();
}
Now the code below will work perfectly. The Serial commands are commented out, but if those are enabled I get random LEDs acting funky again. Also, if you add in just the WiFi connection line it will act strange.

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.


  }

}

Any thoughts or direction would be greatly appreciated!

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Serial and WiFi LED Strip Unreliability

Postby ESP_Sprite » Mon Aug 21, 2017 12:34 am

The Adafruit lib seems to bitbang the LEDs using busy-wait loops, which is incredibly fragile, as you have seen. The ESP32 has a bunch of peripherals (SPI, RMT, I2S) that are way better suited to the task, and there are libraries (like this one) that uses those to get a better result. Maybe you can change over to one of those?

tjohnson
Posts: 3
Joined: Sun Aug 20, 2017 5:08 pm

Re: Serial and WiFi LED Strip Unreliability

Postby tjohnson » Mon Aug 21, 2017 2:23 pm

Thanks ESP_Sprite for the lead. I've tried the library you've linked, but the LED strip doesn't appear to respond at all. No lights or flicker, nothing. I do not get any kind of compile errors and receive a successful "Init Complete" message. Also, I added a Serial.print to fire within one of the demo functions to make sure they're firing, which they are. Not sure if there is something special I need to do with this library, but I've set my data pin and number of LEDs and tried the various types of LED strips within the

Code: Select all

ws2812_init(DATA_PIN, LED_WS2812B)
call.

I've also tried the FastLED library as it now claims support for ESP32. So far, I can get the library to work as long as I only target LEDs in position 0-9. If I try to use a group larger then that it crashes and causes a reboot. Usually an error of " Error of type StoreProhibited occurred on core". I've also seen "ESP32/ESP32/esp-idf-public/components/freertos/./tasks.c:1400 (vTaskDelay)- assert failed!"

No sure what would cause that. My demo code is below. I've also tried a few of the different LED strip types, but I get the same result. If my NUM_LEDS is changed from 9 to anything higher, it will crash.

Code: Select all

#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 9

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 22
#define CLOCK_PIN 13
#define BRIGHTNESS  32
// Define the array of leds
CRGB leds[NUM_LEDS];

void setup() { 
      // Uncomment/edit one of the following lines for your leds arrangement.
      // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
       //FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);
      // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
       FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  	  //FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
      // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);
      
      // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS);

      // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);

      FastLED.setBrightness(  BRIGHTNESS );
}

void loop() { 
  // Turn the LED on, then pause
  for(int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB::Red;
    FastLED.show();
    delay(500);
     leds[i] = CRGB::Black;
     FastLED.show();
  }
}

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Serial and WiFi LED Strip Unreliability

Postby ESP_Sprite » Tue Aug 22, 2017 1:01 am

Sorry, no idea, I personally don't use Arduino. Your code doesn't have any obvious flaws; if no one responds here, you may want to try filing a bug against the FastLED repo.

tjohnson
Posts: 3
Joined: Sun Aug 20, 2017 5:08 pm

Re: Serial and WiFi LED Strip Unreliability

Postby tjohnson » Sun Oct 15, 2017 6:04 pm

Not to resurrect an old thread for no reason, but to help anyone looking here for an answer to the issues I experienced above: I re-tried the MartyMacGyver ESP32-Digital-RGB-LED-Drivers library again after it received some new updates to the repo and it is working perfectly. Everything operates as it should without any kind of inconsistencies.

webecncn
Posts: 1
Joined: Wed May 31, 2017 3:33 am

Re: Serial and WiFi LED Strip Unreliability

Postby webecncn » Tue Feb 20, 2018 4:11 pm

Current FastLED 3.1.6 uses esp32 rmt and seems to work well.

Who is online

Users browsing this forum: Baidu [Spider] and 57 guests