И снова о millis()

Если есть такая возможность - то посмотрите раезультат работы двух вариантов в мониторе. Желательно с секундомером.

Первый вариант. Строку 18 не трогаем. Оставляем ее такой:

moment13 = moment13+period13;

Второй вариант. В строке 18, вместо того, что там есть, написать так:

moment13 = millis();

Сейчас такой возможности нет

В первом варианте в порт с частотой 1 секунда выходит:
1 2 3 4 5 6 7 8 9 10
затем задержка на 3 секунды
и после этого:
11 12 13 выскакивают мгновенно на 13-й секунде.
И т. д.
То есть, за 13 секунд строка 23 (и не только она одна) в #160 отработала 13 раз.

Всегда! Это математически доказуемый факт.

И? Там вполне можно от него избавиться.

Как по мне, описание совершенно разных процессов

Или я “туговат”))

P.S. Я к тому, что алгоритм надо описывать полностью,
чтобы была полная картина .
А лучше выложите схему конкретного устройства, и, тогда
можно будет получить исчерпывающий ответ

Я вот никак не пойму, ну миллис врёт на секунды в минуту и требует точной настройки к данному экземпляру конструкции в данный момент времени. Вы как то запутались совсем между количественным и качественным.

По мотивам…))

Спойлер
#define delay3sek 3u 
#define OFFtime 5u

uint32_t tmrsec = 0;
uint32_t sek = 0;
bool STOP = false;

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

void loop() {
  if(millis() - tmrsec >= 1000)
  {
    tmrsec = millis();
    sek++;
    if(!STOP)
    Serial.print("LIGHT ON  ");
    else
    Serial.print("LIGHT OFF ");
    Serial.println(sek);//
  }

    if(sek >= OFFtime && sek < OFFtime + delay3sek)
    STOP = true;
    else
    STOP = false;
  }

Вариант, где на 3 секунды выключается свет(типа delay)
Но отсчёт секунд не прекращается. Если надо - легко можно зациклить

см#1

Тоже сомневался что так можно. Сам так делать избегал.
Решил всё же проверить код Optrona на переполнение миллис.
Для этого пришлось стать немного хакером))

Спойлер
const int32_t period = 1000;
unsigned long moment;
uint32_t tik = 0;
bool CHECK = false;
uint32_t start;
uint32_t stop;
extern volatile uint32_t timer0_millis;

void setup()
{
  Serial.begin(9600);
  timer0_millis += 4294957000;// 10сек 296мс до переполнения
  moment = 4294957000;//миллис!!! ))))
}

void loop()
{
   if(!CHECK)
   {
    start = millis();
    CHECK = true;
   }

  if (millis() - moment >= period)
  {
    stop = millis();
    moment = moment + period;
    tik++;
    Serial.print("tik = ");
    Serial.print(tik);
    Serial.print("  periodtik = ");
    Serial.print(stop - start);
    Serial.print("  millis = ");
    Serial.println(millis());
    CHECK = false;
  }

}
Спойлер

Как видим, с этой стороны всё норм.
Если тест сделал не правильно, прошу поправить

2 лайка

Если все делать правильно, проблем быть не должно. Главное, чтобы новое значение moment не превышало текущее значение millis(), а при показанном выше применении оно и не должно превысить. Но таки новичкам такого лучше не советовать ))

1 лайк

А чему тут быть не норм?

Вот так, например, сделана системная функция delay() в IDE 2.3.2

void delay(unsigned long ms)
{
	uint32_t start = micros();

	while (ms > 0) {
		yield();
		while ( ms > 0 && (micros() - start) >= 1000) {
			ms--;
			start += 1000;
		}
	}
}
1 лайк

Дык, пока сам не проверишь, не убедишься))

Проверил #175. Работает! Дим-мычъ даже продемонстрировал это в случае переполнения.