WS2812B LED Not Working as Expected with ESP8266

Hey all,

I'm using a this ESP8266 with one single WS2812B IC. It's a status light.

The code I'm writing fetches stock data from the internet and activates some motors based on if the value it came up with was positive or negative. All the code to that end works fine. I tried to add this one LED and it's behaving contrarily to what I expect.

I'm wondering if it could be because my code uses the Serial monitor, but I'm also using the RX pin as an IO?

The LED stays off upon booting, until I press a button. The LED does turn blue as expected when the button is pressed (as it should), but it is not turning green/red afterwards, which I have programmed it to do.

My code in full:


#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <Stepper.h>
  // Library used for parsing Json from the API responses
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.h>



//------- Replace the following! ------
char ssid[] = "Mahasamutr";       // your network SSID (name)
char password[] = "5125076838";  // your network key

  // Defines the number of steps per rotation
const int stepsPerRevolution = 2038;

  // Creates an instance of stepper class
  // Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
Stepper green = Stepper(stepsPerRevolution, 5, 0, 4, 2);
Stepper red = Stepper(stepsPerRevolution, 14, 13, 12, 15);

  // This pin should have a button that raises HIGH when pressed.
int button = 16;
int LEDPIN = 3;
int LEDNUM =1;


  // Just the base of the URL you want to connect to
#define TEST_HOST "www.alphavantage.co"

  // The fingerprint of the site you want to connect to.
  // The fingerprint will change every few months.
  // You can find this by visiting the host, clicking the lock icon in Google Chrome that appears 
  // to the left of the URL, and looking for SHA-1 Fingerprint.
#define TEST_HOST_FINGERPRINT "27 F4 DF 78 11 04 1A DB 4B EC 5A 4C D5 0A FE 1F D6 24 CE BF"

  // The number of basis points' movement that will constitute one M&M's dispensing
int bps_per_turn = 10;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDNUM, LEDPIN, NEO_GRB + NEO_KHZ800);

// For HTTPS requests
WiFiClientSecure client;

void setup() {
  strip.setBrightness(255);
  red.setSpeed(16);
  green.setSpeed(16);
  strip.begin();
  strip.show();

  Serial.begin(115200);

  // Connect to the WiFI
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  // Attempt to connect to Wifi network:
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);

  //--------

  // If you don't need to check the fingerprint
  // client.setInsecure();

  // If you want to check the fingerprint
  client.setFingerprint(TEST_HOST_FINGERPRINT);

//  makeHTTPRequest();
}

int makeHTTPRequest() {

  Serial.println("MakeHTTPRequest");
  // Opening connection to server (Use 80 as port if HTTP)
  if (!client.connect(TEST_HOST, 443))
  {
    Serial.println(F("Connection failed"));
    return 0;
  }

  // give the esp a breather
  yield();

  // Send HTTP request
  client.print(F("GET "));
  // This is the second half of a request (everything that comes after the base URL)
  client.print("/query?function=GLOBAL_QUOTE&symbol=SPY&apikey=XNLW93WXMK02TFOI"); // %2C == ,
  client.println(F(" HTTP/1.1"));

  //Headers
  client.print(F("Host: "));
  client.println(TEST_HOST);

  client.println(F("Cache-Control: no-cache"));

  if (client.println() == 0)
  {
    Serial.println(F("Failed to send request"));
    return 0;
  }
  //delay(100);
  // Check HTTP status
  char status[32] = {0};
  client.readBytesUntil('\r', status, sizeof(status));
  if (strcmp(status, "HTTP/1.1 200 OK") != 0)
  {
    Serial.print(F("Unexpected response: "));
    Serial.println(status);
    return 0;
  }

  // Skip HTTP headers
  char endOfHeaders[] = "\r\n\r\n";
  if (!client.find(endOfHeaders))
  {
    Serial.println(F("Invalid response"));
    return 0;
  }

  // This is probably not needed for most, but I had issues
  // with the Tindie api where sometimes there were random
  // characters coming back before the body of the response.
  // This will cause no hard to leave it in
  // peek() will look at the character, but not take it off the queue
  while (client.available() && client.peek() != '{')
  {
    char c = 0;
    client.readBytes(&c, 1);
    Serial.print(c);
    Serial.println("BAD");
  }

    // While the client is still availble read each
    // byte and print to the serial monitor
    // This is kind of unnecessary but I added the for loop
    // to limit API calls that return huge amounts of data
    String peppapig = "";
    for (int i=0; i<600; i++){
      if (client.available()) {
        char c = 0;
        client.readBytes(&c, 1);
        Serial.print(c);
        peppapig+=c;
        }
    }

    // We now have a String called peppapig, which contains the first 
    // 600 characters that were returned from our API call. 
    // We now throw peppapig into a JSON document so we can index it.
    Serial.println(peppapig);
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, peppapig);
    JsonObject obj = doc.as<JsonObject>();

    // Indexing the results from our call
    // Results are returned as String, so we convert it to a float, multiply it by 10
    // to get the number of necessary turns, and then force it to an int. 
    String pchange = obj["Global Quote"]["10. change percent"].as<String>();
    Serial.println(pchange);
    pchange = pchange.substring(0, 4);
    Serial.println(pchange);
    float float_pchange = pchange.toFloat();
    Serial.println(float_pchange);
    int turns = float_pchange*(100/bps_per_turn);
    Serial.println(turns);
    return turns;
    
   
}



void loop() {
  // put your main code here, to run repeatedly:

  
  // If the button is pressed
  if (digitalRead(button) == HIGH){
    strip.setPixelColor(0,strip.Color(0, 0, 255));
    Serial.println("Mom, I'm turning!");
    setup();
    int number_of_turns = makeHTTPRequest();
    if (number_of_turns < 0){
      strip.setPixelColor(0,strip.Color(255, 0, 0));
      strip.show();
    }
    if (number_of_turns > 0){
      strip.setPixelColor(0,strip.Color(0, 255, 0));
      strip.show();
    }
    delay(50);
    for (int i=0; i<=abs(number_of_turns); i++){
      if (number_of_turns < 0){
        strip.setPixelColor(0,strip.Color(255, 0, 0));
        strip.show();
        red.step(stepsPerRevolution*0.4);
      }
      else if (number_of_turns > 0){
        strip.setPixelColor(0,strip.Color(0, 255, 0));
        strip.show();
        green.step(stepsPerRevolution*0.4);
      }
      delay(50);
    }
  }

  digitalWrite(14, LOW);
  digitalWrite(13, LOW);
  digitalWrite(12, LOW);
  digitalWrite(15, LOW);
  digitalWrite(5, LOW);
  digitalWrite(0, LOW);
  digitalWrite(4, LOW);
  digitalWrite(2, LOW);
  strip.setPixelColor(0, strip.Color(0,0,0));
  strip.show();
}

Specifically, the issue is occuring in the loop function. I've seen it happen on occasion that it will flash green/red for a fraction of a second, which makes me think the issue is something simple.

I've added redundant strip.setPixelColor() instructions in effort to alleviate the problem to no avail. Hoping a second set of eyes will find a simple mistake I've overlooked. Thanks in advance.

The code snippet in question:

void loop() {
  // put your main code here, to run repeatedly:

  
  // If the button is pressed
  if (digitalRead(button) == HIGH){
    strip.setPixelColor(0,strip.Color(0, 0, 255));
    Serial.println("Mom, I'm turning!");
    setup();
    int number_of_turns = makeHTTPRequest();
    if (number_of_turns < 0){
      strip.setPixelColor(0,strip.Color(255, 0, 0));
      strip.show();
    }
    if (number_of_turns > 0){
      strip.setPixelColor(0,strip.Color(0, 255, 0));
      strip.show();
    }
    delay(50);
    for (int i=0; i<=abs(number_of_turns); i++){
      if (number_of_turns < 0){
        strip.setPixelColor(0,strip.Color(255, 0, 0));
        strip.show();
        red.step(stepsPerRevolution*0.4);
      }
      else if (number_of_turns > 0){
        strip.setPixelColor(0,strip.Color(0, 255, 0));
        strip.show();
        green.step(stepsPerRevolution*0.4);
      }
      delay(50);
    }
  }

  digitalWrite(14, LOW);
  digitalWrite(13, LOW);
  digitalWrite(12, LOW);
  digitalWrite(15, LOW);
  digitalWrite(5, LOW);
  digitalWrite(0, LOW);
  digitalWrite(4, LOW);
  digitalWrite(2, LOW);
  strip.setPixelColor(0, strip.Color(0,0,0));
  strip.show();
}

Hey guys,

I fixed it by commenting out the Serial.begin(115200); line.

After doing that, everything works as expected.

:slight_smile:

I was about to say, your very first line of your post had your own answer. :slight_smile: Glad you got it working.