ArduinoJson - необъяснимое поведение '.size()'
Я использую ESP8266, ArduinoJson v6.21.5. PlatformIO и Vscode.
Файл конфигурации сохраняется и корректно считывается во флэш-память ESP8266:
{
"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"
]
}
В случае отсутствия файла конфигурации t[]
, t2[]
и t3[]
жестко запрограммированы во избежание сбой загрузки.
Для чтения тем есть 3 цикла for
(из файла конфигурации или из жестко запрограммированного).
Необъяснимая часть:
Файл конфигурации сохраняется и читается должным образом, а код выполняется без сбоев.
когда цикл
for
содержитDOC["gen_pubTopic"].size()
, темы читаются как положено, но когда они определены какDOC["gen_pubTopic"].size() |3
происходит сбой.x
,x2
иx3
определяются перед каждым цикломfor
. Опять же, как определено в пункте 2), все равно никаких изменений.В какой-то момент это происходило на третьем цикле
for
, а иногда и на втором циклеfor
.Печать значений
xi
показывает ожидаемые значения.Чтобы было понятно: без использования "резервной аннотации"
|2
код выполняется без сбоев.На всех этапах, описанных выше, резервный этап не тестируется (это означает, что файл конфигурации сохраняется и читается), и происходит сбой, когда "резервная аннотация" добавляется.
Цените любую идею.
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);
}
Изменить_1
Добавлен /*код отладки */
в циклы for.
В какой-то момент Serial Monitor показал:
Sub_0
Sub_1
Sub_2
Sub_3
Sub_4
Sub_5
а размер массива SubTopic
по умолчанию равен 4 и |2
.
@Guy . D, 👍2
Обсуждение1 ответ
Лучший ответ:
"Резервное обозначение" вы имеете в виду JsonVariant::operator|
и работает только для < a href="https://arduinojson.org/v6/api/jsonvariant/">JsonVariant
.
В вашей программе вы применяете |
к unsigned long
, поэтому встроенный побитовый оператор "или"; применяется оператор. Он последовательно выполняет операцию «или». операция (например, 2 | 4
— это 6
).
Другими словами, doc["key"] | 4
ведет себя так, как вы описываете, но не doc.size() | 4
.
В отличие от многих других языков, вы не можете использовать логическое «или» (||
) либо потому, что он возвращает логическое значение.
Итак, если вы хотите внести минимальные изменения в свой код, вам придется сделать что-то вроде этого:
uint8_t x = DOC["gen_pubTopic"].size();
if (!x) x = 3;
Я предпочитаю явные условия скрытым функциям C: if (x == 0) // ...
;-) Это не раздражает случайного читателя источника и гораздо лучше показывает намерение., @the busybee
@Бенуа - спасибо за краткий ответ, @Guy . D
Я хочу убедиться, что использование iot.add_pubTopic(DOC["pubTopic"][i] | t3[i]);
корректно (используя t3[i]
как «резервный вариант»), @Guy . D
Нет, я думаю, что нет. Похоже, что аргумент add_pubTopic
по-прежнему является unsigned long
, для которого |
означает "побитовое или". Вероятно, это даже не следует компилировать, потому что t3[i]
— это строка., @John
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- Чтение файла из SPIFFS в nodemcu с использованием ArduinoJson
- Получение всех данных моего объекта JSON из Serial.read() сразу
- Последовательная связь от Arduino до ESP8266 NodeMCU работает, но от NodeMCU до Arduino не работает
- Цикл foreach Arduino JSON
- Проанализировать большой ответ json с помощью ESP8266
- Публиковать данные json в mqtt
- ArduinoJSON v6 – передача буфера как параметра функции
Я не знаю, чего вы ожидали
| 3
сделать., @timemage|3
устанавливается как значение в случае, если файл конфигурации не существует., @Guy . DБоюсь, вы не знаете, что
| значение
на самом деле означает. Пожалуйста, [отредактируйте] свой вопрос и подробно опишите, что, по вашему мнению, он делает., @the busybee*|3 устанавливается как значение в случае, если файл конфигурации не существует* - это не то, что он делает., @Nick Gammon