Modificare la frequenza del PWM su Arduino e ESP32 ( 50, 100 Hz)

Salve a tutti,
ho la necessità di ottenere un segnale PWM a 100 Hz e con Arduino ho paura che non sia possibile, ho visto che l'ESP32 ha una gestione del PWM molto più versatile.
Non avendo ancora acquistato un ESP32, pensate che la configurazione (vedi codice) sia tecnicamente realizzabile? Il compilatore non mi da alcun problema ma ...
Accetto qualsiasi consiglio.
Grazie a tutti.

const uint8_t DPinPWM = 9;                         // Controllo relè PWM
const uint8_t Can1 = 0;                               // Canale PWM
const double Freq1 = 100;                           // Frequenza PWM

void setup() {
    pinMode(DPinPWM, OUTPUT);
    ledcSetup(Can1, Freq1, 8);
    ledcAttachPin(DPinPWM, Can1);
}

Arduino a 16 MHz ....

// generated by: RTM_TimerCalc -- RuntimeMicro.com
// Timer1  Mode_10_16Bit_Phase_TOP_is_ICR

TCCR1A = 0xA2; // 1010 0010
TCCR1B = 0x10 | 2; // Prescale=8

ICR1 = 10000-0;
OCR1A = (int) (ICR1 * 0.25);
OCR1B = (int) (ICR1 * 0.5);

// UnComment following lines for UNO-NANO Timer-1 Pins 
// pinMode(9, OUTPUT);  // OC1a
// pinMode(10, OUTPUT); // OC1b

// UnComment following lines for 2560 Timer-1 Pins 
// pinMode(11, OUTPUT);  // OC1a
// pinMode(12, OUTPUT);  // OC1b

... ho messo il LINK ad un apposito strumento per generare i PWM ... usalo ! :wink:

Guglielmo

crc57:
ho la necessità di ottenere un segnale PWM a 100 Hz e con Arduino ho paura che non sia possibile, ho visto che l'ESP32 ha una gestione del PWM molto più versatile.
Non avendo ancora acquistato un ESP32, pensate che la configurazione (vedi codice) sia tecnicamente realizzabile? Il compilatore non mi da alcun problema ma ...

Ciao,
non serve chiamare la funzione pinMode() per esp32

#define pwmPin 4

const byte pwmChannel = 0;
const unsigned int pwmFreq = 100;
const byte pwmRes = 8;

void setup() {

  ledcAttachPin(pwmPin, pwmChannel);
  ledcSetup(pwmChannel, pwmFreq, pwmRes);
  
  ledcWrite(pwmChannel, 125);

}

void loop() {

}

Io con ESP32 da prove fatte sono andato senza problemi da 50Hz fino ai 100'000Hz, poi nell'applicazione dove la uso ho 3 uscite settate a 250Hz e una a 25kHz mai avuto problemi.

Attento che c'è un piccolo problema nella risoluzione, ovvero in questo caso che è settata a 8-bit dovrebbe avere 2^8 = 256 posizioni (cioè da 0 a 255), in realtà per avere uscita totalmente HIGH devi dare il valore 256.

Stesso discorso se cambi risoluzione, 2^risoluzione + 1 per avere il pwm al 100%.

Moce993:
Ciao,
non serve chiamare la funzione pinMode() per esp32

#define pwmPin 4

const byte pwmChannel = 0;
const unsigned int pwmFreq = 100;
const byte pwmRes = 8;

void setup() {

ledcAttachPin(pwmPin, pwmChannel);
  ledcSetup(pwmChannel, pwmFreq, pwmRes);
 
  ledcWrite(pwmChannel, 125);

}

void loop() {

}




Io con ESP32 da prove fatte sono andato senza problemi da 50Hz fino ai 100'000Hz, poi nell'applicazione dove la uso ho 3 uscite settate a 250Hz e una a 25kHz mai avuto problemi.

Attento che c'è un piccolo problema nella risoluzione, ovvero in questo caso che è settata a 8-bit dovrebbe avere 2^8 = 256 posizioni (cioè da 0 a 255), in realtà per avere uscita totalmente HIGH devi dare il valore 256.

Stesso discorso se cambi risoluzione, 2^risoluzione + 1 per avere il pwm al 100%.

Grazie, farò tesoro delle tue dritte
Grazie ancora

Ciao Guglielmo,
grazie per le dritte che mi hai offerto e spero di riuscire a utilizzarle per risolvere il mio problema, ho comunque due perplessità:

  1. La modifica della frequenza del PWM cambia per caso la funzionalità di millis()?
  2. Se la funzione millis() non subisce alterazioni allora ti confesso che ho avuto delle difficoltà sul corretto utilizzo del programma RTM_TimerCalc, esattamente alle voci Timer e Mode. Pensavo di utilizzare un Arduino Nano ed avere una precisione da 0 a 255, più che sufficiente per le mie esigenze, per quanto riguarda la frequenza è possibile che debba scendere a 50 Hz. Puoi spiegarmi il significato dei parametri su detti?
    Grazie
    Buona serata
  1. NO, se vedi bene la mia foto ho scelto Timer1, millis() è generata tramite Timer0

  2. Se apri il datasheet del ATmega328P e vai dalla pagina 131 alla pagina 138 trovi le varie modalità di funzionamento con anche dei grafici esplicativi del funzionamento e tutti i vari parametri ... come vedi non è cosa spiegabile in due parole in un post, ma tocca studiarsi il datasheet :smiley:

In ogni caso, come ho già risposto in altro thread, essendo il clock fisso ed i prescaler disponibili pure, non puoi avere una possibilità di scelta nel "continuo", ma hai solo valori nel "discreto" entro un certo range ... ::slight_smile:

Guglielmo

P.S.: Ti allego anche un vecchio documento del nostro "admin" leo72 ...

Timer.pdf (747 KB)

Ah ... quando si quota un post, NON è necessario riportarlo (inutilmente) tutto; bastano poche righe per far capire di cosa si parla ed a cosa ci si riferisce, inoltre, se si risponde al post immediatamente precedente, normalmente NON è necessario alcun "quote" dato che è sottinteso. :slight_smile:

Gli utenti da device "mobile" ringrazieranno per la cortesia :wink:

Guglielmo

P.S.: Ho eliminato io il "quote" dal tuo post qui sopra :wink:

Ecco per un Arduino a 16MHz il 50Hz:

// generated by: RTM_TimerCalc -- RuntimeMicro.com
// Timer1  Mode_10_16Bit_Phase_TOP_is_ICR

TCCR1A = 0xA2; // 1010 0010
TCCR1B = 0x10 | 2; // Prescale=8

ICR1 = 20000-0;
OCR1A = (int) (ICR1 * 0.5);
OCR1B = (int) (ICR1 * 0.5);

// UnComment following lines for UNO-NANO Timer-1 Pins 
// pinMode(9, OUTPUT);  // OC1a
// pinMode(10, OUTPUT); // OC1b

// UnComment following lines for 2560 Timer-1 Pins 
// pinMode(11, OUTPUT);  // OC1a
// pinMode(12, OUTPUT);  // OC1b

... e relative impostazioni nel grafico:

Guglielmo

Grazie Guglielmo,
Forse è meglio che cambio il titolo al post, potrebbe essere fuorviante e non essere d'ausilio ad altri

Ciao