Ho studiato un po' il codice della funzione millis() dell'Arduino..... è un codice un po' particolare.
Vi spiego. Nella mia swRTC quando ho messo l'ISR per gestire l'overflow del timer ed incrementare il contatore dei millisecondi che poi usavo per aggiornare i secondi e tutti gli altri registri temporali in cascata (ore, minuti, giorni ecc...) avevo impostato il timer in modo tale che gli overflow avvenissero esattamente 1 ogni 1000mo di secondo. Ciò è possibile dando un valore iniziale al contatore interno del timer. Siccome il contatore è a 8 bit, quindi i valori possibili sono 256, tramite calcoli (la faccio breve) per 16 MHz si imposta un prescaler di 64 e si usa un valore iniziale che dev'essere di 6. In questo modo si ha 16000000/64/250=1000. Quindi 1000 overflow al secondo o, viceversa, 1 secondo ogni 1000 overflow.
Sull'Arduino la cosa è più complicata. Siccome appunto il timer 0 è usato anche per generare il segnale PWM sui pin 5 e 6, non potevano impostare il calcolo come ho fatto io perché se davano un valore di partenza al contatore alteravano anche il segnale PWM. Allora hanno adottato una soluzione via software per limare quella differenza di 6. Inoltre usano anche un altro calcolo per tener conto dei microsecondi.
Per allineare l'aggiornamento all'effettiva frequenza di overflow del timer devo tener conto del fatto che stiamo andando ad un clock leggermente diverso per cui devo calcolare 976 overflow al secondo invece che 1000.
Dopo aver capito come funzionava il tutto, sono riuscito a creare questi 2 file. Sono versioni che vanno sostituite ai file wiring.c e wiring.h dell'Arduino IDE 002x (per la 1.0 ancora non ho fatto nulla) nella cartella /hardware/arduino/cores/arduino.
Adesso c'è la nuova funzione seconds() che restituisce i secondi dall'avvio dello sketch, restando sempre funzionanti sia millis, delay e delaymicroseconds di Arduino e non consumando nessun interrupt o timer aggiuntivo.
Ah, questa modifica è compatibile anche con la secTimer per via del fatto che usa 2 timer differenti ma lo sketch secTimerLed non è più compilabile perché lì usavo una variabile denominata seconds, che invece ora è una parola riservata del core dell'Arduino.
Ah, altra cosa. C'è anche un nuovo file keywords.txt che dovete sostituire a quello che avete in /lib per avere l'evidenziazione del codice.
Resta da provare se la funzione continua a... funzionare attivando il PWM. Sicuramente sì (altrimenti non andrebbe neanche la millis) ma non ho materialmente avuto il tempo di provarla.
Allegato c'è uno sketch di prova, una specie di BlinkWithoutDelay che usa seconds() al posto di millis().
Resta inteso che funziona SOLO per l'Arduino e per gli Atmega168/328 e 1280/2560 dato che è una modifica al core dell'Arduino e non una libreria a sé stante.
seconds2.zip (6.57 KB)