Gestire output in frequenza

Buonasera a tutti,
vorrei gestire la frequenza di uscita di due pin. Ho deciso di utilizzare i pin 5 e 6 che in base alla documentazione hanno una frequenza standard di 488 Hz.
Vorrei iniziare portando la frequenza di uscita a 244 Hz (la metà dunque). Ecco il codice:

void setup() {
  setPwmFrequency(5, 128); 
  setPwmFrequency(6, 128); 
}

void loop() {
  analogWrite(5,255);
  analogWrite(6,255);
}


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;
  }
}

Vorrei avere un'uscita continua (devo avere continuamente quell'output nei due pin a quelle frequenze).
Vorrei sapere se c'è qualche errore nel codice perché sembra non funzionare.

Infine vorrei ottenere una frequenza di 1kHz e quindi dovrei utilizzare un divisore non intero ma avevo letto da qualche parte che ciò forse non è possibile mediante la funzione setPwmFrequency: come potrei fare?

Grazie in anticipo a chi vorrà aiutarmi :slight_smile:

pin 5 e 6 che in base alla documentazione hanno una frequenza standard di 488 Hz.

Non mi pare proprio Link

Pins 5 and 6: controlled by Timer 0 in fast PWM mode (cycle length = 256)

Setting 	Divisor 	Frequency

0x01 1 62500
0x02 8 7812.5
0x03 64 976.5625 <–DEFAULT
0x04 256 244.140625
0x05 1024 61.03515625

Infine vorrei ottenere una frequenza di 1kHz

Usa la funzione tone() Link

Grazie mille: sempre preciso ed esaustivo :slight_smile:

Comunque la funzione tone() sembra molto interessante (non capisco perché in molti link si consiglia la funzione setPwmFrequency(int,int)!)

Infine, è corretto inserire nel loop quelle due righe affinché io abbia continuamente l'output alla frequenza richiesta oppure devo comunque inserire un ritardo (per evitare di "far danni con un uso prolungato") ?

Con la setPwmFrequency() imposti il PWM ( gestito dal relativo Timer ) a quella frequenza.
E’ chiaro che i settaggi sono solo quelli a disposizione.
Considera che i pin 5 e 6 sono quelli usati dal Timer0, e se cambi frequenza poi ti si sballa la delay() e la millis().

Con la tone() generi una frequenza su un determinato pin… e basta, cioè non lo puoi usare con un analogWrite()

Brunello:
Con la tone() generi una frequenza su un determinato pin....... e basta, cioè non lo puoi usare con un analogWrite()

Non ho capito: una volta cambiata la frequenza di uscita di un determinato pin come genero l'output ?

tone(I/O,f,dur) funziona ma, soprattutto impostando certe frequenze, ti rendi conto che ha qualche discontinuità. Forse per farlo funzionare bene bisogna bloccare gli interrupt... Non so.