4 Replies Latest reply on Feb 3, 2018 2:35 PM by simon.ganne

    Is the timer of an arduino accurate enough to build a clock or do I need a RTC?

    simon.ganne

      Is the timer of an arduino accurate enough to build a clock or do I need a RTC? I have some problems with the precision of my clock. I use a TFT display to show the date and the time, it works just fine but the clock is running too slow. has anyone a solution?  I'm going to use this in a project, the code is not complete yet but I have to get this part right first. Here is my code:

      #include <Adafruit_GFX.h>
      #include <MCUFRIEND_kbv.h>                                // bibliotheek voor het communiceren met het diplay 
      #include "DHT.h"
      #include <stdio.h>
      
      
      MCUFRIEND_kbv tft;                                        // maak een display aan
      DHT dht;
      
      
      #if defined(__SAM3X8E__)
      #undef __FlashStringHelper::F(string_literal)
      #define F(string_literal) string_literal
      #endif
      
      
      #define BLACK       0x0000      /*   0,   0,   0 */
      #define WHITE       0xFFFF      /* 255, 255, 255 */
      
      
      uint8_t hh, mm, ss;
      int date_month, date_day, date_year;
      String date_month_string, date_day_string, date_year_string;
      unsigned long time_val, old_time_val, old_time_val_1;
      
      
      int text_size = 3;
      int time_cursor_x = 10;
      int time_cursor_y = 110;
      
      
      uint8_t conv2d(const char* p)
      {
        uint8_t v = 0;
        if ('0' <= *p && *p <= '9') v = *p - '0';
        return 10 * v + *++p - '0';
      }
      void setup() {
        // put your setup code here, to run once:
        Serial.begin(9600);                               // begin de seriële monitor
        while (!Serial) ;                                 // wacht tot deze is opgestard
        String date_string = __DATE__;
      
      
        tft.reset();                                      // reset het tft display
        tft.begin(0x7783);                                // begin de communicatie met het display met adres 0x7783
        tft.setRotation(1);                               // roteer het display zodat het in landscape modus staat
        tft.fillScreen(BLACK);
      
      
        hh = conv2d(__TIME__);
        mm = conv2d(__TIME__ + 3);
        ss = conv2d(__TIME__ + 6);
        date_month_string = date_string.substring(0, 3);
        date_day_string = date_string.substring(4, 6);
        date_year_string = date_string.substring(7, 11);
      
      
        date_year = date_year_string.toInt();
        date_day = date_day_string.toInt();
        date_month = month_string_to_int(date_month_string);
        OCR0A = 0xAF;
        TIMSK0 |= _BV(OCIE0A);
      }
      void loop() {
        // put your main code here, to run repeatedly:
        text_size = 3;
        time_cursor_x = 10;
        time_cursor_y = 110;
      }
      SIGNAL(TIMER0_COMPA_vect){
        time_val = millis();
        if ((time_val - old_time_val) >= 1000) {
          if (++ss > 59) {
            ss = 0;
            mm++;
            if (mm > 59) {
              mm = 0;
              hh++;
              if (hh > 23) {
                hh = 0;
                date_day++;
                if (date_day == 31 && (date_month == 1 || date_month == 3 || date_month == 5 || date_month == 7 || date_month == 8 || date_month == 10 || date_month == 12)) {
                  date_day = 0;
                  date_month++;
                  if (date_month > 11) {
                    date_month = 1;
                    date_year++;
                  }
                }
                if (date_day == 30 && (date_month == 4 || date_month == 6 || date_month == 9 || date_month == 11)) {
                  date_day = 0;
                  date_month++;
                }
                if (date_day == 28 && date_month == 2 && (date_year % 4) != 0) {
                  date_day = 0;
                  date_month++;
                }
                if (date_day == 29 && date_month == 2 && (date_year % 4) == 0) {
                  date_day = 0;
                  date_month++;
                }
              }
            }
          }
          tft.setTextColor(WHITE);
          tft.setTextSize(text_size);
          char buf[8];
          char buf_2[12];
          sprintf(buf_2, "%02i/%02i/%04i", date_day, date_month, date_year);
          sprintf(buf, "%02d:%02d:%02d", hh, mm, ss);
          tft.setCursor(time_cursor_x, time_cursor_y);
          tft.fillRect(time_cursor_x, time_cursor_y, 50 * text_size, 7 * text_size , BLACK);
          tft.print(buf);
          tft.setCursor(time_cursor_x, time_cursor_y + 8 * text_size);
          tft.fillRect(time_cursor_x, time_cursor_y + 8 * text_size, 60 * text_size, 7 * text_size , BLACK);
          tft.print(buf_2);
          Serial.println("tijd weergegeven");
          old_time_val = time_val;
        }
      }
      int month_string_to_int(String date_month_string) {
        if (date_month_string == "Jan")return 1;
        if (date_month_string == "Feb")return 2;
        if (date_month_string == "Mar") return 3;
        if (date_month_string == "Apr") return 4;
        if (date_month_string == "May") return 5;
        if (date_month_string == "Jun") return 6;
        if (date_month_string == "Jul") return 7;
        if (date_month_string == "Aug") return 8;
        if (date_month_string == "Sep") return 9;
        if (date_month_string == "Oct") return 10;
        if (date_month_string == "Nov") return 11;
        if (date_month_string == "Dec") return 12;
      }