часы на ардуино с долгим loop

leds
Offline
Зарегистрирован: 20.10.2014

Приветствую. 

Подобная тема уже обсуждалась, но у меня ситуация немного другая.

loop() у меня выполняется в среднем за 3 секунды, но там разброс в 500 милисекунд.

Как можно реализовать часы с максимально точным показанием времени?

faraddin
Offline
Зарегистрирован: 11.08.2013

либо DS1307, либо функция millis(). А что для Вам максимально точно?

art100
Offline
Зарегистрирован: 09.03.2014

leds пишет:

Приветствую. 

Подобная тема уже обсуждалась, но у меня ситуация немного другая.

loop() у меня выполняется в среднем за 3 секунды, но там разброс в 500 милисекунд.

Как можно реализовать часы с максимально точным показанием времени?

Боюсь даже предложть. За мной тут Клапуций с паяльником бегает.

переферия мусор? не?

без прерываний

или с одним страшныйм и ужасным прерыванием delay(1000);

http://arduino.ru/forum/proekty/arduino-v-tualete#comment-85444

Kлапаyций 99.99
Offline
Зарегистрирован: 11.10.2014

art100 пишет:

Боюсь даже предложть. За мной тут Клапуций с паяльником бегает.

не бойся - я на танке в Москву еду, заказал мне тут один, а затем отказался - стрельну в крембль и подарю лишенцу самоходную единицу принудительно.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

уровень бреда повышается

leds
Offline
Зарегистрирован: 20.10.2014

DS1307 сожалению нет. А заказывать нет времени уже.

Да и хочвется без неё.  Максимально точно - это чтобы разброс не больше 1-2 минут в месяц. Раз в месяц их будут подводить.

Раньше я раз в секунду запускал инкремент времени в loop()

void loop(){ 
   if ((unsigned long)(millis() - lastTime) >= interval){     
    incrementTime();//увеличиваем время    
  }  
}

void incrementTime() {  
  if (seconds >= 59) {    
    dmd.clearScreen( true ); 
    seconds = 0;    
    if (minutes >= 59) {
      minutes = 0;      
      if (hours >= 23) hours = 0; 
      else hours++;    
    }
    else minutes++;
  }
  else seconds++;  
}

И так как loop() проходил быстро, то было более менее точное время. Но сейчас так не получится сделать.

Теперь я думаю накапливать время в какую-нибудь unsigned long переменную, а при выводе просто переводить её в часы, минуты и секунды, при иусловии что было задано время последней корректировки.

Но в какой-то момент millis() обнудлится и я боюсь, что тут будут потери времени.

Radjah
Offline
Зарегистрирован: 06.08.2014

А проверку со счетчиком не таймер повесить никак?

При желании можно интервал в 22 дня задать (32K секунд)

leds
Offline
Зарегистрирован: 20.10.2014

Так как меня интересуют только минуты (секунды не важны), сделал вот так:

void incTime(){ //# Время
unsigned long LongMinute = 60000;
  if (millis() < prev_ms) {prev_ms = millis();} //это проверка обнуления миллисекунд
  if ((millis() - prev_ms) >= LongMinute) { //отбивка интервала в 1 минуту
  	prev_ms = millis() - (millis() - prev_ms - LongMinute); //засекаем когда сработал интервал
  	if (minutes >= 59) {
        minutes = 0;      
        if (hours >= 23){hours = 0; 
        }else hours++;    
      } else minutes++;
  } 
}//#

Но проблема в том, что millis() отстает в моей программе от реального времени. 

Я использую библиотеку <TimerOne.h>, а также прерывания на 5 таймере Arduino Mega

Может из-за этого отсает?

leds
Offline
Зарегистрирован: 20.10.2014

То есть я на другой ардуине вывожу millis() в Serial

И на своей меге с задействованными тамерами тоже вывожу в Serial

 

В итоге сериал с меги значительно отстает. Несколько секунд в минуту.