Здравствуйте!
Бывает так, что программа зависает (подвисает) или наоборот - строки 22,23 отрабатывают с огромной скоростью.
Похоже, что портится переменная moment. (Скетч1)
Почему она портится - задам вопрос в новой теме, где выложу полный скетч.
Скетч1
bool trigger;
int st;
void setup()
{
pinMode(13, OUTPUT);
Serial.begin(9600);
}
void loop()
{
static uint32_t period = 500;
static uint32_t moment;
if (millis() - moment >= period)
{
moment = moment + period; // благословенная строка
trigger = !trigger;
// далее бывает вот что:
// 1. диод мерцает, вывод в порт с огромной скоростью
// 2. диод светится или погашен, вывода в порт НЕТ
digitalWrite(13, trigger);
Serial.println(st);
}
}
Так вот. Если по какой-то причине программа зависла, то с помощью WatchDog легко организоавать ее перезагрузку. А можно ли организовать перезагрузку следующим образом (Скетч2), если строки 22,23 отрабатывают с огромной скоростью?
Скетч2
#include <avr/wdt.h>
bool trigger;
int st;
unsigned long t1, t2;
bool flag = true; // разрешается wdt_reset()
void setup()
{
pinMode(13, OUTPUT);
Serial.begin(9600);
t1 = millis();
t2 = t1 + 5000;
wdt_enable (WDTO_8S);
}
int timer = 0;
void loop()
{
static uint32_t period = 500;
static uint32_t moment;
if (millis() - moment >= period)
{
moment = moment + period; // благословенная строка
trigger = !trigger;
// далее бывает вот что:
// 1. диод мерцает, вывод в порт с огромной скоростью
// 2. диод светится или погашен, вывода в порт НЕТ
digitalWrite(13, trigger);
Serial.println(st);
// определение времени между соседними проходами
t2 = millis();
if (t2 - t1 < 250) // если это время меньше period, запрет wdt_reset()
{
flag = false;
}
else
{
t1 = millis(); // все нормально
}
if (flag)
{
wdt_reset();
}
}
}
If the transmit buffer is full then Serial.write() will block until there is enough space in the buffer.
Легко можно представить себе как именно приведенная в первопосте программа поведет себя так как описано если сперва забьёт буфер серийного порта и замрёт на Serial.println, а когда связь возобновится начнёт “частить” догоняя миллисы в каждой итерации в ускоренном темпе.
В таких вещах дьяволы в деталях любят прятаться.
Похоже, что МММ прав. millis() портится скорре всего из-за того, что эта схема собрана на макетной плате с использованием проводов, у некоторых папа тонкий и мама широкая.
В течение 3-4-х часов на Master не общается с ESP, не общается со Slave.
И начинает вести себя так, что millis() прыгает в соторону переполнения, тогда moment=moment+period; пытается его догнать, и вывод в порт с огромной скоростью. Либо наоборот: millis() прыгает в соторону нуля. В этом случае программа под это условие не заходит. Спасает только WatchDog.
Когда в глобальных было: unsigned long moment; была такая же поблема.
Затем в глобальных я сделал так: static uint32_t moment;, сказали, что такт НЕЛЬЗЯ. Что это надо писать в loop().
3-4 часа работает без общения с ESP, без общения со Slave. И потом начинается. Что за это время может испортится - не знаю. Говорят, что радиоэлектроника - наука о контактах. Все-таки, наука о “соплях”.