desktop

Uso de PWM en esp32 Arduino

Saludos amables compañeros de foro:

Hoy les comparto que derivado de aceptar una actualizacion de las tarjetas ESP32 (3.0.1) dentro del ambiente Arduino (2.3.2); en la compilacion de un codigo que venia usando desde hace tiempo, ahora comenzo a arrojarme un error de compilacion, el error es el siguiente:

"
D:\Datos\Documents\Arduino\OPTO_HIVEGENIE_v1_13_febrero_2023\OPTO_HIVEGENIE_v1_13_febrero_2023.ino:105:3: error: 'ledcSetup' was not declared in this scope
105 | ledcSetup(0, 38000, 8);//Configuramos el canal 0 de PWM a 38000 khz con una resolusion de 8 bits que nos sirven para formar la barrera infrarroja
| ^~~~~~~~~
D:\Datos\Documents\Arduino\OPTO_HIVEGENIE_v1_13_febrero_2023\OPTO_HIVEGENIE_v1_13_febrero_2023.ino:106:3: error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
106 | ledcAttachPin(LEDPWM1, 0); //Asignamos AL pin LEDPWM1 del Microcontrolador el Canal 0 del PWM
| ^~~~~~~~~~~~~
| ledcAttach"


EL codigo que solia usar es el siguiente:

C++:
#define LEDPWM1 17 // El PIN 17 Corresponde al LED IR para formar Barrera infrarroja
#define LEDPWM2 16 // El PIN 16 Corresponde al LED IR para formar Barrera infrarroja



void setup() {
//en las siguientes cuatro lineas configuramos y activamos la barrera infrarroja generada por los LEDs Infrarrojos
  ledcSetup(0, 38000, 8);//Configuramos el canal 0 de PWM a 38000 khz con una resolusion de 8 bits que nos sirven para formar la barrera infrarroja
  ledcAttachPin(LEDPWM1, 0); //Asignamos AL pin LEDPWM1 del Microcontrolador el Canal 0 del PWM
  ledcAttachPin(LEDPWM2, 0); //Asignamos AL pin LEDPWM2 del Microcontrolador el Canal 0 del PWM
  ledcWrite(0, 128);//Dejamos el DutyCicle al 50%
}
void loop() {

}

Despues de batallar un rato, pensando que algo andaba mal en mi Entorno, encontre en la pagina de EspressIf que habia cambios importantes en las APIS y por tanto aplicar la migracion del codigo que corresponda, asi que me di a latarea, sin emabargo, no he logrado lo que antes obtenia. ya me desespere y no entiendo cual es mi problema que mas adelante explanare; por esta razon recurro a ustedes para ver si me arrojan algo de luz.

El codigo que ahora tengo y que compila sin errores es el Siguiente:

C++:
uint8_t LEDPWM1= 17; // El PIN 17 Corresponde al LED IR para formar Barrera infrarroja
uint8_t LEDPWM2= 16; // El PIN 16 Corresponde al LED IR para formar Barrera infrarroja

void setup() {


pinMode(LEDPWM1, OUTPUT);
pinMode(LEDPWM2, OUTPUT);


ledcAttach(LEDPWM1, 38000, 8); //Configuramos el canal PWM a 38000 khz con una resolusion de 8 bits que nos sirven para formar la barrera infrarroja
ledcAttach(LEDPWM2, 38000, 8); //Configuramos el canal PWM a 38000 khz con una resolusion de 8 bits que nos sirven para formar la barrera infrarroja
ledcWrite(LEDPWM1, 128); //configuramos el Duty Cycle al 50%
ledcWrite(LEDPWM2,128);//configuramos el Duty Cycle  al 50%

}

void loop() {

}

Ahora explico lo que antes lograba y ahora no:

Tengo conectados dos Diodos LED Infrarrojos en los pines 16 y 17, respectivamente oscilando a 38khz con la finalidad de excitar y formar una barrera infrarroja para unos recpetores infrarojos VS1838B, lo cual funcionaba perfectamente.

Ahora, no logro que los dos Pines (16 y 17) se activen, es decir, tal cual esta el codigo "nuevo"; solo en el PIN 17 detecto la señal de 38khz, sin embargo, si hago un REM a las lineas que corresponden a ese PIN 17, entonces si que obtenlo los 38Kz en el PIN 16. No es un problema de hardware ya que como ya mensione, es una Tarjeta que vengo usando hace años y si paso a otro equipo alterno donde sigo con las versiones anteriores del Core de ESP32, todo funciona bien, con lo que solo se me ocurre que no entendi como migrar mi codigo o hay un BUG en la nueva version.

Nota.- Obviamente en el codigo que les comparto, solo dejo lo correspondiente "encender" la barrera infrarroja y no confundir con todo el proyecto.


Ojala que me puedan ayudar a discernir cual es mi problema, de antemano gracias
 
Adelanto mas informacion con respecto a lo que encontrado.

Tome de la siguiente pagina el ejemplo de LEDC Write RGB example para probar. el codigo es el siguiente:

C++:
/*
  ledcWrite_RGB.ino
  Runs through the full 255 color spectrum for an rgb led
  Demonstrate ledcWrite functionality for driving leds with PWM on ESP32
 
  This example code is in the public domain.
 
  Some basic modifications were made by vseven, mostly commenting.
 */
 
// Set up the rgb led names
uint8_t ledR = 16;
uint8_t ledG = 17;
uint8_t ledB = 2;

const boolean invert = true; // set true if common anode, false if common cathode

uint8_t color = 0;          // a value from 0 to 255 representing the hue
uint32_t R, G, B;           // the Red Green and Blue color components
uint8_t brightness = 255;  // 255 is maximum brightness, but can be changed.  Might need 256 for common anode to fully turn off.

// the setup routine runs once when you press reset:
void setup()
{         
  Serial.begin(115200);
  delay(10);
 
  // Initialize pins as LEDC channels
  // resolution 1-16 bits, freq limits depend on resolution
  ledcAttach(ledR, 12000, 8); // 12 kHz PWM, 8-bit resolution
  ledcAttach(ledG, 12000, 8);
  ledcAttach(ledB, 12000, 8);
}

// void loop runs over and over again
void loop()
{
  Serial.println("Send all LEDs a 255 and wait 2 seconds.");
  // If your RGB LED turns off instead of on here you should check if the LED is common anode or cathode.
  // If it doesn't fully turn off and is common anode try using 256.
  ledcWrite(ledR, 255);
  ledcWrite(ledG, 255);
  ledcWrite(ledB, 255);
  delay(2000);
  Serial.println("Send all LEDs a 0 and wait 2 seconds.");
  ledcWrite(ledR, 0);
  ledcWrite(ledG, 0);
  ledcWrite(ledB, 0);
  delay(2000);
 
  Serial.println("Starting color fade loop.");
 
 for (color = 0; color < 255; color++) { // Slew through the color spectrum

  hueToRGB(color, brightness);  // call function to convert hue to RGB

  // write the RGB values to the pins
  ledcWrite(ledR, R); // write red component to channel 1, etc.
  ledcWrite(ledG, G); 
  ledcWrite(ledB, B);
 
  delay(100); // full cycle of rgb over 256 colors takes 26 seconds
 }
 
}

// Courtesy http://www.instructables.com/id/How-to-Use-an-RGB-LED/?ALLSTEPS
// function to convert a color to its Red, Green, and Blue components.

void hueToRGB(uint8_t hue, uint8_t brightness)
{
    uint16_t scaledHue = (hue * 6);
    uint8_t segment = scaledHue / 256; // segment 0 to 5 around the
                                            // color wheel
    uint16_t segmentOffset =
      scaledHue - (segment * 256); // position within the segment

    uint8_t complement = 0;
    uint16_t prev = (brightness * ( 255 -  segmentOffset)) / 256;
    uint16_t next = (brightness *  segmentOffset) / 256;

    if(invert)
    {
      brightness = 255 - brightness;
      complement = 255;
      prev = 255 - prev;
      next = 255 - next;
    }

    switch(segment ) {
    case 0:      // red
        R = brightness;
        G = next;
        B = complement;
    break;
    case 1:     // yellow
        R = prev;
        G = brightness;
        B = complement;
    break;
    case 2:     // green
        R = complement;
        G = brightness;
        B = next;
    break;
    case 3:    // cyan
        R = complement;
        G = prev;
        B = brightness;
    break;
    case 4:    // blue
        R = next;
        G = complement;
        B = brightness;
    break;
   case 5:      // magenta
    default:
        R = brightness;
        G = complement;
        B = prev;
    break;
    }
}

Lo unico que modifique del ejemplo de la pagina fue asignar los pines que corresponden a mi proyecto, es decir; el pin 16 y 17 (deje el PIN 2 para respetar el codigo para no modificar elejemplo), compile y probe.

Encontre que sucede lo mismo que con mi codigo del post anterior. El PIN 17 si se activa a, el PIN 16 no se activa y el PIN 2 del ejemplo si se activa. Por otro lado cuando viene la secuencia de "Starting color fade loop." ahi si que el PIN 16 hace la secuencia (aunque en dicha secuencia el pin 17 y el pin 2 estan desactivados) con lo que considero que hay un Bug o algo que esta fuera de mi entendimiento.

Hasta ahora mi conclusion es que no puedo dejar activo dos PINES activos con el PWM (Duty cycle) asigando... la Sigo experimentando.
saludos

================================
¡BINGO!

Finalmente lo solucione, de la manera mas estupida a mi pensar....pero asi son las cosas: Asigne un a linea de un delay(1); despues de cada ledcWrite y asi si que funciono.

dejo el codigo final:

Código:
uint8_t LEDPWM1= 17; // El PIN 17 Corresponde al LED IR para formar Barrera infrarroja
uint8_t LEDPWM2= 16; // El PIN 16 Corresponde al LED IR para formar Barrera infrarroja

void setup() {


pinMode(LEDPWM1, OUTPUT);

pinMode(LEDPWM2, OUTPUT);


ledcAttach(LEDPWM1, 38000, 8); //Configuramos el canal PWM a 38000 khz con una resolusion de 8 bits que nos sirven para formar la barrera infrarroja
ledcAttach(LEDPWM2, 38000, 8); //Configuramos el canal PWM a 38000 khz con una resolusion de 8 bits que nos sirven para formar la barrera infrarroja
ledcWrite(LEDPWM1, 128); //configuramos el Duty Cycle al 50% del led LEDPWM1
delay(1);
ledcWrite(LEDPWM2,128);//configuramos el Duty Cycle  al 50% el led LEDPWM2
delay(1);
}

void loop() {



}

Nota.- Todos sabemos que un delay en programacion de microcontroladores es aberrante....pero asi las cosas 🤷‍♂️🤦‍♀️

Saludos al Foro, de cualquier forma dejo abierto el tema a sus comentarios.

¡Felices resultados en sus proyectos!
 
Última edición:
Buen día.
G
racias por compartir la solución. Llegue con el mismo inconveniente, pero sumado con un problema adicional. Ya eh usado la función ledcSetup() en códigos anteriores sin problemas pero siempre en el void setup(). Ahora la quise probar en el Void Loop(), para modificar la frecuencia dependiendo de la señal de un potenciómetro y me encuentro con la modificación de las API.
C
onsulta, sacando de tema la modificación de las API, ¿ Sabes si puedo ejecutar las funciones de "ledcAttach" y ledcWrite" en el Loop?
 
Última edición por un moderador:
Atrás
Arriba