Salve a tutti, per motivi di lavoro, sono sempre costretto a trascinarmi dietro un ingombrante generatore di frequenza a 4 canali.
Vorrei rinunciare a questo ingombrante coso e costruirmi un qualcosina di molto meno ingombrante.
Di seguito ciò che vorrei realizzare:
Arduino Mega / TFT 3 pollici in modalità touch / 4 x 555 e altri componenti.
Vorrei costruirmi un generatore di frequenza con le seguenti caratteristiche:
4 x canali di uscita indipendenti da 0 – 2500Hz con VPP di ca.12 Volt (onda quadra)
L’alimentazione verrebbe presa da terze parti (12V)
Domanda: sapreste consigliarmi su come si fa a creare uno sfasamento di 90 gradi fra il canale 2 e 1, rispettivamente 4 e 3 ?
Si può creare qualcosa in modalità software sull’arduino o sarebbe meglio farlo in modalità hardware ?
Direi con millis() e digitalWrite ...
Poi dipende da precisione ed accuratezza che ti servono.
Hai anche PORTx sempre senza necessità di montare 555
Parli di 12 Vpp ma è diverso il caso fra:
onda quadra fra 0 - 12 V
onda quadra fra -6 - +6 V
Nel primo caso è semplicissimo e ti bastano 4 transistor BJT o MOSFET.
Nel secondo invece c'è qualche complicazione circuitale in più ed in quel caso forse potresti anche considerare di mettere lo sfasamento in hardware.
Ovviamente puoi anche avere frequenze e duty differenti per ogni canale.
Puoi farlo anche con la UNO. O al limite invece della MEGA vai con la DUE che ha il DAC.
Con nessuna delle due, la prima ti limita a non più di 1 ms per ogni cambio di livello il che porta la massima frequenza generabile a poco meno di 500 Hz, la digitalWrite è lentissima e introduce ulteriori errori.
La soluzione è usare il timer a 16 bit come clock programmabile (i timer servono proprio a questo), poi tramite interrupt e accesso diretto ai registri del port si cambiano i livelli logici ed è anche possibile inserire uno sfasamento, perfettamente sincronizzato, tra i vari segnali.
Per dare ulteriori indicazioni è necessario sapere quale precisione serve per queste onde rettangolari e se è necessario anche variarne il duty cycle.
Grazie delle risposte,
In effetti si tratta di onde quadre solo in ambito positivo da 0 a 12 V (duty cycle stabile al 50%)
Per quanto riguarda lo sfasamento tramite arduino, non sono molto preparato in fatto di interrupt e accessibilita ai registri. Devo vedere se trovo un semplice esempio in rete.
Per quanto riguarda la precisione, dovrei rientrare almeno dentro i 0.01% in una frequenza che va da 0 a circa 2200 Hz. (circa +0.3Hz -0.3Hz)
Alla fine è un prototipo che vorrei realizzare, 1 Hz andrebbe anche bene che nel mio caso (lavorando con la velocità) sarebbe un errore di 0.01 km/h prendendo uno sbaglio 1 Hz di sbaglio.
Volevo suggerire qualcosa di semplice, con il millis sei limitato al millisecondo ma c'è anche il micros che ti limita intorno ai 4 microsecondi e magari andare di portx invece che di digitalwrite.
Ma credo di aver "semplificato troppo"
Ma se cerchi 0.3 Hz siamo fuori, almeno con la UNO.
Forse con la DUE...
L'errore introdotto passando da 0.3 Hz ad 1 Hz andrebbe valutato nel complesso, insieme agli altri errori introdotti da tutto il resto del sistema (sensori, metodo di calcolo, ecc.). In ogni caso, anche se è un prototipo, credo sia meglio configurarlo opportunamente.
remino:
A livello HW, sarebbe troppo difficile creare un circuitino che mi sfasa il secondo e quarto canale?
Non è una cosa semplice da realizzare direttamente in hardware, si fa prima a farlo da software anche se la generazione delle frequenze è comunque realizzata in hardware tramite timer.
Ma i quattro canali hanno la stessa frequenza oppure frequenze diverse ? Nel secondo caso non ha senso parlare di sfasamento costante a meno che non siano dei multipli esatti tra loro.
Grazie delle celeri risposte,
Si tratta di 4 frequenze identiche, in pratica due canali con 2 ferquenze cadauno.
Lo sfasamento mi serve per rilevare se il rotabile viaggia in avanti o indietro.
In pratica, mando la prima frequenza e dopo 90 gradi mando la seconda, questo vale per la frequenza 1 e 2 del Canale 1 e frequenza 3 e 4 del canale 2.
@guglielmo: grazie del Link, in pratica posso generare una frequenza con quello sketch indicato ?
Io per non stressare l'arduino avevo optato per i 555.
remino: @guglielmo: grazie del Link, in pratica posso generare una frequenza con quello sketch indicato ?
Io per non stressare l'arduino avevo optato per i 555.
... come avrai notato è di Astro ... che potrà confermarti cosa puoi fare o meno con quel programma appena passa di qui
remino:
In pratica, mando la prima frequenza e dopo 90 gradi mando la seconda, questo vale per la frequenza 1 e 2 del Canale 1 e frequenza 3 e 4 del canale 2.
Se mi confermi che devi emulare due encoder incrementali, quindi ti serve sia lo sfasamento +90° che lo sfasamento -90° per il verso di marcia, CW e CCW, il tutto si fa usando il timer 1 di Arduino che dispone di due uscite O.C. (output compare) e 16 bit di risoluzione.
Usando direttamente con il clock del micro (16 MHz) come input del timer 1 la risoluzione è 87 ns, cosa che permette una risoluzione leggermente inferiore a 1 Hz sulla variazione della frequenza tenendo conto del limite superiore di 2500 Hz.
Tramite il timer 1 ottieni due out distinti che possono essere sia due frequenze diverse sia due segnali con frequenza identica sfasate di +/- 90°, con questi due segnali puoi pilotare i quattro driver a 12V per ottenere i segnali che ti servono.
Grazie Astro,
Confermo tutto cio che hai elencato per quanto riguarda i sensi di marcia.
Proveró il tuo sketch (togliendo al momento l opzione 555), ció che non mi torna è come confluire questa frequenza (elettronicamente) ai 12 V di ampiezza.
remino:
Proveró il tuo sketch (togliendo al momento l opzione 555), ció che non mi torna è come confluire questa frequenza (elettronicamente) ai 12 V di ampiezza.
Lo sketch che ti ha linkato Guglielmo era poco più di un esempio, anche se funzionante, e tocca ricompilarlo ogni volta che si deve cambiare frequenza e senso di marcia, per giunta non ha la risoluzione al singolo Hz perchè basato su delay di microsecondi.
Se non hai fretta posso scrivere un codice migliore con possibilità di cambiare il verso di marcia con uno switch e frequenza tramite un potenziometro.
Grazie Astro, molto gentile.
Aspetterò il tuo sketch, nel frattempo preparo il codice con le variabili da immettere per poter calcolare la velocità, che nel mio caso sono il diametro della ruota, e numero di pulsi provenienti dal disco per calcolare un giro.
Per quanto riguarda lo switch di cambio direzione, avevo in mente di attivarlo tramite il touch del mio TFT, così come l'impostazione della frequenza.
remino:
Per quanto riguarda lo switch di cambio direzione, avevo in mente di attivarlo tramite il touch del mio TFT, così come l'impostazione della frequenza.
Che TFT è che libreria usi ?
Potrebbero esserci problemi di compatibilità per i pin impegnate e le risorse utilizzate.
Dato che usi una Mega, praticamente obbligatoria per quel tipo di display per via del numero di pin richiesti e la quantità di flash, è un attimo sforare i 32k con la libreria UTFT per via dei font, non ci sono particolari problemi.
L'ATmega2560 dispone di quattro timer a 16 bit il che permette di ottenere la gestione indipendente della simulazione di due encoder, ovvero puoi gestire due velocità diverse, con relativo verso di marcia, invece di una sola per tutti e due gli encoder.
Per amplificare i 5V fino a 12V puoi usare piccolo mos logic level N channel con il drain collegato al +12 tramite una pullup da 10k, il segnale proveniente da Arduino sul gate tramite una R da 100 ohm e il source direttamente a GND, poi ti posto il relativo schema.
Vedo di prepararti due funzioni che settano i timer in funzione del verso di marcia e la frequenza desiderata, il tutto viene gestito tramite interrupt O.C..
In pratica una cosa del tipo "Encoder_1(verso, frequenza)", "Encoder_2(verso, frequenza)" che devi usare solo per modificare il segnale emesso su i due encoder simulati, ovviamente avrai due coppie di segnali tra loro sfasati di 90°.