Необходимо отмерять секунды

Здравствуйте.
Необходимо увеличивать счетчик секунд stsec каждую секунду. Правильный ли подход к решению этой задачи?
Спасибо.

long stsec=0; // счетчик секунд;
unsigned long t2=0; // момент увеличения счетчика секунд

void loop()
{
  if (millis()-t2>=1000)
  {
    stsec++;
    t2=t2+1000;
  }
}

А просто millis делить нацело на 1000 не вариант ???

Этот вариант я использую через несколько дней, чтобы убедиться в том, что stsec с делением millis() на 1000 нацело не расходится более, чем на секунду. Правда, тип stsec сейчас поменяю.

Даже интересно, как ты это проверишь …
Точность тактового генератора в Ардуино +/- нихера.
При любой попытке измерять реальное время встроенными средствами Ардуино, результат будет отличаться от реального времени, при чем по разному.
Зависеть будет и от питания и от температуры и от конкретного экземпляра.

Да хотя бы с часами. Секундомером.

увеличиваю…

#include <avr/io.h>
#include <avr/interrupt.h>
#define LEDPIN 13

volatile uint32_t stsec = 0;

void setup()
{
  pinMode(LEDPIN, OUTPUT);

  // инициализация Timer1
  cli();  // отключить глобальные прерывания
  TCCR1A = 0;   // установить регистры в 0
  TCCR1B = 0;

  OCR1A = 15624; // установка регистра совпадения

  TCCR1B |= (1 << WGM12);  // включить CTC режим
  TCCR1B |= (1 << CS10); // Установить биты на коэффициент деления 1024
  TCCR1B |= (1 << CS12);

  TIMSK1 |= (1 << OCIE1A);  // включить прерывание по совпадению таймера
  sei(); // включить глобальные прерывания
}

void loop()
{
  // основная программа
}

ISR(TIMER1_COMPA_vect)
{
  stsec++;
  digitalWrite(LEDPIN, !digitalRead(LEDPIN));
}
1 лайк

кто сложнее?)

Ну ты же знаешь, что эта процедура бесполезна.
Отличатся будет и сильно.

Ну а как иначе без спец. средств. Только на глаз. +/-.)
У меня обычные часы пикают каждый час. Я же, сидя за компьютером, вижу насколько они спешат/отстают.)

Мне нужно совпадение stsec (в пределах секунды) с “машинным, системным” временем.

Расходждение с реальным временем меня бы устроило +/- 10 минут. Затем корретировать. Отстали системные часы больше, чем на 10 минут - добавил 10 минут и наоборот.

А разве не 15625?

Нормально. Делаешь суточную коррекцию и вперёд. Только погрешность будет зависеть от питающего напряжения и, в большей степени, температуры.

long stsec=0; // счетчик секунд;

unsigned long t2=0; // эта переменная используется ТОЛЬКО внутри одной функции
//   и нигде больше. Что она делает в глобальной области видимости?

void loop()
{
  if (millis()-t2>=1000)
  {
    stsec++;
    t2=t2+1000; // идея так себе - довольно дорогая
  }
}

Вот так правильнее:

long stsec = 0; // счетчик секунд;

void loop(void) {
	{
		static unsigned long t2 = 0; // момент увеличения счетчика секунд
		const unsigned long currentMillis = millis();
		if (currentMillis - t2 >= 1000) {
			stsec ++;
			t2 = currentMillis;
		}
	}
}

Зачем, чтобы в случае задержки в loop проскочить мимо значения и пойти на вторую секунду?

Нет, это будут уже готовые секунды:

uint32_t secs = millis()/1000; 

Зачем огород городить…

Сорри, о таком варианте не подумал. Мне почему-то всё время рисовалось (не знаю, с чего), что нам важно знать момент перехода секунды (типа что-то сделать).

Точно мне смысл задачи тоже неясен.
Что там за “системное время”,

Именно нужен момент перехода секунды. Если в текущем цикле произошло отставание на долю секунды, то в следующем будет опережение на эту же долю. И эти “рывки” stsec вполне устраивают. stsec - это маятник своего рода.

Тогда лучше верните вариант со сложением, как у Вас было.

1 лайк

Что за бред…
Если в прошлом цикле произошло отставание, то в следующем его максимум не будет, а скорее всего будет точно такое же отставание.
Или вам нужна корректировка ?
Про это в шапке нет ни слова