• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь Зависает MH-Z19.

Cadil

New member
В метеостанции на ESP8266 с датчиком температуры и влажности DHT22, датчиком содержания CO2 MH-Z19 и отправкой данных на Blynk зависают показания MH-Z19, при этом, значения температуры и влажности отправляются на сервер Блинка нормально. После перезагрузки устройства информация с MH-Z19 снова нормально отправляется на Блинк и читается на экране 128*64 какое-то время, затем снова показания с MH-Z19 "замерзают".
Поскольку в скетче наворочено много переменных, библиотек, составил простейший скетч, в котором информация с MH-Z19 выводится только на монитор платформы Arduino IDE (скетч в приложении) .
На 11-ой минуте после загрузки скетча в ESP8266 - wdt reset ( protocol_MH-Z19_02022018.txt). Заметил, что после предварительного сброса ESP до заводских настроек скетч mh-z19_vb4f.ino работает по крайней мере десятки(!) часов.
Загрузил в модуль после форматирования памяти другой простой скетч, в котором данные с датчика отправляются на Blynk:
Код:
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(13, 15); // GPIO15 (TX) and GPIO13 (RX)
char auth[] = "b0bf3e0d02f648c6b7aff07028хххх";

static byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79}; 
byte response[9];
byte crc = 0;
int ppm = 0;
int i = 0;

void readCO2()
{
  while (mySerial.available())mySerial.read();//очистка буфера UART перед запросом
  memset(response, 0, 9);// очистка ответа
  mySerial.write(cmd,9);// запрос
  mySerial.readBytes(response, 9);//чтение 9 байт сенсора
  //расчет  CRC
  crc = 0;
  for (int i = 1; i <= 7; i++)
  {
    crc += response[i];
  }
  crc = ((~crc)+1);
  {
  //проверка CRC
  if ( !(response[0] == 0xFF && response[1] == 0x86 && response[8] == crc) )
  {
    Serial.println("CRC error");
  } else
      {
   
       ppm = (((unsigned int) response[2])<<8) + response[3];
 
        Blynk.virtualWrite(V4, ppm);      //отправка на Blynk 
        Serial.println("CO2: " + String(ppm) + "ppm");
        }
  }
}

void setup()
{
   Serial.begin(9600);
   mySerial.begin(9600); 

Blynk.begin(auth, "ххххххх", "ххххххх", "blynk-cloud.com", 8442);
}

void loop(){
   Blynk.run();
   i++;
   Serial.println("time: " + String(i) + " *10s");
if (i>=60)  i = 0;
   readCO2(); 
   delay(10000);  
}
Данные на Blynk перестали поступать примерно через 2 часа после загрузки (скрин S80204_mh-z19.png).

В чем причина или, хотя бы, как объяснить подобную работу устройства?
 

Вложения

Последнее редактирование:

Cadil

New member
К сожалению, не поможет. Этот декодер у меня уже установлен, но перечня исключений (если такой существует) я не нашел.
Возможно вы прочитаете:
Decoding 27 results
0x40103840: lmacProcessTXStartData at ?? line ?
0x40106c09: sws_isr_13() at D:\Users\VB\Documents\Arduino\libraries\SoftwareSerial/SoftwareSerial.cpp line 131
0x40106cf0: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 116 (discriminator 2)
0x40106d3e: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 125
0x40106cb8: delayMicroseconds at ?? line ?
0x40106d54: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 131
0x40106d3e: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 125
0x40106d3e: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 125
0x40106cb8: delayMicroseconds at ?? line ?
0x402027d5: BlynkApi > >::processCmd(void const*, unsigned int) at D:\Users\VB\Documents\Arduino\libraries\Blynk/BlynkApiArduino.h line 200
0x402027c7: BlynkApi > >::processCmd(void const*, unsigned int) at D:\Users\VB\Documents\Arduino\libraries\Blynk/BlynkApiArduino.h line 199
0x4010564a: spi_flash_write at ?? line ?
0x40107190: timer1_isr_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_timer.c line 34
0x40206561: ppCheckTxIdle at ?? line ?
0x40206a02: DefFreqCalTimerCB at ?? line ?
0x40206aaf: DefFreqCalTimerCB at ?? line ?
0x40218c41: eagle_auth_done at ?? line ?
0x40218c86: eagle_auth_done at ?? line ?
0x402027bf: BlynkParam::iterator::asStr() const at D:\Users\VB\Documents\Arduino\libraries\Blynk/Blynk/BlynkParam.h line 32
: (inlined by) BlynkApi > >::processCmd(void const*, unsigned int) at D:\Users\VB\Documents\Arduino\libraries\Blynk/BlynkApiArduino.h line 198
 

rybeg

New member
Скорее всего не удачно происходит прерывание wi-fi части, а так как uart не аппаратный, датчик залипает.
 

Cadil

New member
Скорее всего не удачно происходит прерывание wi-fi части, а так как uart не аппаратный, датчик залипает.
Спасибо! Как бы вы посоветовали отредактировать скетч в первом посте или скетч из вложения mh-z19_vb4f.ino , чтобы уйти от неудачных прерываний?
 

Cadil

New member
Разнесите отправку на сервер и считывание датчика по времени.
Ваш совет оказался продуктивным. Разнес считывание с датчика и отправку на сервер, подключил датчик непосредственно к UART без библиотеки SoftwareSerial.h и добавил условие поиска старта пакета считывания данных с датчика.
Скетч проработал более суток и я понял, что решение найдено.
Но все попытки перенести это решение в скетч метеостанции оказались неудачными. Метеостанция работает не более 3 часов после форматирования памяти, затем датчик СО2 зависает. Скетч метеостанции не сильно навороченный - использует 35% памяти и глобальные переменные занимают 45% динамической памяти устройства.

Где копать?
 

CodeNameHawk

Moderator
Команда форума
Код:
  mySerial.readBytes(response, 9);//читаем 9 байт ответа сенсора
Попробуйте сделать проверку наличия байта в буфере и только потом его читайте.

У вас, если байт пропал, программа повиснет, сделайте ограничение по времени.
Если н.п. в течении 2 секунд не получили 9 байт, выбрасываете принятые байты и новый запрос к датчику.

Да и другие проверки необходимы, перед отправкой в WiFi проверяйте не отключился ли WiFi.
 
Последнее редактирование:

Cadil

New member
Код:
  mySerial.readBytes(response, 9);//читаем 9 байт ответа сенсора
Попробуйте сделать проверку наличия байта в буфере и только потом его читайте.

У вас, если байт пропал, программа повиснет, сделайте ограничение по времени.
Если н.п. в течении 2 секунд не получили 9 байт, выбрасываете принятые байты и новый запрос к датчику.
Этот подход дублирует заложенные в скетче проверку контрольной суммы и поиск начала пакета только в другом виде.
Хотелось бы сосредоточиться на поиске причины зависания, а не борьбе со следствиями.
 

rybeg

New member
Этот подход дублирует заложенные в скетче проверку контрольной суммы и поиск начала пакета только в другом виде.
Хотелось бы сосредоточиться на поиске причины зависания, а не борьбе со следствиями.
Схема подключения можно посмотреть?
 

enjoynering

Well-known member
Для борьбы с зависанием у вас есть все данные. Вы их постили в начале. Просто вы не хотите разбираться и ждете что кто то сделает это за вас. Вот то чтотвы постили


Decoding 27 results
0x40103840: lmacProcessTXStartData at ?? line ?
0x40106c09: sws_isr_13() at D:\Users\VB\Documents\Arduino\libraries\SoftwareSerial/SoftwareSerial.cpp line 131
0x40106cf0: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 116 (discriminator 2)
0x40106d3e: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 125
0x40106cb8: delayMicroseconds at ?? line ?
0x40106d54: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 131
0x40106d3e: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 125
0x40106d3e: interrupt_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_wiring_digital.c line 125
0x40106cb8: delayMicroseconds at ?? line ?
0x402027d5: BlynkApi > >::processCmd(void const*, unsigned int) at D:\Users\VB\Documents\Arduino\libraries\Blynk/BlynkApiArduino.h line 200
0x402027c7: BlynkApi > >::processCmd(void const*, unsigned int) at D:\Users\VB\Documents\Arduino\libraries\Blynk/BlynkApiArduino.h line 199
0x4010564a: spi_flash_write at ?? line ?
0x40107190: timer1_isr_handler at C:\Users\VB\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0-rc2\cores\esp8266/core_esp8266_timer.c line 34
0x40206561: ppCheckTxIdle at ?? line ?
0x40206a02: DefFreqCalTimerCB at ?? line ?
0x40206aaf: DefFreqCalTimerCB at ?? line ?
0x40218c41: eagle_auth_done at ?? line ?
0x40218c86: eagle_auth_done at ?? line ?
0x402027bf: BlynkParam::iterator::asStr() const at D:\Users\VB\Documents\Arduino\libraries\Blynk/Blynk/BlynkParam.h line 32
: (inlined by) BlynkApi > >::processCmd(void const*, unsigned int) at D:\Users\VB\Documents\Arduino\libraries\Blynk/BlynkApiArduino.h line 198
 

ikari81

New member
Вместо readBytes использовать
while (mySerial.available()) {
measure_response[i++] = (mySerial.read());
}
иначе недочитывает один байт
 
Сверху Снизу