Часы без модуля реального времени.

Тема в разделе "Arduino & Shields", создана пользователем Ssienby, 12 июн 2018.

  1. Ssienby

    Ssienby Нуб

    Добрый день, господа. Было интересно сделать часы с подсветкой и с датчиком движения без модуля реального времени. После продолжительного теста часов, я заметил отставание у часов(за 2 часа = 20 секунд). Просмотрел код, но ничего подозрительного я не нашёл. Не могли бы вы мне помочь?
    код:
    #include <LiquidCrystal.h>

    const int ekran = 7;
    const int svet = 3;
    const int datchik = 6;

    int minuta = 5;
    int chas = 10 ;

    LiquidCrystal lcd(8, 9, 10, 11, 12, 13);


    void setup() {
    LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
    lcd.begin(16,2);
    pinMode(ekran,OUTPUT);
    pinMode(svet, OUTPUT);
    pinMode(datchik, INPUT);
    lcd.setCursor(0,1);
    lcd.print("1");
    lcd.begin(16,2);
    }

    void loop() {
    int i = 0;
    for( int i = 0; i < 59; i++){
    if( digitalRead(datchik) == 1){ //управление освещением
    digitalWrite(ekran, HIGH);
    digitalWrite(svet, HIGH);
    } else {
    digitalWrite(ekran, LOW);
    digitalWrite(svet, LOW);
    }
    lcd.begin(16,2);
    lcd.clear();
    if(chas < 10){ //вывод часов
    lcd.setCursor(5,1);
    } else {
    lcd.setCursor(4,1);
    }
    lcd.print(chas);
    lcd.setCursor(6,1);
    lcd.print(":");
    lcd.setCursor(7,1);
    if(minuta < 10){ // вывод минут
    lcd.setCursor(7,1);
    lcd.print("0");
    lcd.setCursor(8,1);
    lcd.print(minuta);
    } else {
    lcd.setCursor(7,1);
    lcd.print(minuta);
    }
    lcd.setCursor(9,1);
    lcd.print(":");
    if ( i < 10){ // вывод секунд
    lcd.setCursor(10,1);
    lcd.print("0");
    lcd.setCursor(11,1);
    lcd.print(i);
    } else {
    lcd.setCursor(10,1);
    lcd.print(i);
    }
    delay(1000);
    }
    if( minuta < 59){ // обработка минут и часов
    minuta = minuta + 1;
    } else {
    minuta = 0;
    if ( chas < 23){
    chas = chas +1;
    } else {
    chas = 0;
    }
    }
    }
     

    Вложения:

    • Version1.ino
      Размер файла:
      1,6 КБ
      Просмотров:
      43
  2. BAR__MEN

    BAR__MEN Гуру

    А что насчет delay? Если он делает задержку, весь код останавливается и следовательно отсчет времени тоже.
     
    Ssienby нравится это.
  3. Ssienby

    Ssienby Нуб

    Он один задерживает на 1 секунду, чтобы был правильный отсчет секунд.
     
  4. BAR__MEN

    BAR__MEN Гуру

    Напомню, другие операции тоже не мгновенные, они тоже дают задержку
     
    Yaroslav1 и Ssienby нравится это.
  5. Ssienby

    Ssienby Нуб

    Спасибо, сейчас попробую уменьшить delay()
     
  6. Ssienby

    Ssienby Нуб

    А как в delay записывать десятичную дробь ?
     
  7. Igor68

    Igor68 Гуру

    Не поможет... надо сделать обучаемые. Это когда через какое-то время производилась коррекция часов. Когда-то давно делал что-то подобное на PIC16F876 с синхронизацией времени по GPS. Через 30-40 минут обучения по GPS они убегали менее чем на 1 сек. за 48 часов (оставляли для теста на выходные). Там набирался массив коррекции, а среднее значение содержимого массива было делителем для таймера.
     
    Ssienby и BAR__MEN нравится это.
  8. Ssienby

    Ssienby Нуб

    А есть ли менее сложный и быстрый выход из этой ситуации?
     
  9. Daniil

    Daniil Гик

    никак, аргумент этой функции int.
    Есть delayMicroseconds.
     
  10. Ssienby

    Ssienby Нуб

    Хорошо, спасибо :)
     
  11. Ssienby

    Ssienby Нуб

    Хорошо, спасибо :)
     
  12. BAR__MEN

    BAR__MEN Гуру

    использовать модуль часов реального времени;)
     
    Daniil, Igor68 и Ssienby нравится это.
  13. Ssienby

    Ssienby Нуб

    Хорошо, спасибо :)
     
  14. Airbus

    Airbus Оракул

  15. SergeiL

    SergeiL Гик

    А если вместо delay(1000) поставить delay(998) ? ;)
     
    BAR__MEN нравится это.
  16. Ssienby

    Ssienby Нуб

    я рассчитал, что минимальное отклонение 86,7 секунд в день, и для более корректной работы, нужны дополнительные модули
     
  17. Daniil

    Daniil Гик

    т.е. у вас ошибка каждую секунду увеличивается на 86.7/24/60/60=1003.47 мкс, вот вам и подсказали ждать не 1000 мс=1000000мкс, а учесть, что остальной код тоже время занимает и ждать 998997 мкс. А чтобы учесть ещё почти 0.5 мкс, то можно через раз ждать то 998997 мкс, а в другой раз 998996 мкс, но не знаю отработает ли ардуина такую разницу. Вы до тронитесь до часов/пройдёте мимо может произойти искажение из-за изменения температуры.
     
    Ssienby нравится это.
  18. parovoZZ

    parovoZZ Гуру

    Использовать вачдог. У него асинхронный генератор, но чудес также ждать не стоит - часы будут отставать либо убегать в зависимости от температуры. Лучшее решение, на мой взгляд, это МК со встроенным генератором на часовой кварц. Там тоже не без фокусов - придётся замерять температуру и править коэффициенты. Внешний часовой модуль - в качестве обучения сойдет, но это решение из позапрошлого века.
     
    Ssienby нравится это.
  19. AlexU

    AlexU Гуру

    Если часы будут находиться в таком месте, в котором будет обеспечена постоянная температура, то можно откалибровать частоту генератора тактовых импульсов микроконтроллера, так чтобы генератор выдавал "правильную" частоту. Ну или учесть отклонение частоты генератора от номинала в коде. Но всё равно это не самое лучшее решение, если хотите сделать точные часы.

    И второе -- хватит изобретать велосипеды. В avr-libc (по крайней мере в версии 2.0 точно) есть реализация поддержки времени -- заголовочный файл 'time.h'. Для корректного подсчёта времени нужно обеспечить вызов функции 'system_tick()' раз в секунду (сделать это можно, например, с помощью того же таймера 'Timer0', который используется для подсчёта миллисекунд). Вы получите "полноценные" RTC -- вот только с точностью таких часов будут определённые проблемы, о которых указал в первом абзаце.
     
    Ssienby нравится это.
  20. Ssienby

    Ssienby Нуб

    Спасибо