Varie · 13 settembre 2012 0

Un semplice RTC basato sul leOS

Guardando ad un mio precedente progetto, la libreria swRTC, ho pensato di realizzare qualcosa di simile usando il leOS. Meno preciso senz’altro ma anche più semplice, grazie all’uso del leOS. Ho scritto quindi un semplice sketch che usa il leOS per creare un task che ogni 1000 millisecondi, quindi 1 volta al secondo, aggiorna un orologio RTC software. Spero che questo sketch sia utile.

Lo sketch è scritto usando l’IDE 1.0.1 di Arduino e stampa sulla seriale l’orario, che potete modificare agendo sulle variabili globali. Il lampeggio del led integrato scandisce i secondi.

/* 
    Creazione di un semplice RTC software mediante l'uso del leOS.
    Viene creato un task che aggiorna ogni secondo una serie di
    variabili temporali per poter gestire ore, minuti, secondi,
    giorno, mese ed anno.

    L'orario e la data attuali sono stampati ad intervallo di 1
    secondo direttamente sulla seriale, contemporaneamente al
    lampeggio del led integrato sull'Arduino.

    La precisione non è elevata a causa della presenza di un
    risonatore ceramico.

    Versione: 1.0 - 2012/09/13

    Licenza: GNU GPL 3.0 o successive
*/

#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("Ore ");
        Serial.print(_hours, DEC);
        Serial.print(":");
        Serial.print(_minutes, DEC);
        Serial.print(":");
        Serial.print(_seconds, DEC);
        Serial.print(" - Data: ");
        Serial.print(_day, DEC);
        Serial.print("/");
        Serial.print(_month, DEC);
        Serial.print("/");
        Serial.println(_year, DEC);    
    }
}

//aggiorna l'orologio software
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++;
                    }
                }
            }
        }
    }
}

//controlla se l'anno corrente è bisestile
boolean leapYear(int yearT) {
    if (((yearT % 4) == 0) && ((yearT % 100) != 0) || ((yearT % 400) == 0)) {
        return true;
    } else {
        return false;
    }
}