2

I'm using an ESP8266, ArduinoJson v6.21.5. PlatformIO, and Vscode.

The config file is saved and read correctly to the ESP8266's flash:

{
    "gen_pubTopic": [
        "DvirHome/Messages",
        "DvirHome/log",
        "DvirHome/debug"
    ],
    "subTopic": [
        "DvirHome/Light/int/KitchenLEDs",
        "DvirHome/All",
        "DvirHome/Light/int",
        "DvirHome/Light"
    ],
    "pubTopic": [
        "DvirHome/Light/int/KitchenLEDs/Avail",
        "DvirHome/Light/int/KitchenLEDs/State"
    ]
}

In case the config file is missing, t[], t2[], and t3[] are hard-coded to avoid boot failure.

There are 3 for loops to read topics (from the config file or from hard-coded).

The unexplained part is:

  1. The config file is saved and read as expected, and the code runs without any failure.

  2. when the for loop contains DOC["gen_pubTopic"].size() topics are read as expected, but when it is defined as DOC["gen_pubTopic"].size() |3 it crashes.

  3. x, x2, and x3 are defined before each for loop. Again, once as defined in 2), still no change.

  4. At some part it happened at the 3rd for loop, and sometimes at the 2nd for loop.

  5. Printing xi values shows the expected values.

  6. To make it clear - without using "fallback annotation" |2 the code runs without crashing.

  7. In all stages above - the fallback stage is not tested (meaning- config file is saved and read), and crashes happens when "fallback annotation" is added.

Appreciate any lead why.

void start_iot2(JsonDocument &DOC)
{

/* Default values / const char t[] = {"DvirHome/Messages", "DvirHome/log", "DvirHome/debug"}; const char t2[] = {"DvirHome/Device", "DvirHome/All"}; const char t3[] = {"DvirHome/Device/Avail", "DvirHome/Device/State"};

uint8_t x = DOC["gen_pubTopic"].size() | 3; for (uint8_t i = 0; i < x; i++) { /* Some Code / / debug code */ Serial.print("Gen_"); Serial.println(i); }

uint8_t x2 = DOC["subTopic"].size() | 2;
for (uint8_t i = 0; i < x2; i++) { /* Some Code / / debug code */ Serial.print("Sub_"); Serial.println(i); }

uint8_t x3 = DOC["pubTopic"].size() | 2; for (uint8_t i = 0; i < x3; i++) { /* Some Code / / debug code */ Serial.print("Pub_"); Serial.println(i); }

iot.start_services(extMQTT); }

Edit_1 Added /*debug Code */ to for loops. At some point, the Serial Monitor showed:

Sub_0
Sub_1
Sub_2
Sub_3
Sub_4
Sub_5

while the size of the SubTopic array is 4 and |2 as default.

ocrdu
  • 1,795
  • 3
  • 12
  • 24
guyd
  • 1,049
  • 2
  • 26
  • 61

1 Answers1

4

The "fallback notation" you're referring to is JsonVariant::operator| and only works for JsonVariant.

In your program, you apply | to an unsigned long, so the built-in bitwise "or" operator applies. It performs a bit-by-bit "or" operation (for example 2 | 4 is 6).

In other words, doc["key"] | 4 behaves as you describe, but not doc.size() | 4.

Unlike many other languages, you cannot use logical "or" (||) either because it returns a boolean. So, if you want to make minimal changes to your code, you'll have to do something like this:

uint8_t x = DOC["gen_pubTopic"].size();
if (!x) x = 3;
Benoit Blanchon
  • 932
  • 4
  • 8