top of page

Sortides analògiques (PWM)

Un senyal digital de l'ESP32 només pot tenir un valor de 0V o de 3.3V. Permet activar/desactivar un actuador.

Un senyal analògic de sortida pot tenir qualsevol valor entre 0V i 3.3V.

Permet controlar la intensitat d'iluminació d'una làmpada, la velocitat de gir d'un motor, ... 

ESP_EsquemaDigital.png
prohibido
prohibido
prohibido

Tots els pins que podem fer servir com a sortides digitals poden treure senyals PWM.

A més, l’ESP32 té un controlador amb 16 canals independents que es poden configurar per generar senyals PWM amb diferents propietats.

Pautes de programació

En inicialitzar el PWM, cal especificar:

el canal, la freqüència i la resolució de la conversió DA:

ledcSetup (canal, freqüència, resolució);

Cal inicialitzar el pin PWM a utilitzar:

ledcAttachPin (GPIO, canal);   

 

Especificació de la sortida PWM (pel canal, no pel GPIO):

ledcWrite (canal, valor PWM);

Comprovem-ho. Encesa gradual d'un led

Es tracta de treure un senyal PWM pel pin de connexió del led (5) i anar augmentant el seu valor des de 0 fins al màxim (255).

Com més gran sigui aquest valor, més alta la tensió i més s'il·luminarà el LED.

// valors amb que treballarem:

const int LedPin = 5;  // GPIO per on sortirà el senyal PWM

// propietats del senyal PWM:

const int frecuencia = 5000;   // cal definir la freqüència del tren de polsos. Per controlar la il·luminació d'un LED utilitzem 5000 Hz

const int canal = 0;                // cal definir el canal. N'hi ha 16, de 0 a 15

const int resolucio = 8;           // resolució de 8 bits vol dir que podem controlar la lluentor del led mitjançant un valor PWM de 0 a 255

int PWM = 0;                         // valor inicial del senyal PWM (led apagat)

void setup ()   
{ 
  ledcSetup (canal, frecuencia, resolucio);  

  ledcAttachPin (LedPin, canal);  
}

void loop ()    

  ledcWrite (canal, PWM);   // treu el senyal especificat ...
  delay (500);                   // durant 500 ms 

  PWM = PWM + 5;           // assignem nou valor al senyal PWM

Millorem-ho ...

Quan el PWM arrivi al seu valor màxim (255) cal que no continui pujant. Un parell d'opcions i diferents maneres d'implementar-les:

void loop ()
{

  if (PWM <= 255)  // quan el led arrivi a la màxima lluentor, el senyal es mantindrà constant

  {

    ledcWrite (canal, PWM);   // treu el senyal amb el valor especificat 
    delay (500);  // durant 500 ms 

    PWM = PWM + 5;  // nou valor del PWM

  }

  // com que ja no es cumpleix la condició, PWM deixarà de pujar i es mantindrà constant

void loop ()
{

  if (PWM <= 255)  

  {

    ledcWrite (canal, PWM);   // treu el senyal amb el valor especificat 
    delay (500);  // durant 500 ms 

    PWM = PWM + 5;  // nou valor del PWM

  }

  else

  { PWM = 0; }  // quan el led arrivi a la màxima lluentor, el senyal tornarà a 0

If vs If - Else

Podem comprovar el funcionament d'aquestes propostes monitoritzant el valor del senyal PWM.

 

Si volem veure les dades en format gràfic ...

Plotter.png

Serial.println (PWM);

Serial2.png
PlotetrMenu.png

Dimmer continu

Fem que quan el PWM arrivi al màxim, s'inverteixi el comportament

del led, es vagi apagant gradualment.

void loop ()
{

  while (PWM <= 255)  // mentre es cumpleixi la condició ...

  {

    ledcWrite (canal, PWM); 
    delay (500);

    PWM = PWM + 5;    // augmenta el valor del senyal

  }

  while (PWM >= 0)  // mentre es cumpleixi la condició ...

  {

    ledcWrite (canal, PWM); 
    delay (500);

    PWM = PWM - 5;    // disminueix el valor del senyal
  } 

void loop ()
{

  for PWM = 0; PWM <= 255; PWM PWM + 5)

  {

    ledcWrite (canal, PWM); 
    delay (500);

  }

  for PWM = 255; PWM >= 0; PWM PWM - 5)

  {

    ledcWrite (canal, PWM); 
    delay (500);

  }

Plotter1.png

While vs For

Si volem monitoritzar o graficar el valor de la tensió resultant:

Serial.print ((3.3 * PWM) / 255);

Serial.println ("  V");

Obtinguem el mateix senyal en diferents pins

Modifiquem l'exemple anterior per controlar 3 leds utilitzant el mateix senyal PWM pel mateix canal ... Potser un led RGB?

Com que la sortida del PWM (ledcWrite) es defineix pel canal, no pel pin, només cal afegir els nous leds a la configuració (setup).

// valors amb que treballarem:

const int LedPin1 = 5;  // GPIO per on sortirà el senyal PWM

const int LedPin2 = 18;  // GPIO per on sortirà el senyal PWM

const int LedPin3 = 19;  // GPIO per on sortirà el senyal PWM

// propietats del senyal PWM:

const int frecuencia = 5000;     // cal definir la freqüència del tren de polsos

const int canal = 0;                  // cal definir el canal. N'hi ha 16, de 0 a 15

const int resolucio = 8;            // resolució de 8 bits vol dir que podem controlar la lluentor del led mitjançant un valor PWM de 0 a 255

int PWM = 0;                          // valor inicial del senyal (led apagat)

void setup ()   
{ 
  ledcSetup (canal, frecuencia, resolucio);  

  ledcAttachPin (LedPin1, canal);  

  ledcAttachPin (LedPin2, canal);  

  ledcAttachPin (LedPin3, canal);  
}

void loop ()    

  ledcWrite (canal, PWM);   // treu el senyal especificat
  delay (500);  // durant 500 ms 

  PWM = PWM + 5;  // assignem nou valor al PWM

L'efecte d'aquest programa:

Tots tres LED augmenten i disminueixen la lluentor simultàniament, produïnt un efecte sincronitzat.

bottom of page