Mega 10bits pwm - modalità pwm

Salve!

Sto cercando di settare sul pin 9 e 10 della Mega2560 un pwm a 10kHz, il massimo permesso dalla dual motor driver Pololu - Dual VNH3SP30 Motor Driver Carrier MD03A. Astro mi ha consigliato l'uso della libreria TimerOne e TimerThree, ma monto una usb host shield della sparkfun https://www.sparkfun.com/products/9947 e decido di leggere due segnali per ogni encoder, MORALE ho liberato dello spazio reindirizzando il pin SS e INT per avere finalmente liberi i pin 9 e 10, legati al timer1, nella mia testa indispensabile per il FastPWM... insomma ho fatto una gran confusione. Ripartendo da zero cerco di capirci qualcosa...

Sempre astrobed, mentre brancolo nel buio, mi consiglia risoluzione a 10bits e frequenza del pwm a 10kHz, il limite della motor driver. A prescindere ho acquistato una mega per problemi di spazio e subito adottata.

Scarto il Timer2 e quindi i pin 9 e 10 perchè la risoluzione massima è 8bits.(Advanced Arduino: direct use of ATmega counter/timers)
Per non fare casino con gli altri timer perchè legati a pin che uso per l'spi o per leggere gli encoder scarto anche timer 1 ,3 e 4.

Per la mega i timer con risoluzione a 16 bit sono 1,3,4,5:

timer 1 for pin 11 12
timer 3 for pin 2 3 5
timer 4 for pin 6 7 8
timer 5 for pin 44 45 46

Il più comodo per me sarebbe quindi il timer 5, anche per una questione di spazio.

Sempre qui Advanced Arduino: direct use of ATmega counter/timers quasi alla fine mostra una tabella con le modalità: Fast Pwm a diverse risoluzioni, phase correct, phase and frequency correct. Perchè per un robot autobilanciante spesso viene scelta la terza modalità? Quale risoluzione prevede?

Sono più propenso a fare a lavorare col timer 5, sempre che sia compatibile con la modalità di pwm scelta, OPPURE (se necessario) sposto gli encoder e uso TimerThree(pin 2 3 5).

Ne approfitto per ringraziare del supporto dato dai ragazzi del forum.

NXT

Scusate se rispondo a me stesso, ma ho fatto passi avanti:

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.

Domani posto il codice.

Come dicevo:

//arduino mega2560 Timer5 
//here is my code where I generate 799,92Hz freq, PWM of 
//75% on OC5B and PWM of 75% on OC5C with clock system, phase & freq correct PWM

int outputB = 45;
int outputC = 44;

void setup()
{
//outputs via timer5
 pinMode(outputB, OUTPUT);  // select Pin as ch-B
 pinMode(outputC, OUTPUT);  // select Pin as ch-C
 
 TCCR5A = B00101001; // Phase and frequency correct PWM change at OCRA
 TCCR5B = B10001;  // System clock
 OCR5A = 10000; // 799,92Hz
 OCR5B = 7500; // 75%
 OCR5C = 7500; // 75%
 }

come posso togliere il clock di sistema a favore di un prescaler che mi dia una frequenza di pwm intorno a 10kHz, che sarebbe il massimo consentito dalla motor driver pololu ?Pololu - Dual VNH3SP30 Motor Driver Carrier MD03A

OCR5A = 800; // pwm a 10KHz
OCR5B = 600; // 75%
OCR5C = 600; // 75%

e la modalità scelta non è la 11 ma la 9

icio:
OCR5A = 800; // pwm a 10KHz
OCR5B = 600; // 75%
OCR5C = 600; // 75%

e la modalità scelta non è la 11 ma la 9

Sulla modalità siamo d'accordo che è la 9, ma non è OCR5A = 1600; per il PWM a quella frequenza?
16MHz/10KHz=1600 no?

1600/2 ..... Prova e vedrai che con 800 va a 10KHz, con 1600 và a 5Khz

icio:
1600/2 ..... Prova e vedrai che con 800 va a 10KHz, con 1600 và a 5Khz

Grazie @icio :slight_smile: