Contare 60 minuti

Salve a tutti, dovrei creare un progetto in cui ho un mp3 lungo 60 minuti, con arduino lo faccio partire e dopo 59 minuti vorrei farlo riavviare. In più dopo qualche secondo, ad esempio 3, voglio memorizzare un particolare valore. Per contare 3 secondi penso di usare la funzione mills() come nell'esempio http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Il mio dubbio è su come fare a contare 59 minuti in maniera efficiente? posso usare semplicemente la funzione mills?
Grazie a chiunque voglia rispondere.

Tranquillo ... millis() è un unsigned long ... quindi ... poi calcolarci tempi fino a 50 gg. XD XD XD

Per avere una visione più completa sull'uso di millis() leggiti QUESTO e QUESTO :wink:

Guglielmo

Grazie mille Guglielmo, ho letto gli articoli nei link riportati, ora ho capito molte più cose.
Metto subito tutto in pratica :slight_smile:

Fai delle prove, potrebbe anche sbagliare di qualche minuto :smiley:

paulus1969:
Fai delle prove, potrebbe anche sbagliare di qualche minuto :smiley:

Se ha una Uno, puoi togliere il "potrebbe", è una certezza che la Uno sgarri e di non poco :wink:

La singola scheda ha sempre lo stesso errore, o dipende da fattori ambientali (temperatura, ...)?
Se l'errore fosse sempre lo stesso, si potrebbe compensare introducendo un fattore correttivo all'atto del caricamento.
Mi spiego meglio.
Scrivo il software "Faiqualcosa", questo software ha bisogno di gestire i minuti. Lo scrivo in modo da avere una costante che rappresenta il fattore di correzione. Diciamo che si chiama k.
Prendo la scheda "Pippo", ha un suo errore, diverso da quello della scheda "Pluto" e da quello della scheda "Topolino".
Carico su "Pippo" un programma "Testatempi" che invia un messaggio ogni X secondi e leggo questi messaggi dal PC mediante apposito software "Correggitempi". Il "Correggitempi" fa i suoi calcoli e mi fornisce il fattore di correzione, che poi inserirò nel programma "Faiqualcosa" assegnando il suo valore a k prima di lanciare compilazione e caricamento.
Sarebbe forse interessante....

il "problema" e il finto quarzo che è un risuonatore, oltre a risuonare come gli pare e piace intorno alla frequenza di risonanza basta alitargli sopra che si sposta di frequenza ]:smiley:
un quarzo serio è un ottimo orologio ma costa quanto un arduino se non di più =(

Non c'è nessun "finto quarzo" in arduino, un quarzo ha 50ppm di errore e un risuonatore 200ppm, sono entrambi errori molto alti, non adatti per RTC precisi, per avere un clock preciso e stabile con la temperatura usare un TCXO che ha 1ppm , componente presente in tutti i cellulari, solo che costa al dettaglio circa 2-3 euro in confronto ai 0.10 euro di un quarzo

Riassumendo... dipende dalla temperatura, quindi sarebbe inutile cercare di compensarlo.
Per una realizzazione stand-alone, però, si potrebbe usare uno di questi elementi compensati termicamente ottenendo un miglioramento, pur facendo aumentare il costo di un paio di euro?
Trovandolo...
Io ho trovato questo

non sarà un po' esagerato? :smiley:

Ce ne sono di ancora più precisi e stabili ma il costo và su, e anche i consumi e le dimensioni, e allora la domanda è :
come fà la casio nei suoi orologetti da polso con quarzi modesti ad ottenere precisioni da "casio"? Facile : all'incirca come ha detto paulus1969!

Sì ma alla fine la questione non riguarda più la precisione ma l'effettiva utilità di essa.
Ossia: ha senso per la mia applicazione spendere 20/30$ per un componente che da solo vale quanto tutto il resto messo insieme? Se la risposta è sì, allora l'acquisto è da farsi, se la risposta è no, uno si tiene la tolleranza del risuonatore. O di un RTC tipo DS1307 o PCF8563 che hanno scarti di qualche secondo su 1 ora, quindi più che accettabili per gli usi comuni.

leo72:
RTC tipo DS1307 o PCF8563 che hanno scarti di qualche secondo su 1 ora, quindi più che accettabili per gli usi comuni.

Attenzione, sono scarti di +/- 1 sec. su un ora ... il che significa che su 24 ore spesso si compensano e la precisione rimane comunque altissima :wink:

Se poi vuoi ancora di più ... DS3231 (Timekeeping Accuracy ±3.5ppm from -40°C to +85°C) ... XD

Guglielmo

Scusate se mi intrometto ma la discussione mi interessa.. Ho un progetto su questo forum che riguarda un sistema di controllo dei consumi di casa con delle azioni di distacco e di segnalazione che dipendono proprio dal tempo passato che attualmente viene calcolato in base ai millis() !!!

Inoltre lo sketch calcola l'uptime del sistema visualizzandolo su lcd. Sino ad oggi non mi sono mai accorto di GROSSI "sbalzi" di tempo, però leggere che in base a tanti fattori (tra cui la temperatura) il "tempo" possa cambiare mi ha fatto pensare un po, inoltre:

Siccome il progetto iniziato con UNO sta continuando con YUN (per aggiungere funzionalità web, di lettura e controllo remoto), da due giorni circa avevo pensato (prima di imbattermi in questo thread) di trasformare tutto il codice che si basa su "millis() - millisprecedenti > intervallo"... come da esempio "BlinkWithoutDelay", in una cosa del genere:

...
Process uptime;
uptime.runShellCommand("echo | cut -d. -f1 /proc/uptime");
while (uptime.available() > 0) {
    int sec = uptime.read();
    Serial.write(sec);
}
Serial.flush();
...

attualmente in codice così come postato scrive correttamente su monitor seriale il numero di SECONDI che il processore con linux mi passa.
Due domande:

  1. Il modo in cui Yun calcola quanti secondi sono trascorsi dall'avvio di un processo, è soggetto pure ad "errori" come per UNO con i millis?
  2. Avendo il valore dentro una INT, come mai se prima del Serial.write aggiungo un: sec += x; dove x è un qualsiasi numero, il serial monitor mi scrive dei caratteri strani anzichè il risultato dell'operazione ?

5a2v0:
....
Siccome il progetto iniziato con UNO sta continuando con YUN
....

Ma visto che sei su una Yún sotto Linux ... fai ogni tot delle chiamate ad un server NTP e ti prendi l'ora esatta e aggiorni con regolarità l'orologio di sistema :wink:

Ricordo che era una cosa fattibile già con la UNO ... immagino che con una Yún e Linux a bordo ... sia banale ...

Guglielmo

Si Yun è già configurato per aggiornare l'orario tramite server esterni (configurabili per altro). Però se poi mancasse internet quando Yun si avvia ? Se magari si aggiornasse l'ora (legale, solare) non vorrei andare a incappare in problemi e controllo da integrare...

In questo modo i secondi d'avvio me li da già... solo non capisco il perché non posso fare operazioni di somma/sottrazione/divisione/moltiplicazione su una variabile INT che contiene un numero !!

5a2v0:
In questo modo i secondi d'avvio me li da già... solo non capisco il perché non posso fare operazioni di somma/sottrazione/divisione/moltiplicazione su una variabile INT che contiene un numero !!

... magari perché le variabili che rappresentano lo "Unix Time" NON sono int (16 bit) ma sono unsigned long (32 bit) ... ]:smiley: ]:smiley: ]:smiley:

Guglielmo

E questo anche se il dato passato é 3600 come avrei ad esempio dopo un ora di accensione ?

EDIT:

ho provato con unsigned long ma il risultato non cambia..

 while (uptime.available() > 0) {
    unsigned long c = uptime.read();
    c /= 3600;
    Serial.write(c);

mi restituisce caratteri illeggibili..

... perdona, non lavoro sulla Yún ... da dove arriva quella classe uptime ? Perché occorre capire esattamente COSA restituisce ... :roll_eyes:

Guglielmo

gpb01:
Attenzione, sono scarti di +/- 1 sec. su un ora ... il che significa che su 24 ore spesso si compensano e la precisione rimane comunque altissima :wink:

Sì ma il titolo del thread è "Contare 60 minuti", quindi per 1 ora avere in più o in meno un paio di secondi non è un gran problema :wink:

... trovata ... l'errore che stai facendo è considerare che ritorna un int o un long int per rappresentare un numero ...

Se ti studi il metodo read() vede che : Returns the first byte of incoming data available (or -1 if no data is available) quindi, nella tua while, tu stai stampando CARATTERE a CARATTERE quello che la "echo | cut -d. -f1 /proc/uptime" ti ha ritornato e NON un numero !!!

Per avere un numero dovresti mettere quei caratteri in un char array e convertire poi la stringa ottenuta in un long integer su cui puoi lavorare !

Guglielmo