Ciao ragazzi, ho cercato per il web esempi per cercare di capire qlks ma non ho trovato niente di quello che mi serve. n pratica io ho un segnale in ingresso di cui io misuro la frequenza, e devo generare un uscita sul pin 11, una frequenza in pwm con duty cycle al 75% con frequenza variabile?Molti in rete parlano di far riferimento ai timer, ma avendo poca dimestichezza con il pwm non so dove mettere le mani. La variazione della frequenza in uscita è determinata dalla frequenza in ingresso, spiego meglio...leggo 30hz in ingresso devo riprodurre 30 hz in uscita...
Confido in un vostro aiuto, grazie
La gestione dei timer e dei segnali PWM non è fattibile con le istruzioni base di Arduino, devi manipolare a mano i registri del microcontrollore.
Ti rimando ad un sito che spiega bene i dettagli:
Ricordati che non tutte le frequenze sono riproducibili da tutti i timer, ad esempio i timer ad 8 bit hanno un range di frequenze più limitato di quello a 16 bit.
leggevo questo articolo
anche se fà riferimento a arduino uno...io ho un arduino micro...cmq ho fatto una prova e genero sul pin 11 una frequenza di 980 hz...
Il Micro ha un chip diverso quindi devi controllare sul datasheet i registri da usare ed i prescaler che hai per ogni timer.
Se usi il PWM di Arduino non puoi cambiare la frequenza ma solo il duty cycle, e la frequenza a fissa a ~976 Hz per alcuni ed a ~490 per altri; per cambiare anche la frequenza devi manipolare i registri come ti ho già detto. Devi armarti di calcolatrice e farti i conti, tieni anche presente la modalità scelta.
io devo riprodurre frequenze che vanno da 0hz a max 50hz!!!
ho fatto alcune prove con il codice che posto sotto...ma niente
void setup() {
void setPwmFrequency(int pin, int divisor) {
byte mode;
if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
switch(divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 64: mode = 0x03; break;
case 256: mode = 0x04; break;
case 1024: mode = 0x05; break;
default: return;
}
if(pin == 5 || pin == 6) {
TCCR0B = TCCR0B & 0b11111000 | mode;
} else {
TCCR1B = TCCR1B & 0b11111000 | mode;
}
} else if(pin == 3 || pin == 11) {
switch(divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 32: mode = 0x03; break;
case 64: mode = 0x04; break;
case 128: mode = 0x05; break;
case 256: mode = 0x06; break;
case 1024: mode = 0x7; break;
default: return;
}
TCCR2B = TCCR2B & 0b11111000 | mode;
}
}
void loop() {
setPwmFrequency(11, 64);
analogWrite(11,77);
}
mi va in errore la riga TCCR2B = TCCR2B & 0b11111000 | mode;
http://forum.arduino.cc/index.php?topic=167655.msg1303328#msg1303328
Dal post indicato scaricati lo zip allegato. Troverai dei documenti che spiegano l'uso dei timer ed il progetto dell'Attiny Punk Console, un generatore di suoni simil-giochi ad 8 bit fatto con un Tiny85. Ovviamente a te serve vedere lo sketch per capire come configurare il timer, modificare i prescaler, ed il contatore che regola la frequenza generata.
Ah, lo sketch è per un Tiny85 ma non avrai difficoltà ad adattarlo all'Atmega328.
ma non riesco a riprodurre quello che mi serve per un semplice fatto la mia frequenza è variabile ma deve essere variabile anche il duty cycle.....Il mio progetto è un tentativo di riprodurre uno strumento che al variare della frequenza onda quadra duty cycle 50% in ingresso emette un segnale di onda quadra in uscita con duty cycle variabile. Ho fatto diverse misurazioni con l'oscilloscopio è ho potuto appurare che con 280 hz in ingresso ho 280 hz in uscita ma il duty cycle cambia...(caratteristica che ho letto del pwm) solo che non sono riuscito a determinare la percentuale....la formula è duty cycle% = (livello alto / periodo) * 100 ma io con arduino il tempo lo devo supporre a 1ms?
ho fatto diverse ricerche e prove, ma non ho capito ancora come e per quanto devo dividere avendo in uscita il pin 11! voi avete qlk idea? ho trovato qst in rete http://letsmakerobots.com/content/changing-pwm-frequencies-arduino-controllers ho provato a dividere x 64 x 32 etc...ma la frequenza rimane sempre la stessa!!!
Il principio è identico per tutti i timer.
Intanto decidi la modalità, così da sapere che formula usare. Rifacendoci alla pagina che ti avevo linkato, scegliamo la FastPWM, la più semplice. Per l'output sul canale A la formula è semplicissima:
Fpwm = Fsys / prescaler / valore_top
La frequenza di PWM è data dalla frequenza del clock di sistema (sull'Arduino sono 16 MHz) divisa il prescaler impostato divisa il valore_top. Valore_top dipende dal tipo di modalità impostata: in FastPWM il top è fissato dal valore massimo del registro ed usi OCRA per regolare il duty cycle; in FastPWM con OCRA come top, invece, per regolare per il duty cycle oppure un top fissato da OCRA ed allora sul canale A il duty cycle è fisso al 50% mentre puoi variarlo sul canale B. Un pò complicato eh ![]()
Facciamo un esempio. Vuoi regolare il timer 2 per i 280 Hz con duty cycle del 75%?
Imposti la modalità del timer su FastPW con top fissato da OCR2A, setti il prescaler a 256, OCR2A a 223 e OCR2B a 167. Output sul canale B, ovviamente, perché altrimenti non posso regolare il duty cycle.
Calcoli:
Fpwm = 16000000 / 256 / (223 + 1) = 279 Hz
Duty cycle = (167 + 1) / (223 + 1) = 0,75 -> 75%
(formule riprese dalla pagina linkata)