Cambiare frequenza PWM Arduino Mega

Salve a tutti,chiedo qualche delucidazione per quanto riguarda la il PWM dei pin del Mega.
Allora,devo controllare la velocità di una ventola da PC tramite il pin 45 dell'Arduino Mega,che da come ho letto in giro deve essere collegato al Timer5 e lavorare a circa 490 Hz.
Tra il Mega e la ventola è inserito un ULN per dare più birra all'uscita chiaramente!!..
Il PWM funziona,ma la ventola è parecchio rumorosa,fischietta allegramente!!...mi chiedevo se magari alzando la frequenza di switching il rumore diventasse più accettabile.
Se qualcuno che ha più confidenza di me con Timer e prescaler vari mi da qualche suggerimento come sempre sarò lieto di sperimentare...grazie a tutti

I timer sono preimpostati dal core di Arduino. Per cambiarli devi manipolarli tu.
Perché dici che devi collegare la ventola espressamente al timer 5? Non mi pare che le nuove prescrizioni mediche dicano questo :wink:

Se non sai manipolare i timer, ti consiglio di rivolgerti ad un prodotto già pronto. Ad esempio la PWM Frequency Library:

con questa puoi impostare la frequenza che vuoi per un'uscita PWM

leo72:
I timer sono preimpostati dal core di Arduino. Per cambiarli devi manipolarli tu.
Perché dici che devi collegare la ventola espressamente al timer 5? Non mi pare che le nuove prescrizioni mediche dicano questo :wink:

Se non sai manipolare i timer, ti consiglio di rivolgerti ad un prodotto già pronto. Ad esempio la PWM Frequency Library:
http://arduino.cc/forum/index.php?topic=117425.0
con questa puoi impostare la frequenza che vuoi per un'uscita PWM

Le prescrizioni mediche no, ma è attaccata a quel pin , quindi c'è poco da fare...comunque penso di aver risolto cercando in rete ... Molte grazie comunqie!!

ibbba:
Le prescrizioni mediche no, ma è attaccata a quel pin ,

Tu avevi scritto:

che da come ho letto in giro deve essere collegato al Timer5

Imperativo. "Deve" essere collegato al timer 5 :stuck_out_tongue:

quindi c'è poco da fare...comunque penso di aver risolto cercando in rete ... Molte grazie comunqie!!

La lib che ti ho segnalato agisce su tutti i timer.

leo72:

ibbba:
Le prescrizioni mediche no, ma è attaccata a quel pin ,

Tu avevi scritto:

che da come ho letto in giro deve essere collegato al Timer5

Imperativo. "Deve" essere collegato al timer 5 :stuck_out_tongue:

quindi c'è poco da fare...comunque penso di aver risolto cercando in rete ... Molte grazie comunqie!!

La lib che ti ho segnalato agisce su tutti i timer.

... Come ho detto all'inizio la ventola e' pilotata tramite il pin 45 del Mega,quindi Timer 5 o no??... Comunque ho risolto cambiando il valore di prescaler del Timer in oggetto... Grazie della bacchettata anche se avrei preferito un insegnamento... Su questo forum la,tendenza e' sempre dire: se non sai rivolgiti a qualcosa di preconfezionato,così rimarrai sempre ignorante uguale non imparando nulla di nuovo!!... Mah,va beh

Mi spiace che tu colga le battute come bacchettate.
Sinceramente non mi spiace che tu abbia visto in me una punta di superiorità. Ti ho consigliato una libreria già fatta per semplificarti il compito, non perché non volevo spiegarti le cose. Un timer è una cosa molto complicata da gestire. Se noti sul datasheet ci sono decine e decine di pagine che spiegano come programmarlo. Se ti avessi detto, senza una sola cognizione in merito da parte tua, "devi scrivere il bit CS50 nel registro TCCR5A perché così facendo hai un prescaler di /1024 invece di /1." Avresti capito qualcosa?

Spiegare i timer in un posto non è semplice.

leo72:
Mi spiace che tu colga le battute come bacchettate.
Sinceramente non mi spiace che tu abbia visto in me una punta di superiorità. Ti ho consigliato una libreria già fatta per semplificarti il compito, non perché non volevo spiegarti le cose. Un timer è una cosa molto complicata da gestire. Se noti sul datasheet ci sono decine e decine di pagine che spiegano come programmarlo. Se ti avessi detto, senza una sola cognizione in merito da parte tua, "devi scrivere il bit CS50 nel registro TCCR5A perché così facendo hai un prescaler di /1024 invece di /1." Avresti capito qualcosa?

Spiegare i timer in un posto non è semplice.

Guarda la mia e' una elettronica spicciola, imparata da poca scuola( terza media) ma tanta passione ( ho 40 anni ),basata su pochi calcoli ma un'esperienza diretta fatta di saldatore e stagno da quando ho 10 anni!!... Quindi fai molto bene a sentirti superiore a me ,in effetti ci va ben poco!!.. Comunque negli anni ho imparato l'architettura degli ST6 grazie a Nuova Eetteonica e dei Pic grazie a buon Tanzilli e da un anno a questa parte mi sto dedicando ad Arduino,anche un po' per amor di patria, visto che abito a 20 km da Ivrea e mi piace l'idea dell'open.... In ogni modo un Timer in un micro so cos'è e so cos'è un prescaler,ma leggendo il datasheet ci posso impiegare una vita a capire quale sia il registro che lo governa e cosa va impostato... Ecco perché ho fatto una domanda specifica, non ho presentato un problema generale... Ormai comunque è' risolto,grazie ancora della risposta.

ibba sbagli candeggio,

non solo hai colto male i consigli, poi te ne esci con grazie ho risolto ?
la frase giusta e' "Grazie, ho risolto cosi'..."

@ibba:
ok. quindi se hai già un'infarinatura, allora posso approfondire il discorso.
Sugli Atmel i timer sono ad 8 o a 16 bit.

Fondamentalmente, un timer lo puoi usare in 3 modi:
come contatore: il contatore riparte da zero una volta arrivato al max valore;
in modalità CTC, ossia il contatore viene resettato quando il suo valore raggiunge un registro di confronto;
come generatore di PWM, con diverse modalità: Fast PWM, Phase Correct PWM ecc...

Quello che segue vale per l'Atmega2560 ma con le dovute modifiche anche per tutti gli altri chip.
Un timer è governato da un segnale di clock: ad ogni "colpo" il contatore viene incrementato. Il segnale proviene generalmente dal sistema stesso (è il clock del micro). Può essere usato il clock così com'è oppure tramite un divisore, il "prescaler".
Il prescaler si governa col registro TCCRxB (x è il numero di timer). Nel tuo caso sarebbe stato TCCR5B (timer 5). I flag che lo impostano sono CS50, CS51 e CS52. La loro combinazione varia il fattore di divisione.

Scelto il prescaler, che serve ad avere il range di frequenze, si sceglie la modalità.
Se devi usarlo per generare un segnale PWM si sceglie Fast PWM o Phase Correct PWM. La prima genera un'onda a dente di sega mentre la Phase Correct PWM genera un'onda triangolare, più simmetrica. Si usa generalmente per pilotare motori o simili.
La modaità la imposti tramite il registro TCCRxA ed a volte anche TCCRxB, a seconda di quante modalità gestisce il timer. Facciamo il caso di usare la modalità Phase Correct PWM con top fissato da OCRxA. Questa modalità fa contare il timer finché il valore del suo contatore non raggiunge il valore fissato dal registro OCR5A. Per far ciò si imposta la modalità n° 11 tramite i flag WGM50/51/52/53.
Poi metti nel registro OCR5A il valore a cui invertire la direzione di incremento del contatore.
Una volta fatto questo devi collegare i pin al timer in modo che sia il timer stesso a pilotarne lo stato.
Questo lo fai agendo sui flag COMxAx, COMxBx e COMxCx del registro TCCRxA.
Ad esempio, per far sì che il pin 45 dell'Arduino MEGA cambi stato, bisogna trovare a cosa corrisponde.
Esso è il piedino OC5B, significa che è il canale "B" del timer 5. Quindi si governa con i flag COM5B0 e COM5B1.
Guardando il datasheet si vede che impostando il flag COM5B0 a 1 si fa in modo che al raggiungimento di OCR5A il timer cambi lo stato al pin OC5B.

Ecco fatto. Adesso non resta che mettere il pin in output ed hai il tuo PWM.

leo72:
@ibba:
ok. quindi se hai già un'infarinatura, allora posso approfondire il discorso.
Sugli Atmel i timer sono ad 8 o a 16 bit.

Fondamentalmente, un timer lo puoi usare in 3 modi:
come contatore: il contatore riparte da zero una volta arrivato al max valore;
in modalità CTC, ossia il contatore viene resettato quando il suo valore raggiunge un registro di confronto;
come generatore di PWM, con diverse modalità: Fast PWM, Phase Correct PWM ecc...

Quello che segue vale per l'Atmega2560 ma con le dovute modifiche anche per tutti gli altri chip.
Un timer è governato da un segnale di clock: ad ogni "colpo" il contatore viene incrementato. Il segnale proviene generalmente dal sistema stesso (è il clock del micro). Può essere usato il clock così com'è oppure tramite un divisore, il "prescaler".
Il prescaler si governa col registro TCCRxB (x è il numero di timer). Nel tuo caso sarebbe stato TCCR5B (timer 5). I flag che lo impostano sono CS50, CS51 e CS52. La loro combinazione varia il fattore di divisione.

Scelto il prescaler, che serve ad avere il range di frequenze, si sceglie la modalità.
Se devi usarlo per generare un segnale PWM si sceglie Fast PWM o Phase Correct PWM. La prima genera un'onda a dente di sega mentre la Phase Correct PWM genera un'onda triangolare, più simmetrica. Si usa generalmente per pilotare motori o simili.
La modaità la imposti tramite il registro TCCRxA ed a volte anche TCCRxB, a seconda di quante modalità gestisce il timer. Facciamo il caso di usare la modalità Phase Correct PWM con top fissato da OCRxA. Questa modalità fa contare il timer finché il valore del suo contatore non raggiunge il valore fissato dal registro OCR5A. Per far ciò si imposta la modalità n° 11 tramite i flag WGM50/51/52/53.
Poi metti nel registro OCR5A il valore a cui invertire la direzione di incremento del contatore.
Una volta fatto questo devi collegare i pin al timer in modo che sia il timer stesso a pilotarne lo stato.
Questo lo fai agendo sui flag COMxAx, COMxBx e COMxCx del registro TCCRxA.
Ad esempio, per far sì che il pin 45 dell'Arduino MEGA cambi stato, bisogna trovare a cosa corrisponde.
Esso è il piedino OC5B, significa che è il canale "B" del timer 5. Quindi si governa con i flag COM5B0 e COM5B1.
Guardando il datasheet si vede che impostando il flag COM5B0 a 1 si fa in modo che al raggiungimento di OCR5A il timer cambi lo stato al pin OC5B.

Ecco fatto. Adesso non resta che mettere il pin in output ed hai il tuo PWM.

OK....allora io ho impostato il timer 5 canle B a 61 Hz con:
TCCR5B |= 0x05; ....dovrebbe essere ok giusto?

ibbba:
OK....allora io ho impostato il timer 5 canle B a 61 Hz con:
TCCR5B |= 0x05; ....dovrebbe essere ok giusto?

Ecco... ora mi tocca fare la conversione hex->flag :sweat_smile:

A parte gli scherzi, cerca di usare le costanti identificative dei bit. In questo modo tra 1 mese il tuo codice sarà ancora un libro aperto per te. Diversamente non ci capirai una mazza e dovrai metterti lì a spulciare il datasheet :wink:

Quindi
TCCR5B |= ((1<<CS52) | (1<<CS50));

Prescaler a 1024, però non hai specificato che modalità del timer stai usando. In base ad essa cambia la formula per calcolare la frequenza.