Set LED colours based on specific text on webpage - getting various errors

Hi all,

I'm working on a project using a Wemos D1 mini with 4 LEDs in series. The aim is to get it to read text from a web page which only has text on stating 1, 2 or 3 colours, and then replicate those colours across the LEDs. The webpage is created using NodeRed to extract information from a website. I've got code from a similar project which I'm using, but I think some of it may be outdated based on old ArduinoJSON. When I try and upload the code to the Arduino I get the following errors:

`Arduino: 1.8.16 (Windows Store 1.8.51.0) (Windows 10), Board: "LOLIN(WEMOS) D1 R2 & mini, 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, 4MB (FS:2MB OTA:~1019KB), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

C:\Users\M\Desktop\Bindicator.ino: In function 'void loop()':

Bindicator:74:38: error: 'class ArduinoJson6185_91::StaticJsonDocument<300>' has no member named 'parseArray'

74 | JsonArray& parsed = JSONBuffer.parseArray(parseMe);

  |                                      ^~~~~~~~~~

Bindicator:77:19: error: 'ArduinoJson::JsonArray' {aka 'class ArduinoJson6185_91::ArrayRef'} has no member named 'success'

77 | if (!parsed.success()) {

  |                   ^~~~~~~

Bindicator:91:19: error: 'class ArduinoJson6185_91::ElementProxy<ArduinoJson6185_91::ArrayRef>' has no member named 'printTo'

91 | parsed[i].printTo((char*)jsonChar, parsed.measureLength() + 1);

  |                   ^~~~~~~

Bindicator:91:51: error: 'ArduinoJson::JsonArray' {aka 'class ArduinoJson6185_91::ArrayRef'} has no member named 'measureLength'

91 | parsed[i].printTo((char*)jsonChar, parsed.measureLength() + 1);

  |                                                   ^~~~~~~~~~~~~

exit status 1

'class ArduinoJson6185_91::StaticJsonDocument<300>' has no member named 'parseArray'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
`

The code I'm using in IDE is:

 
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <Adafruit_NeoPixel.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
 
// Change to suit your number of pixels and output pin on the ESP8266
#define PIN D3
#define NUMPIXELS 4
 
// Change to add in your WiFi SSID, Password & NODE_RED Server IP
const char* NODE_RED_HOST_IP = "http://XXX.XXX.X.XX:1880/endpoint/mybin";
const char* ssid = "XXXXXX";
const char* password = "XXXXXXXX";
 
// Adafruit NeoPixel initilisation string
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
 
// Define some standard colours for easier reference later
const uint32_t redPixel = pixels.Color(255, 0, 0);
const uint32_t greenPixel = pixels.Color(0, 255, 0);
const uint32_t bluePixel = pixels.Color(0, 0, 255);
const uint32_t whitePixel = pixels.Color(255, 255, 255);
const uint32_t unlitPixel = pixels.Color(0, 0, 0);
const uint32_t dimWhitePixel = pixels.Color(255, 255, 255);
 
 
void setup() {
  // Boot up ESP8266, setup serial comms and try to connect to wifi
  Serial.begin(115200);
  Serial.println("Booting Up");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection to WiFi Failed! Retrying...");
    delay(5000);
  }
 
  // Set LED colour to dim white when booted and connected to your wifi with a valid IP, print the IP to serial
  Serial.print("IP Address:");
  Serial.println(WiFi.localIP());
  pixels.begin();
  pixels.setPixelColor(0, dimWhitePixel);
  pixels.show();
}
 
void loop() {
  // Connect to the NODE_RED server and pull a result, show red LED if this fails
  HTTPClient http;
  const int httpPort = 1880;
  // Connect to the NODE_RED bins webpage, change to suit your IP and Bins webpage address
  if (! http.begin("http://XXX.XXX.X.XX:1880/endpoint/mybin"  )) {
    Serial.println("Connection Failed To " + String(NODE_RED_HOST_IP));
    // If we cant connect, show 1 pixel red to indicate an error
    pixels.setPixelColor(0, redPixel);
  } else {
    // If we can connect to NODE_RED, start a pull of data from NODE_RED server
    Serial.print("Doing Get: ");
    int httpCode = http.GET();
    
    Serial.printf("[HTTP] GET... code: %d\n", httpCode);
 
    // Check we're getting a HTTP Code 200
    if (httpCode = HTTP_CODE_OK) {
      String parseMe = http.getString();
      //Create a memory buffer to store the JSON data
      StaticJsonDocument<300> JSONBuffer;
      JsonArray& parsed = JSONBuffer.parseArray(parseMe);
      
      // If we can connect to NODE_RED, but dont understand the returned data, set 1 pixel to red and output to serial
      if (!parsed.success()) {
        Serial.println("Parsing JSON Failed");
        pixels.setPixelColor(0, redPixel);
        pixels.show();
        delay(5000);
        return;
      }
    
      int arraySize = parsed.size();
      int pixelIndex = 0;
 
      static uint32_t lastColour = unlitPixel;
      for (int i = 0; i < arraySize; i++) {
        char jsonChar[10];
        parsed[i].printTo((char*)jsonChar, parsed.measureLength() + 1);
 
        // Parse retreived data and check for for matching colours. If webpage says Green, show Green LED, if Red, show Red, etc
        if (strcmp(jsonChar, "green") == 0 ) {
          pixels.setPixelColor(pixelIndex, greenPixel);
          lastColour = greenPixel;
          Serial.println("Set To Green");
        }
        if (strcmp(jsonChar, "red") == 0 ) {
          pixels.setPixelColor(pixelIndex, redPixel);
          lastColour = redPixel;
          Serial.println("Set To Red");
        }
        if (strcmp(jsonChar, "blue") == 0 ) {
          pixels.setPixelColor(pixelIndex, bluePixel);
          lastColour = bluePixel;
          Serial.println("Set To Blue");
        }
        if (strcmp(jsonChar, "white") == 0 ) {
          pixels.setPixelColor(pixelIndex, whitePixel);
          lastColour = whitePixel;
          Serial.println("Set To White");
        }
        pixelIndex++;
      }
      // If only one bin value is found, repeat colour so whole bin lights up
      if (arraySize ==1) {
        for (int i = 0; i < NUMPIXELS; i++) {
          pixels.setPixelColor(pixelIndex, lastColour);
        }
      }
      
    }
    // Clean up your HTTP connection to prevent memory leaks or other weird behaviour
    Serial.println();
    Serial.println("Closing Connection");
    http.end();
    pixels.show();
    // This is how often we check the NODE_RED server. Set to something low, like 3000 for testing and perhaps 30000 or 60000 for "Production" use
    delay(3000);
  }
 
}

Can anyone please advise on what needs to be edited to resolve the errors?

Thanks in advance

Welcome,

It looks like this code was made for a previous version of the ArduinoJson library. For example, parseArray has been replaced by deserializeJson.

See this Migrating from version 5 to 6 | ArduinoJson 6

1 Like

You probably meant to write:
if (httpCode == HTTP_CODE_OK) {

Use the ArduinoJson 'Assistant' to write your deserialization code for you:

(You have to give it an example of the JSON document you are deserializing.)

Note: The ArduinoJSON library can deserialize straight from the HTTP client stream so you don't have to read the JSON document into memory before deserializing.

1 Like

I think I've resolved the issue now as IDE doesnt return any error messages when uploading, however I do get the following error in serial monitor:

load 0x4010f000, len 3460, room 16 
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4 
tail 4
chksum 0xc9
csum 0xc9
v00047cd0
~ld
Booting Up
IP Address:XXX.XXX.X.XX
Doing Get: [HTTP] GET... code: 200
Parsing JSON Failed

The last line 'Parsing JSON Failed' would indicate it can access the server but isnt reading the information there properly. The server just has the text 'green,blue' (this changes weekly).

Can you advise on how I need to modify my code to read it correctly?

That does not look like a JSON document to me. Shouldn't it start with '{' and end with '}'? Shouldn't it contain key:value pairs?

How would I need to modify my code to avoid the requirement for it to be a JSON document? Or would it be simpler to modify it at the other end to make it a JSON document?

Go back to your original sketch and remove all the JSON stuff. After String parseMe = http.getString();, put some code to look at the contents of the string.

Is the order of the color names important? If not, you could use a series of:

if (parseMw.indexof("red") != -1)...
if (parseMw.indexof("green") != -1)...
if (parseMw.indexof("blue") != -1)...

Hi John,

I believe I'm managed to get the page to read in JSON format as it now comes up with ["Blue"]. I've also changed the JSON library to a previous version so I don't have to worry about changes to the code. However it still gives me errors when trying to parse it. Any thoughts?

Nope.