element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Community Feedback
  • Challenges & Projects
  • element14 presents
  • element14's The Ben Heck Show
  • Community Feedback
  • More
  • Cancel
Community Feedback
Forum Is the timer of an arduino accurate enough to build a clock or do I need a RTC?
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Community Feedback requires membership for participation - click to join
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Verified Answer
  • Replies 4 replies
  • Answers 2 answers
  • Subscribers 8 subscribers
  • Views 2195 views
  • Users 0 members are here
  • tft display
  • arduino time
  • arduino
Related

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

simon.ganne
simon.ganne over 7 years ago

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;
}

  • Sign in to reply
  • Cancel

Top Replies

  • shabaz
    shabaz over 7 years ago +9 verified
    Hi Simon, The arduino is as accurate as a typical home clock, because it uses a crystal oscillator. However, you're using the millis() function and although there is a risk of an assumption that this provides…
  • ntewinkel
    ntewinkel over 7 years ago +6 suggested
    Hi Simon, Maybe try the Time library? It seems to take care of most of the details for you. https://playground.arduino.cc/Code/Time Cheers, -Nico
  • beacon_dave
    beacon_dave over 7 years ago +4 suggested
    You don't say how accurate the clock needs to be an or the intended operating conditions. However there is also the internal RC oscillator, which can be calibrated for improved accuracy: http://www.atmel…
  • shabaz
    0 shabaz over 7 years ago

    Hi Simon,

     

    The arduino is as accurate as a typical home clock, because it uses a crystal oscillator. However, you're using the millis() function and although there is a risk of an assumption that this provides a count value in milliseconds, this actually isn't the case according to https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers  - that website says that millis() provides a count at a rate of 976.5625Hz, i.e. it increments every 1.024msec. So, this explains why the clock is perceived to be running too slowly.

     

    You could compensate for the discrepancy by adding three seconds to the displayed value every 125 seconds. Another (warranty-voiding, and possibly outside the microcontroller specification too) option is to remove the crystal and replace it with a different one (16.384MHz instead of 16MHz).

     

    Personally I would just add 3 every 125 sec, perhaps spaced out. So, add 1 second when the clock would display that 41 seconds have elapsed, add another second after 83 seconds have accumulated, and add one more second at 125 seconds. Easy to do if you keep another variable counting this. With this approach, if you're displaying the seconds value, some people might notice it, but if you're not displaying the seconds then it would go unnoticed.

    • Cancel
    • Vote Up +9 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • ntewinkel
    0 ntewinkel over 7 years ago

    Hi Simon,

     

    Maybe try the Time library? It seems to take care of most of the details for you.

     

    https://playground.arduino.cc/Code/Time

     

    Cheers,

    -Nico

    • Cancel
    • Vote Up +6 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • beacon_dave
    0 beacon_dave over 7 years ago

    You don't say how accurate the clock needs to be an or the intended operating conditions. However there is also the internal RC oscillator, which can be calibrated for improved accuracy:

    http://www.atmel.com/Images/Atmel-2555-Internal-RC-Oscillator-Calibration-for-tinyAVR-and-megaAVR-Devices_ApplicationNot…

     

    This would have to be calibrated on a per microcontroller device basis, so not so convenient for large quantities. It is also susceptible to voltage and temperature so you probably want to calibrate it in typical usage conditions for best results.

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • simon.ganne
    0 simon.ganne over 7 years ago in reply to shabaz

    thanks this was really helpfull!!

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube