ESp32 y los servos II

Objetivos

 

  • Introducción a los servos con el ESP32.
  • Veremos una librería similar a la habitual de arduino.
  • Haremos un pequeño programa. [/three-fourth] [clear/]
  •  

    Material requerido.

     

     

    Detalle de horns  

    Un servo SG90 o MGS995

    modelo esp32 con menos pines Un ESp32
    Tamaño completo Cables y protoboard
    R 33 Kohm   rojo verde amarillo Un par de Leds y resistencias de 220 ?

     

    ESP32 y PWM segundo asalto

     

    Ando estos días liado con un proyecto para un control industrial con un ESP32, en el que tenía que manejar un par de motores con una señal de pulsos PWM y cunado me puse a jugar con ello descubrí, por sorpresa, que, aunque el ESP32 es compatible con casi todo lo que escribas para Arduino… la cuestión de la modulación de pulsos es diferente, y tiene sus propias reglas

    En la ultimia sesion vimos como manejar un servo usando na libreria ad hoc, que es basicamente lo que solemos hacer con nuestros Arduinos UNO y demas familia. Usamos la libreria Servo que viene de serie y nos olvidamos del resto.

    Pero resulta que para ciertas cosas hay que tener un control mas exhaustivo de las propiedades de la señal PWM que vamos a usar para obtener los resultados deseados. Por ejemplo, ya hemos dicho en mas de una ocasion que las señales PWM tienen una frecuencia base y una amplitud para controlar los servos, pero… ¿Alguien sabe que frecuciencia es esa o cuanta anchura de puso podemos usar? ¿No? pues ese es el tema de esta sesion.

    En ella veremos como definir las señales de base que gobernaran nuestras señales PWM a nuestra voluntad cunado usemos un ESP32 que nos permite controlar un poco más la cuestión del PWM y por eso nos vamos a manchar de grasa las manos un poco mas-

     

    ESP32 y la modulación de pulsos PWM

     

    Conviene que fijemos algunas ideas antes de entrar en materia. Por si acaso a alguien no os suena, la modulación de anchura de pulsos o PWM, por sus siglas en ingles (Pulse Width Modulation), es una técnica que permite a un controlador digital puro, que no puede generar señales analógicas, simularlas mediante una onda cuadrada de una frecuencia determinada, a base de hacer que los pulsos cuadrados que genera tengan más o menos anchura.

    O lo que es lo mismo que al variar la anchura del pulso, el porcentaje de corriente que entregamos al chisme analógico al final, se modifica de acuerdo con esa anchura, y un chisme analógico lo percibe como si se tratase de una señal analógica entre 0 y 5V (para una anchura de 0% de pulso y de 100%) a este porcentaje se le llama en inglés Duty Cycle.

    ¿Complicado? En realidad, no. Es una técnica que se usa mucho en la industria con muy buenos resultados. Os pongo aquí un GIF que he tomado prestado de deepblue y que lo muestra muy gráficamente:

    La librería normal de Arduino nos hace casi todo el trabajo cuando estamos con un Arduino UNO o Mega, pero con el ESP32, tenemos que currárnoslo un poco más. Para empezar ¿Qué pines podemos usar para sacar señales PWM?

    Todos los pines que tienen el simbolito ~ pueden proporcionar salidas PWM aunque solo puedes usar 16 a la vez, tenlo en cuenta.  Vamos a hacer un ejemplo variando la intensidad de un par de diodos LED.

    Para poner en marcha un pin PWM en nuestro ESP32 necesitamos poner en marcha algunas consideraciones:

  • ESp32 dispone de 16 canales PWM numerados de 0 – 15. Yo voy a usar 2 por ejemplo el 0 y el 1.
  • Elegir un pin adecuado para hacer el attach al canal de arriba. por ejemplo, los pines 16 y 17 con la instrucción: ledcAttachPin(GPIO_pin,PWM_Ch);
  • Elegir la resolución del canal entre 2 y 16 bits. En esta ocasión voy a ponerlo a 8 bits de modo que tendré 28 = 256 niveles.
  • Podemos elegir la frecuencia base de la señal sobre la que vamos a modular la anchura de los pulsos. Para un led vale con 1000 Hz, aunque muchas veces para operaciones más exigentes suele irse a 5000.
  • Configurar el canal entre 0 y 15 que elegimos mas arriba con la frecuencia y resolución con esta instrucción: ledcSetup(PWM_Ch, PWM_Freq, PWM_Res);ç
  • Ahora ya podemos cambiar el dutyCycle con la instrucción:
    ledcWrite(PWM_Ch, DutyCycle); 
     
  •  

     

    Poniendo en marcha el ejemplo

     

    Vamos a montar un par de leds conectados a un par de pines del esp32 y para ello podemos hacer un montaje como este:

    Esquema de conexion de ESP32 y PWM leds

    La idea es modificar el brillo de los leds mediante el uso de una señal PWM para variar la tensión que aplicamos. Podemos empezar el programa con algunos defines, para fijar los pines a usar: 16 y 17, los canales 0 y uno de los 16 disponibles y la frecuencia y resolución de la señal

    #define PWM1 16
    #define PWM2 17
    #define PWM1_Ch 0
    #define PWM2_Ch 1
    
    #define Resolution  8
    #define Freq  1000

    Pasamos al setup, donde haremos el attach de los pines elegimos a los canales correspondientes:

    void setup() 
    {    ledcAttachPin(PWM1, PWM1_Ch);  // (GPIO, PWM channel = 0 )
         ledcSetup( PWM1_Ch, Freq,Resolution) ;   // (PWM channel, Freq, Resolution)
         ledcAttachPin(PWM2, PWM2_Ch);  // (GPIO, PWM channel = 0 )
         ledcSetup( PWM2_Ch, Freq,Resolution) ;   // (PWM channel, Freq, Resolution)
    }

    Ahora en el loop solo nos queda hacer un ciclo de subida y bajada desde el valor máximo del DutyCycle (255 ) hasta el 0, apagado y luego al revés para que vuelva alcanzar el máximo brillo, pero como soy vago, voy a elegir hacer un solo ciclo que haga las dos cosas:

    void loop()
    { int DutyCycle = -255;
      while( DutyCycle < 255)
           { ledcWrite(PWM1_Ch, abs(DutyCycle)) ;
             ledcWrite(PWM2_Ch, abs(DutyCycle++));
             delay(10);
           }
    }

    Si te fijas, al hacer variar Dutycicle entre -255 y 255 toma los valores que queremos, pero no podemos pasar un valor negativo al led por lo que usamos la función abs() para calcular el valor positivo. De ese modo, la variable se mueve entre 255,254,253……2,1,090,1,2,3…255

    Después usamos ledcWrite para mandar el valor del ancho de pulsos a cada uno de los dos canales que hemos definido y eso es todo

    Aquí os dejo el programa completo; ESP32_PWM_II

     

    Un último comentario

     

    EL ESP32 solo nos permite 16 canales diferentes para generar señales PWM, pero en realidad tiene 28 pines capaces… ¿Por qué? Bien, la limitación de los 16 canales viene porque utiliza dos grupos de 8 canales usando 4 timers por cada grupo. Si echamos una ojeada a la documentación, veremos que el esquema es así:

    Eso hace en cada grupo podemos modificar la frecuencia de los 4 timers como queramos….pero solo hay 4 timers y eso significa que no podemos producir mas que 4 frecuencias para los 8 de cada grupo (Y los mismo para el otro grupo)

    No tiene porque ser grave, por dos razones:

  • Primero, porque con el IDE Arduino no podemos elegir la frecuencia de base (¿A que no te habías enterado?), así que hasta ahora, probablemente no te habías leído la documentación para poder hacerlo a bajo nivel y no lo habías echado de menos.
  • Y segundo, porque, aunque solo podemos generar 4 frecuencias diferentes por grupo, los que nos da 8 frecuencias, en principio podemos asignar mas de un pin al canal en cuestión.  
  •  

    Esto significa que puede usar uno de los canales, el 0 por ejemplo y asignarlo a mas de un pin. Por ejemplo, si en el setup cambiamos este par de líneas:

    ledcAttachPin(PWM1, PWM1_Ch);  // (GPIO, PWM channel = 0 )
    ledcAttachPin(PWM2, PWM1_Ch);  // (GPIO, PWM channel = 0 )

    Fíjate que hemos asociado ambos pines al mismo canal PWM1_Ch, lo que significa que comparten la frecuencia y por tanto si os pusiera el video del resultado no notarias la diferencia con el código de más arriba.

    El ESP32 nos permite 28 pines PWM (Si no recuerdo mal) sin problemas siempre y cuando la frecuencia base para cada uno no tenga mas de 8 valores diferentes, De hecho, podríamos un solo canal para los 28 pines siempre y cuando la frecuencia fuera la misma para todos ¿Qué te parece?