ESP8266 + Blynk.virtualWrite = Crash "cause:4, boot mode:(3,6)"

В вашем примере таймер на 2 секунды, что может значительно усложнить поиск ошибки наложения. В моём случае ошибка может возникнуть при 100 быстрых нажатиях на кнопку + также редко, как и при трёх. В 70% случаях варьируется от 10 до 30 нажатий на кнопку “+”.
И! Скорость нажатия на кнопку “+” в моём тесте около 9 нажатий в секунду! :slight_smile:

Мил, человек… Пит на этом форуме один из самых опытных программистов, который отчаянно поддерживает всех пользователей. Да и я сам тоже давно с Blynk-ом, еще с версии 0.1… Послушай совета добрых умных людей. Твоя ошибка в диагностике довольно сложная, а по итогу ты все равно упрешься в возможности железки ESP8266 (судя по тому что ты от неё хочешь). Ты от неё хочешь того, что она не сможет сделать. К сожалению сетевые протоколы довольно требовательны к таймингам и ресурсам ЦП. Почитай ESP32 и ESPЗ8266.

P.S. Думаю решение кроется в ограничении количества вызова BLYNK_WRITE в единицу времени, но это уже к создателям, а они сейчас активно заняты версией 2.0

1 Like

Cause 4 boot(3,6) is caused by the hardware watchdog timer (there are also two software watchdogs). Essentially the hardware watchdog is not being triggered hence a reboot. On a regular basis, the micro-controller must toggle the watchdog, if this is not done the watchdog times out and resets the microcontroller. The ESP8266 software watchdog, which has a time-out period about half as long as that of the ESP8266 hardware watchdog (around 3-4 and 6-8 seconds respectively), feeds the latter. But if generated by a software watchdog the root cause is 2.
Finding the exact cause can be be difficult, the best option is to start by commenting out any any indefinite loops i.e. one that only exits when it receives an input and then commenting out bits of code until the error goes. I the ESP8266 seems to be particularly sensitive when it comes to this error, I have had problems with other communication based libraries

1 Like

Я понимаю что у меня много ошибок, как у любого новичка. Моя ошибка никакого отношения к возможностям железки не имеет, объективности ради.

Пит - человек, на котором возможно держится вся поддержка, я это сразу понял. Единственный кто мне помогал быстро и сразу из всех подобных форумов :slight_smile: Но к чему это высказывание?
Когда упрусь в возможности 8266, перейду на другое железо. А пока, моя задача не такая нагрузка для процессора, чтобы переходить на x32 монстров. “Из пушки по воробьям”– не мой метод. Оптимальное решение я всё равно найду с появлением опыта, вопрос времени. Спасибо за проявленный интерес и попытки помощи пользователям!
P.S. Я почти сразу нашёл в качестве временного решения отправку данных в Blynk последовательно, отдельным циклом. Но это не так комфортно для взаимодействия из приложения из-за задержки. Пока в голове одна мысль, использовать условие + флаг который однократно включает изменение входных данных, отправляемых ежесекундно.

Основные вопросы остались без внимания, это: почему не выполняющееся условие вызывает ошибку? Почему объявленный флаг нужно объявлять повторно?.. Много простых, казалось бы очевидных строк, поведение которых я не могу понять. С этого и началось моё обращение.

My diagnostic problem is that many different factors (strings) influence the occurrence of the error, which have nothing to do with the cause of the error itself.
Such as:
// flag = 0; – Why does a repeated announcement affect the fulfillment of the condition? When it was said earlier: bool flag = 0;
if (flag == 1) - Why does an unfulfilled condition cause an error?
These are the questions I ask again and I see no answer on this matter :frowning:

Thanks for the explanation about the watchdog! :slight_smile:

Blynk uses a publish/subscribe messaging model with the Blynk server being the broker. This has I think been implemented with a minimal set of functionality which makes it less robust, this means that the processing of the messages (Blynk writes) i.e. needs to be completed quickly before other essages are received or sent as there is no automatic retries. I do not know how the Blynk code handles the messages it receives or has to send but I suspect that the problem you are having is a timing one which causes messages not be processed completely before another one is initiated. (Flag == 1). I would suggest that you separate out changing the time with the + and - buttons from reporting back the new value. For example set 'timerChangedflag == true, then testing for this flag in the loop: if set report back the new timer value then set 'timerChangedflag = false.

1 Like

I wanted to implement the fastest possible response in the application when buttons are pressed. I will try the flag experiment on other tasks that may conflict. Thnks :slight_smile:

Упрямство=целеустремленность - это отличное качество :slight_smile: Но в меру!

То что вы пытаетесь найти причину именно в коде
// flag = 0;
проблема не в нем…

Я попробую объяснить…
Проблема в прерываниях! Которые и вызывают у вас наложения исполнения кода, “не пойми где и когда”. Для ESP8266 500мс это вообще критическое время которое вызовет watchdog. ‘Task1’ довольно тяжелый не смотря на всю его простоту написания, из которого вы также не однократно вызываете Blynk.virtualWrite(). Именно из-за наложения прерываний я ставил 2 секунды для Task1. Чтобы дать возмонжость BLYNK отрабатывать свой протокол обмена…

Помните, что у сервера blynk-cloud.com тоже есть задержки на обработку числа запросов в секунду. Что в свою очередь может вызывать задержки ответов, хотя в библиотеке используется методы Async передачи и тротлинг.

Я однозначно убедился, что проблема у вас не в коде, а в подходе решения вашей задачи.
На своем локальном сервере, мне не удалось завесить вот такой код, даже очень частыми вызовами события BLYNK_WRITE() (со сокростью больше 10 раз в секунду):

#define BLYNK_PRINT Serial
#define BLYNK_MSG_LIMIT 10        //Ограничьте количество исходящих команд в секунду.
#define BLYNK_SEND_THROTTLE 50    //Ждать после отправки каждого фрагмента (в миллисекундах).

//#define BLYNK_DEBUG
#include <BlynkSimpleEsp8266.h>
#include <ESP8266WiFi.h>

BlynkTimer timer;

char auth[] = "4dRNg1EPD***************6xbYki4";
char ssid[] = "Oblako";
char pass[] = "*********";
IPAddress device_ip  (192, 168, 0, 33);
IPAddress gateway_ip (192, 168, 0, 1);
IPAddress subnet_mask(255, 255, 255, 0);

#define vPIN_TIMER_SET       V18
#define vPIN_TIMER_OUT       V19
#define vPIN_TIMER_RST_PWR   V20

#define PERIOD 1000

bool flag = 0;
uint16_t timeHour, timeMin, timeSec, timeDay, cHour, cMin, cSec;
uint32_t count_time, countSec, count_p = 66;
String hhmmss, ddhhmmss;

void setup() {
  Serial.begin(115200); delay(25); Serial.println();
  WiFi.config(device_ip, gateway_ip, subnet_mask);
  WiFi.begin(ssid, pass);
  Blynk.config(auth, "192.168.0.50", 8080);
  timer.setInterval(2000, Task1);
}

BLYNK_CONNECTED()
{
  //Blynk.syncAll();
  Blynk.syncVirtual(V18, V19);
}

BLYNK_WRITE(vPIN_TIMER_SET) {
  Serial.print("\n BLYNK_WRITE - start1: "); Serial.println(micros());
  count_p = param.asInt() * 60;
  cHour = count_p / 3600ul;
  cMin = (count_p % 3600ul) / 60ul;
  cSec = count_p % 60ul;
  hhmmss = "";
  Serial.print("\n BLYNK_WRITE - start2: "); Serial.println(micros());
  if (cHour > 0) {
    Serial.print("\n BLYNK_WRITE - start3: "); Serial.println(micros());
    if (cHour > 9) hhmmss = hhmmss + cHour + ':';
    else hhmmss = hhmmss + '0' + cHour + ':';
  }
  if (cMin > 0 || cHour > 0) {
    Serial.print("\n BLYNK_WRITE - start4: "); Serial.println(micros());
    if (cMin > 9) hhmmss = hhmmss + cMin + ':';
    else hhmmss = hhmmss + '0' + cMin + ':';
  }
  if (cSec > 9) hhmmss = hhmmss + cSec; else hhmmss = hhmmss + '0' + cSec;
  Serial.print("\n BLYNK_WRITE - start5: "); Serial.println(micros());
  
  Blynk.virtualWrite(vPIN_TIMER_OUT, hhmmss);
  
  Serial.print("\n BLYNK_WRITE - start6: "); Serial.println(micros());
  Serial.print("\n=Timer: "); Serial.println(hhmmss);
  Serial.print("\n BLYNK_WRITE - end: "); Serial.println(micros());
}

void loop() {
  timer.run();
  Blynk.run();
}

void Task1() {
  Serial.print("\n Task1() - start: "); Serial.println(micros());
  count_time += PERIOD;
  countSec = count_time / 1000;
  timeDay = (countSec / 3600ul) / 24ul;
  timeHour = (countSec / 3600ul) % 24;
  timeMin = (countSec % 3600ul) / 60ul;
  timeSec = countSec % 60ul;
  ddhhmmss = "";
  if (timeDay > 0) ddhhmmss = ddhhmmss + timeDay + "d ";
  if (timeHour > 0 || timeDay > 0) {
    if (timeHour > 9) ddhhmmss = ddhhmmss + timeHour + ':'; else ddhhmmss = ddhhmmss + '0' + timeHour + ':';
  }
  if (timeMin > 0 || timeHour > 0 || timeDay > 0) {
    if (timeMin > 9) ddhhmmss = ddhhmmss + timeMin + ':'; else ddhhmmss = ddhhmmss + '0' + timeMin + ':';
  }
  if (timeSec > 9) ddhhmmss = ddhhmmss + timeSec; else ddhhmmss = ddhhmmss + '0' + timeSec;
  Blynk.virtualWrite(vPIN_TIMER_RST_PWR, ddhhmmss);
  Serial.print("\nTime: "); Serial.print(ddhhmmss);
  bool  flag = 0; // Removes the error why???
  if (flag == 1) { // Conditions are simplified for example, should be triggered under several conditions by &&
    cHour = count_p / 3600ul;
    cMin = (count_p % 3600ul) / 60ul;
    cSec = count_p % 60ul;
    hhmmss = "";
    if (cHour > 0) {
      if (cHour > 9) hhmmss = hhmmss + cHour + ':';
      else hhmmss = hhmmss + '0' + cHour + ':';
    }
    if (cMin > 0 || cHour > 0) {
      if (cMin > 9) hhmmss = hhmmss + cMin + ':';
      else hhmmss = hhmmss + '0' + cMin + ':';
    }
    if (cSec > 9) hhmmss = hhmmss + cSec; else hhmmss = hhmmss + '0' + cSec;
    Blynk.virtualWrite(vPIN_TIMER_OUT, hhmmss);
    Serial.print("\nCountdown: "); Serial.println(hhmmss);
  }
  if (flag == 1) {
    Serial.println("\n Cond.3: Alert");
    Blynk.notify("{DEVICE_NAME}: Alarm!");
  }
  Serial.print("\n Task1() - end: "); Serial.println(micros());
}

Для этого я добавил элемент слайдер на V18 с отключенной опцией SEND ON RELEASE (отправить последнее). А также включил две опции см. 2 и 3 строки. Вообще много интересного можно найти в файле BlynkConfig.h . ВНИМАНИЕ! Только не правте в BlynkConfig.h опредления, а вносите лучше сразу в свой код. Можете поиграться параметрами задережек и выбрать для себя мимнимально достаточное, что бы ваш код работал стабильно.

P.S.
Если вы действительно настроены разобраться и понять причины BSOD/wrp, начните изучать SDK для ESP.

1 Like