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:
The config file is saved and read as expected, and the code runs without any failure.
when the
for
loop containsDOC["gen_pubTopic"].size()
topics are read as expected, but when it is defined asDOC["gen_pubTopic"].size() |3
it crashes.x
,x2
, andx3
are defined before eachfor
loop. Again, once as defined in 2), still no change.At some part it happened at the 3rd
for
loop, and sometimes at the 2ndfor
loop.Printing
xi
values shows the expected values.To make it clear - without using "fallback annotation"
|2
the code runs without crashing.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.
1 Answer 1
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;
-
I prefer explicit conditions instead of hidden C features:
if (x == 0) // ...
;-) It does not irritate the casual reader of the source and shows the intention much better.the busybee– the busybee2024年01月23日 09:12:23 +00:00Commented Jan 23, 2024 at 9:12 -
I wish to make sure that using
iot.add_pubTopic(DOC["pubTopic"][i] | t3[i]);
is correct (usingt3[i]
as "fallback")guyd– guyd2024年01月23日 09:59:44 +00:00Commented Jan 23, 2024 at 9:59 -
Nope, I think not. It looks as if the argument to
add_pubTopic
is still aunsigned long
, for which|
means 'bitwise or'. This probably should not even compile, becauset3[i]
is a string.John– John2024年01月23日 19:48:33 +00:00Commented Jan 23, 2024 at 19:48
| 3
to do.|3
is set as a value in case config file does not exist| value
actually means. Please edit your question and describe what you think it does in detail.