И снова о millis()

Меня пугает работа со строками. Как-то давно я в своем скетче я что-то натворил и он у меня работал некорректно. Портились переменные. Проблема была со String. Ошибку нашел, но забыл - в чем причина была.

Прием коньяка перед работой снимает тревожность.

1 лайк

Иде ты тут две изменяющиеся переменные нашел, я не пойму?..

  if (millis() - moment >= period)
  {
    moment = moment + period;
   //....
  }

Даже дополнять ничем не надо, достаточно чуть переставить операторы

Нету тут бомбы. Переполнение отработает верно.

2 лайка

moment и millis().

Есть два приёма:

if (millis() - moment >= period)
  {
    moment = millis();
   //....
  }

и

if (millis() >= moment )
  {
    moment = moment + period;
   //....
  }

У ТС же винегрет.

Эммм, вот тоже не ожидал )))

Что произойдет после переполнения millis(), когда она на два месяца станет меньше moment?

На самом деле это тоже рабочий вариант, используется, когда нужно не допустить накопления погрешности

Я хз - не пользуюсь этим способом и не рефлексирую.

Вряд ли он будет мигать.

:slight_smile:
Теперь осталось спросить какой вариант лучше и понеслось…

Всё там нормально. Будет мигать как надо.) Никакого переполнения!
И блинк этот можно сократить.)

const uint16_t period = 500;

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  for (static uint16_t moment; (uint16_t)millis() - moment >= period; moment += period)
    digitalWrite(13, !digitalRead(13));
}

Точно?

Оххх … как писал поэт: “мы – волчата сосали волчицу и всосали …

Там столько граблей разбросано :frowning:

Как по мне, ошибка постепенно накопится , но очень медленно.
Для проверки, запустите скетч на недельку - другую))
Можно лог в ЕЕPROM сделать, потом прочитать.

Спойлер
const int period = 500;
bool trigger;
unsigned long moment;
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, 0);
}
void loop()
{
  static uint32_t checkMicros = 0;
  static uint32_t perMicros = 0;
 
  if (millis() - moment >= period)
  {
    perMicros = micros() - checkMicros;
    checkMicros = micros();
    moment = moment + period;
    trigger = !trigger;
    digitalWrite(13, trigger);
    Serial.print("period = ");
    Serial.print(perMicros);
    Serial.print("   deviation = ");
    if(perMicros >= period * 1000UL)
    Serial.println(perMicros - period * 1000UL);
    else
    Serial.println(period * 1000UL - perMicros);
    
  }

}
Спойлер

И чем это будет отличаться от блинка с делеем?

Нет.
Так сделано специально.

unsigne long = 500;
bool trigger;
unsigned long moment;
void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, 0);
}
void loop()
{
  if (millis() - moment >= period)
  {
    moment = moment + period;
    trigger = !trigger;
    digitalWrite(13, trigger);
    if (trigger)
    {
    // после этой строки будет много команд !!!
    }
  }
}

После строки 18 еще какое-то количество команд.
Мне надо, чтобы за один час МАШИННОГО условие строка 16 выполнилось как можно ближе к 3600 раз.

Проверил на УНО - работает. Но сам так писать не буду никогда.

А чем оно от реального отличается? В технике машинное время - это суммарное время наработки двигателя, т.е. считается только время, когда двигатель запущен. А здесь какой смысл у термина?

Видимо секунды с точки зрения МК.

Это не сработает. :wink: точка с запятой из дефайна даст вторую в if и закроет его.
Не надо так писать.