Orologio siderale

Ciao a tutti,

vorrei costruire un orologio siderale partendo da un movimento per orologio da parete diviso in 24 ore (anziché 12) e controllarne la frequenza con Arduino. Perché un orologio da parete e non un semplice orologio digitale? Beh, è una questione di gusti personali, mi piace l'idea di ricostruirne il quadrante e di modificarlo a mio piacimento. Capisco di avere idee un po' anacronistiche, ma dovete avere pazienza.

Dunque! il meccanismo dell'orologio ce l'ho già ma dovrei utilizzarne solamente gli ingranaggi e posizionare un motore passo-passo sull'asse e pilotarlo con Arduino alla giusta frequenza per il tempo siderale.
L'orologio, poi, lo vorrei rimettere da PC (o direttamente da Arduino) per evitare di utilizzare encoder assoluti portando manualmente le lancette su ore 0. Con un pulsante di start il PC calcolerebbe il numero di passi da fare per rimettere l'ora siderale in base all'ora e alla data del PC o interne a Arduino.

Ma quali schede dovrei usare?

Ho rotto anche troppo, grazie.
Emiliano

io direi che un RTC esterno potrebbe bastare, in pratica è un orologio a se, che ha vita indipendente dall'arduino. Quindi per ora lo programmi una volta da PC, e magari ti fai un programmino che quando accendi il pc aggiorna l'ora, però a parte la prima volta arduino è indipendente.

Poi direi che ci vuole un pulsante di azzeramento e un pulsante di start.

puoi programmare l'rtc per lanciare un interrupt ogni secondo (anche i più economici lo permettono) in modo che eventualmente potrai mettere arduino in sleep profondo quando deciderai di fare un circuito a sè, per risparmiare tantissimo in batterie.

Dicevamo, ogni secondo arriva un iterrupt, arduino si sveglia, e fa scattare la lancetta di un passo. O meglio. se vuoi 24 ore, vuol dire che ti servono 1440 minuti, ovvero 86400 secondi.

Ti serve una buona meccanica per i secondi, ma per i minuti dovresti farcela anche in modo rozzo. In oltre gli stepper hanno un numero di passi ben preciso, quindi per il reset basta tornare indietro dei passi percorsi o completare i passi mancanti (sta a te vedere la soluzione che ti piace di più, io farei la stada "più veloce")

in oltre hai altri 2 interrupt:

  1. sul pulsante reset. Disabilita l'allarme che fa generare l'interrupt dall'RTC, dopodichè riporta la lancetta in posizione zero
  2. pulsante start: riabilita l'allarme dell'RTC.

@lesto:
un orologio siderale è un orologio che misura il "tempo delle stelle" :wink:
Rispetto ad un orologio che misura il tempo "ortodosso", l'orologio siderale ha un giorno che dura 23h56m4s, se non ricordo male.

Quindi serve oltre ad un RTC da cui prelevare l'orario, anche un piccolo calcolo sw per accelerare leggermente le lancette durante il giorno, in modo che la mezzanotte arrivi 3m56s prima.

E dopo 6 mesi misurerà la mezzanotte a mezzogiorno. :disappointed_relieved:

leo72:
@lesto:
un orologio siderale è un orologio che misura il "tempo delle stelle" :wink:
Rispetto ad un orologio che misura il tempo "ortodosso", l'orologio siderale ha un giorno che dura 23h56m4s, se non ricordo male.

Quindi serve oltre ad un RTC da cui prelevare l'orario, anche un piccolo calcolo sw per accelerare leggermente le lancette durante il giorno, in modo che la mezzanotte arrivi 3m56s prima.

se prendiamo l'interrupt ogni secondo dall'RTC, allora è un problema di meccanica:
un giro anzichè farlo in 86400 step, dovrà farlo in 86400 - 3*60 - 56=86164 step

Sì, si può rigirare in questo modo il problema, dicendo che ogni secondo invece di far avanzare la lancetta dei secondi di 1 passo, la si deve far avanzare di 1,002731481 passi.

PaoloP:
E dopo 6 mesi misurerà la mezzanotte a mezzogiorno. :disappointed_relieved:

E' un orologio usato in astronomia per i calcoli delle posizioni degli oggetti celesti, non si usa per avere l'ora :wink:

lesto:
io direi che un RTC esterno potrebbe bastare, in pratica è un orologio a se, che ha vita indipendente dall'arduino. Quindi per ora lo programmi una volta da PC, e magari ti fai un programmino che quando accendi il pc aggiorna l'ora, però a parte la prima volta arduino è indipendente.

Poi direi che ci vuole un pulsante di azzeramento e un pulsante di start.

puoi programmare l'rtc per lanciare un interrupt ogni secondo (anche i più economici lo permettono) in modo che eventualmente potrai mettere arduino in sleep profondo quando deciderai di fare un circuito a sè, per risparmiare tantissimo in batterie.

Dicevamo, ogni secondo arriva un iterrupt, arduino si sveglia, e fa scattare la lancetta di un passo. O meglio. se vuoi 24 ore, vuol dire che ti servono 1440 minuti, ovvero 86400 secondi.

Ti serve una buona meccanica per i secondi, ma per i minuti dovresti farcela anche in modo rozzo. In oltre gli stepper hanno un numero di passi ben preciso, quindi per il reset basta tornare indietro dei passi percorsi o completare i passi mancanti (sta a te vedere la soluzione che ti piace di più, io farei la stada "più veloce")

in oltre hai altri 2 interrupt:

  1. sul pulsante reset. Disabilita l'allarme che fa generare l'interrupt dall'RTC, dopodichè riporta la lancetta in posizione zero
  2. pulsante start: riabilita l'allarme dell'RTC.

Caspiterina, quante risposte! E tutte molto pertinenti. Veramente bravi tutti.
Ma questo RTC è costituito da uno stepper? Ed è possibile programmarlo in modo che invii l'interrupt ogni 0,9972685... anziché ogni secondo? Ovvero 86400 interrupt in 86164 secondi di tempo (23h 56m 04s)
Per quanto riguarda la meccanica ho già il movimento di un orologio su 24 ore che veniva pilotato da un quarzo.
Mi basterebbe rendere l'asse dello stepper solidale alla lancetta dei secondi, la rotazione della lancetta dei minuti e delle ore avverrebbe meccanicamente.

Cosa intendi quando dici "riporta la lancetta in posizione zero" ?
Io pensavo, ancor più semplicemente di quanto avevo detto, di farmi visualizzare dal PC l'ora siderale, spostare le lancette, compresi i secondi, un po' più avanti e riavviare l'RTC allo scattare di quell'ora sul PC.

no, un RTC è un Real Time Counter, ovvero un orologio.
Arduino ha dei timer interni, che però lavorano con un generatore di clock (quarzo o peggio oscillatore) molto impreciso, Leo72 ha provato a creare una libreria orologio usandoli, e l'errore è di molti secondi al giorno, forse anche minuti.

Un RTC invece è un chippino con un quarzo particolare che è fatto apposta per misurare il tempo come lo intendiamo noi (e costicchia, quanto un chip atmega intero, che al suo interno ha un oscillatore...)

poi gli stepper con 86164 o anche 86400non esiste, anche usando i microstep (sconsiglio ai principianti).

un motore stepper da 15/20€ ha circa 400step/rotazione.

86164(step richiesti)/400(step necessari)=215.41

cosa vuol dire? che devi creare una serie di ingranaggi che moltiplicano il movimento di 215.41 volte, ovvero ogni 215.41 rotazioni dello stepper avrai una rotazione completa dell'orologio.

Però quel numero NON è tondo (lo sarebbe stato nel caso di un orologio normale, 216 spaccato), ciò vuol dire che la lancetta sarà sempre un poco errata.. nulla che un umano possa vedere eh..

il punto è fare un ingranaggio 216:1 (anzi, 215.41:1, ma è impossibile se non usando qualche arcana combinazione, meglio cercare uno stepper che ha un numero di step a rivoluzione che sia divisore di 86164)
ovviemente puoi usare più ingranaggi in cascata

ORA sappi che NON ho mai studiato meccanica. Tutto quello che ti scrivo è basato su pura filosofia fatta al momento e non verificata, quindi magari ho detto boiate pazzesce........ ma dubito (tranne forse quella che NON è impossibile fare 215.41:1)

RTC sta per Real-Time Clock, ossia Orologio in Tempo Reale.
E' un piccolo integrato che serve a tenere il tempo.

Siccome a te serve un secondo che duri un po' meno di un secondo, non userei la tecnica dell'interrupt generato dal chip RTC esterno ma piuttosto potresti prendere un timer interno ed impostarlo affinché tu abbia un sistema efficace per calcolarti la durata che ti serve. Va studiato un po' ma non è impossibile. Anche nel caso dell'Arduino, il timer 0 è impostato per generare un interrupt ogni 976 us, quindi dopo 1000 interrupt non è trascorso 1 secondo esatto. Per "addirizzare" lo scorrere del tempo viene usato un piccolo accorgimento software.
Tu dovresti fare lo stesso secondo me. Ed usare l'RTC esterno solo per ricalibrare l'orologio siderale ogni 8/12 ore in modo che l'accumulo dello scarto abbia prodotto una differenza misurabile in secondi, un valore gestibile con l'RTC.

no, con la riduzione che dico io si può fare, solo che l'orologio ogni secondo "normale" muoverà la lancettadi 1.002739 secondi siderali.

invece se vuoi la precisione di conteggiare il secondo siderale... la cosa si complica.

Tu dovresti fare lo stesso secondo me. Ed usare l'RTC esterno solo per ricalibrare l'orologio siderale ogni 8/12 ore in modo che l'accumulo dello scarto abbia prodotto una differenza misurabile in secondi, un valore gestibile con l'RTC.

ma a questo punto l'errore accumulato sarebbe probabilmente molto più grande dell'errore di sommare ogni secondo reale 1.002739 ad una variabile float, e stampare quindi il numero troncato. Che poi ripeto, essendo a lancetta (e a 24ore) non si vede nemmeno questo errore, salvo lancetta lunga 1/2metri :wink:

lesto:
no, con la riduzione che dico io si può fare, solo che l'orologio ogni secondo "normale" muoverà la lancettadi 1.002739 secondi siderali.

Lesto, come dici tu non può funzionare. Ragiona un attimo.
Un secondo siderale è lungo 0,997261 secondi "legali". Nel modo che dici tu sposti in avanti la lancetta ma non hai il tempo allineato con la vera ora siderale.
Ti faccio un esempio:

00:00 siderali
00:00 "legali"

Dopo 1 secondo "legale", l'orario è:
00:01,002739
00:01

Ma la lancetta non sta sulla tacca di 1 secondo sull'orologio, ma poco avanti.

Invece a 00:01 siderali io devo avere la lancetta sulla 1a tacca dei secondi dopo appunto 0,997261 secondi "legali".

Cioè, non è solo una questione di spostare le lancette, l'orario siderale è un'orario a tutti gli effetti che misura il tempo in modo diverso e quindi la sua durata è inferiore e come tale va calcolata.

Domanda:
Si può collegare ad un ATmega320 un quarzo da 32KHz, e usarlo per regolare un timer con overflow ogni 997,26 millisecondi. Avresti, come fai nel looper con i secondi "legali", un secondo siderale "vero" con una buona precisione.

EDIT: Ho trovato questo application note --> http://www.atmel.com/Images/doc1259.pdf
E nel datasheet del 328 risulta la possibilita di usare RTC interno con quarzo separato --> http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Summary.pdf

P.S. il nuovo datasheet completo del 328 è di 35MB. :astonished: (http://www.atmel.com/devices/atmega328.aspx?tab=documents)

PaoloP:
Domanda:
Si può collegare ad un ATmega320 un quarzo da 32KHz, e usarlo per regolare un timer con overflow ogni 997,26 millisecondi. Avresti, come fai nel looper con i secondi "legali", un secondo siderale "vero" con una buona precisione.

Il modulo RTC degli Atmega328 può lavorare in modo asincrono con il quarzino suddetto.
Normalmente però ottieni delle frequenze diverse, date dal clock di 32768 Hz diviso per il prescaler.
Per cercare di ottenere qualcosa di diverso, bisogna scrivere una ISR che intercetti l'interrupt dell'overflow e modifichi il registro del timer in modo da provare ad ottenere la frequenza richiesta.

La miglior precisione che si può ottenere è 1,003921569.
In un giorno la differenza diventa di 337s, cioè 5,6 minuti. 2 minuti più del tempo siderale.
Quindi oltre a ciò andrebbe messo un sistema per recuperare questo differenza.

leo72:

lesto:
no, con la riduzione che dico io si può fare, solo che l'orologio ogni secondo "normale" muoverà la lancettadi 1.002739 secondi siderali.

Lesto, come dici tu non può funzionare. Ragiona un attimo.
Un secondo siderale è lungo 0,997261 secondi "legali". Nel modo che dici tu sposti in avanti la lancetta ma non hai il tempo allineato con la vera ora siderale.
Ti faccio un esempio:

00:00 siderali
00:00 "legali"

Dopo 1 secondo "legale", l'orario è:
00:01,002739
00:01

Ma la lancetta non sta sulla tacca di 1 secondo sull'orologio, ma poco avanti.

Invece a 00:01 siderali io devo avere la lancetta sulla 1a tacca dei secondi dopo appunto 0,997261 secondi "legali".

Cioè, non è solo una questione di spostare le lancette, l'orario siderale è un'orario a tutti gli effetti che misura il tempo in modo diverso e quindi la sua durata è inferiore e come tale va calcolata.

ma quella differenza di 1.002739 non la vedi ad occhio nudo, ma l'ingranaggio fa in modo che l'errore non si accumuli.

certo se conti gli step della lancetta, ti accorgerai che ne mancano 3*60 + 56....

problema risolvibile giocando sulla VELOCITA' di rotazione. Se ottieni una velocità di rotazione fissa, puoi calcolare una riduzione per cui tutto torni. l'RTC serve solo una volta ogni tot ad allineare l'orario, intervendendo sulla velocità di rotazione

Come ripeto sono alle prime armi con Arduino, e siccome le idee suggerite sono parecchie, sono parecchio disorientato. Per questo vorrei porre un po' di paletti.
Partiamo dal risultato finale: uno stepper montato sulla lancetta dei secondi che fa un singolo passo ogni 0.997261 secondi. Il treno di ingranaggi che segue fa spostare la lancetta dei minuti e quella delle ore.
Quindi un controllore Arduino dello stepper e un'interfaccia programmabile che faccia fare 86400 passi in 86164 secondi reali allo stepper. Lo so perfettamente che non esistono stepper che fanno 86164 passi a giro, come mi diceva Lesto. Lo stepper farebbe i suoi 200 passi a giro (in 199.4522 secondi reali), ovvero 430.82 giri in 24 ore siderali.
Non so se l'interfaccia programmabile abbia al suo interno un clock in tempo reale, ma se si potesse controllare attraverso il PC, per esempio, basterebbe un programmino del genere:

mi esprimo tipo VB

for I =0 to 86400 step 0.997261 'secondi reali
' fa fare un passo allo stepper
next I

Si può ricavare qualcosa da questo?

Spero tanto che non mi abbiate abbandonato. Forse ho detto qualche castroneria imperdonabile?
Parziale rettifica: il motore passo/passo ideale dovrebbe fare 6°/passo per avere lo spostamento di 1 secondo siderale ad ogni step del motore, ma anche se fa 1.8°/passo va bene ugualmente perché esattamente ogni 3 secondi siderali farebbe 10 passi e sarebbe anche meglio perché la lancetta dei secondi sembrerebbe ruotare in modo più fluido, a passettini di circa 1/3 di tacca. L'unica cosa che non ho la più pallida idea di come risolvere è quella di far fare uno step al motore ogni 0,2992863 secondi reali. Esiste una scheda di pilotaggio di un bipolare con la possibilità di programmarla in modo da ottenere un clock del genere?

Grazie mille.

Non ti abbiamo abbandonato ma di suggerimenti te ne abbiamo dati, sta a te ora trovare il sistema per risolvere il problema.
Di mio posso aggiungere che con il timer 1, che è un timer a 16 bit, potresti avere un sistema per avere un incremento dei secondi siderali ogni 0,99725754176s
Ciò porta ad una durata del giorno siderale di 86163,05s al posto di 86164s, quindi una differenza di 1 secondo/24h.

Basta che imposti il timer in modalità CTC con tetto massimo fissato da OCR1A a 8021 e prescaler a 1.
Difatti (16000000/2/1/(8021+1))=997,25754176 Hz. Intercetti la relativa ISR e dopo 1000 overflow puoi contare 1 secondo siderale.

dunque, se vuoi usare un PC, fai attenzione: molti SO e vecchi sistemi operativi hanno dei timer precisi solo ad centesimo di secondo. (lo so perchè facendo della grafica al PC alle volte tra un'immagine e l'altra capita di dover far aspettare al Thread qualhe millesimo/centesimo di secondo e non si può.

La soluzione di leo è interessante, ma come dicevamo i timer tendono a sballare sul lungo termine (e per un timer lungo termine vuol dire decine di minuti), però ecco, un sistema leo + un RTC (che poi usi il PC come RTC è una tua scelta).

la cosa diventa un poco complessa, a solo lato matematico non programmazione.
tu avresti l'RTC (che poi sia il PC chissene), che ogni secondo invia un impulso. chiamiamolo RTC

quando ti arriva un impulso, salvi il valore di micros() in una variabile, lastRTC per esempio.
Quando l'utente preme su "start" salvi il valore attuale di micros() meno lastRTC (ovvero il numero di microsecondi di sfaso tra il secondo reale e il secondo siderale, chiamamiamola sfasoRTC), setti a 0 una variabile che conta i secondi RTC (chiamaiamola secRTC).

poi fai la durata di un secondo in micros (6.000.000) meno sfasoRTC e ottieni quanti microsecondi ci rimangono entro il prossimo interrupt RTC (chiamiamo missingRTC)

ora avreai precalcolato quanto microsecondi RTC equivalgolo and un microsecondio SID (siderale): 997.261 (SIDinRTC)

ora calcoli il numero di SID che devono trascorrere fino al prossimo interrupt RTC: missingRTC/SIDinRTC = missingSID

ora semplicemente fai un for da 0 a missingSID che incrementa uno step il motore (che saranno 86400) e poi si mette a nanna per SIDinRTC microsecondi.

poi a questo punto, finito il for, devi ricalcolare lo sfaso di missingRTC, però ora devo andare, vediamo se riesci a concludere da solo...

Ma in pratica tutto questo è un modo per usare l'RTC per rimanere allineati con i Timer.

ps. @leo: sul tuo github si discute per modificare la swRTC, sarebbe gradito un tuo intervento :slight_smile: