Varie · 13 September 2012 0

A simple RTC based on leOS

I was looking at a previous work of mine, the library swRTC, and I thinked that I could realize something similar using leOS. Sure, less accurate, but easier too thanks to the use of leOS. So I wrote the sketch below that uses leOS to create a task that updates, every 1000 milliseconds (so 1 time at a second), a software RTC. I hope that this work will be useful.

The sketch has been written using Arduino IDE 1.0.1 and it prints on the serial monitor the internal time, that you can modify just by editing the corresponding global variables. The led blinking rhythms the seconds.

/* 
    A simple software RTC based on the use of leOS.
    A task has been created to update every second a series of variables 
    that keep the hours, minutes, seconds, day, month, and year.

    The time and the date are printed on the serial monitor
    together with the blinking on the integrated LED.

    The RTC is not accurate due to the presence of a ceramic resonator.

    Version: 1.0 - 2012/09/13

    License: GNU GPL 3.0 or later
*/

#include "leOS.h"

leOS myOS;

volatile byte _hours = 0;
volatile byte _minutes = 0;
volatile byte _seconds = 0;
volatile byte _day = 0;
volatile byte _month = 0;
volatile int _year = 0;
volatile byte daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
byte led1Status = 0;
const byte LED1 = 13;
byte temp = 0;

void setup() {
    myOS.begin();
    Serial.begin(9600);
    pinMode(LED1, OUTPUT);
    myOS.addTask(updateRTC, 1000);
    temp = _seconds;
}

void loop() {
    if(temp != _seconds) {
        led1Status ^= 1;
        digitalWrite(LED1, led1Status);
        temp = _seconds;
        Serial.print("Time ");
        Serial.print(_hours, DEC);
        Serial.print(":");
        Serial.print(_minutes, DEC);
        Serial.print(":");
        Serial.print(_seconds, DEC);
        Serial.print(" - Date ");
        Serial.print(_day, DEC);
        Serial.print("/");
        Serial.print(_month, DEC);
        Serial.print("/");
        Serial.println(_year, DEC);    
    }
}

//update the software clock
void updateRTC() {
    byte _dayT;
    _seconds++;

    if (_seconds>59) {
        _seconds=0;
        _minutes++;
        if (_minutes>59) {
            _minutes=0;
            _hours++;
            if (_hours>23) {
                _hours=0;
                _day++;
                if (_month == 2) { //february?
                    if (leapYear(_year)) {
                        _dayT=29;
                    } else {
                        _dayT=28;
                    }
                } else {
                    _dayT=daysPerMonth[_month-1];
                }
                if (_day>_dayT) {
                    _day=1;
                    _month++;
                    if (_month>12) {
                        _month=1;
                        _year++;
                    }
                }
            }
        }
    }
}

//check if the year is a leap year
boolean leapYear(int yearT) {
    if (((yearT % 4) == 0) && ((yearT % 100) != 0) || ((yearT % 400) == 0)) {
        return true;
    } else {
        return false;
    }
}