1

I'm trying to send a JSON to a ESP32 and set the value to a variable, for the first 3 variables it works fine, but for some reason it skips the last one. Right now it's sent in an array, but when it's not in an array and I make it a JSONObject instead of a JSONArray it even skips the last 2 values.

When trying a hardcoded JSON it works fine though.

Here is the code:

#include <Arduino.h>
#include <EEPROM.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <NeoPixelBus.h>
#include <AsyncJson.h>
#include <ArduinoJson.h>

#define EEPROM_SIZE 512

const int powerStateAddress = 0;
const int groupNumberAddress = 2;

const uint16_t pixelCount = 82;
const uint pixelPin = 17;
const uint relayPin = 26;

const char* ssid = "";
const char* password = "";
AsyncWebServer server(80);
const size_t jsonCapacity = JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + 70;

int powerState;
int groupNumber;
int colorSaturation = 255;
int greenValue;
int redValue;
int blueValue;
int whiteValue;

NeoPixelBus<NeoGrbwFeature, NeoEsp32I2s1800KbpsMethod> strip(pixelCount, pixelPin);
RgbwColor green(colorSaturation, 0, 0, 0);
RgbwColor red(0, colorSaturation, 0, 0);
RgbwColor blue(0, 0, colorSaturation, 0);
RgbwColor white(0, 0, 0, colorSaturation);
RgbwColor black(0);

void setGroupNumber(DynamicJsonDocument json) {
  groupNumber = json["groupNumber"];
  EEPROM.write(groupNumberAddress, groupNumber);
  EEPROM.commit();
}

void setColor() {
  for(uint16_t pixel = 0; pixel < pixelCount; pixel++) {
    strip.SetPixelColor(pixel, RgbwColor(greenValue, redValue, blueValue, whiteValue));
  }
}

void setColorValues(DynamicJsonDocument json) {
  JsonArray colorValues = json["colorValues"];

  if(greenValue != colorValues[0]) {
    greenValue = colorValues[0];
  }
  if(redValue != colorValues[1]) {
    redValue = colorValues[1];
  }
  if(blueValue != colorValues[2]) {
    blueValue = colorValues[2];
  }
  if(whiteValue != colorValues[3]) {
    whiteValue = colorValues[3];
  }

  setColor();
}

void setBrightness(DynamicJsonDocument json) {
  colorSaturation = json["brightness"];
  setColor();
}

DynamicJsonDocument parseData(AsyncWebServerRequest *request, uint8_t *data, String endpoint) {
  DynamicJsonDocument doc(jsonCapacity);
  DeserializationError err = deserializeJson(doc, data);

  Serial.println(serializeJson(doc, Serial));
  if(err) {
    request->send(400, "text/plain", "err on" + endpoint);
  } else {
    request->send(200, "application/json", "{'msg': 'OK'}");
  }

  return doc;
}

void setup() {
  Serial.begin(115200);
  while(!Serial) {}

  EEPROM.begin(EEPROM_SIZE);

  if(EEPROM.read(powerStateAddress) == LOW || EEPROM.read(powerStateAddress) == HIGH) {
    powerState = EEPROM.read(powerStateAddress);

    if(powerState == HIGH) {
      digitalWrite(relayPin, HIGH);
    }
  } else {
    powerState = LOW;
    EEPROM.write(powerStateAddress, powerState);
    EEPROM.commit();
  }
  if(EEPROM.read(groupNumberAddress) != 255) {
    groupNumber = EEPROM.read(groupNumberAddress);
  }

  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(250);
  }

  Serial.println(WiFi.localIP());

  server.on("/controller/setGroup", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, 
  [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
      DynamicJsonDocument doc = parseData(request, data, "/setGroup");
      setGroupNumber(doc);
  });

  server.on("/controller/setColor", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, 
  [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
    DynamicJsonDocument doc = parseData(request, data, "/setColor");
    setColorValues(doc);
  });

  server.begin();
}

void loop() {
  Serial.println(powerState);
  Serial.println(EEPROM.read(powerStateAddress));
  Serial.println(groupNumber);
  Serial.println(EEPROM.read(groupNumberAddress));
  Serial.print("Brightness: ");
  Serial.println(colorSaturation);
  Serial.print("green: ");
  Serial.println(greenValue);
  Serial.print("red: ");
  Serial.println(redValue);
  Serial.print("blue: ");
  Serial.println(blueValue);
  Serial.print("white: ");
  Serial.println(whiteValue);
  Serial.println("---------");
  delay(2000);
}

Here is the JSON that I send:

    "colorValues": [
        255,
        255,
        255,
        255
        ]
}

This is what the ESP32 receives:

{"colorValues":[255,255,255,255]}33

And this is the result:

green: 255
red: 255
blue: 255
white: 0
JobKlimop
  • 21
  • 1
  • 7
  • You declare the `jsonCapacity` capacity as `JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + 70;`. but in your actual there is at least one json array in it as your shown as `colorValues`, so are you sure you had sufficient and correct memory allocation for `jsonCapcity`? What is exactly the json object looks like? – hcheung Feb 28 '20 at 13:33
  • Depending on the endpoint the JSON can be a little larger or smaller, but for this endpoint `{ "colorValues": [ 255, 255, 255, 255 ] }` is actually it. – JobKlimop Feb 28 '20 at 13:47
  • You didn't answer my question, my question is `are you sure there is sufficient allocation for the json object`. Based on your code, you will need capacity of `JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(3) + 50;` or 162. If you plug in this value, your problem will go away. If you are not sure how much you need, just use a slightly bigger value and `StaticJsonDocument<200> doc`. – hcheung Feb 28 '20 at 15:15
  • In summary, what you experienced is short of memory allocation for the json doc. – hcheung Feb 28 '20 at 15:18
  • Sorry for the previous wrong reaction. Though, assigning `JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(3) + 50;` did not help. Nor did `StaticJsonDocument<200> doc`. I do see and understand my earlier mistake of not using `JSON_ARRAY_SIZE(4)` now though, so thanks for that. I'm still not sure why the last value still won't be assigned though, since the assigned size should be large enough. ArduinoJson Assistant even suggests `JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1)`. – JobKlimop Feb 28 '20 at 19:11

2 Answers2

0

Okay here is an example of my JavasScript code when I ran into the issue
var colors = {"red":255, "green":255, "blue":255};
is just added the coma to the back like so
var colors = {"red":255, "green":255, "blue":255,};

and now my arduino can find the blue I intend to use

-1

I ran into the same issue and weird enough if you add an element to the object like the 115:

        111,
        112,
        113,
        114,
        115
        ]
}

Then it gets the last 114 and still doesn't get the 115 but atleast you can use you 4 elements, I am guessing it is somethint to do with the last elmenet doesn't have a comma