ESp32 y los servos

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

    Montando un servo simple con ESP32

     

    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 un par de servos. Así que cogí un viejo tuto de esta página con el servo.h y me puse a jugar con el programa típico para mover un pequeño servo.

    La primera en la frente. En cuanto me puse a jugar con el asunto el compilador me informó amablemente, de que la librería Servo.h no es compatible con el ESP32… ¡Mal empezamos!

    ATENCIÓN: la librería Servo pretende ejecutarse sobre arquitectura(s) 
    avr, megaavr, sam, samd, nrf52, stm32f4, mbed, mbed_nano, mbed_portenta, 
    mbed_rp2040 y puede ser incompatible con tu actual tarjeta la cual corre sobre 
    arquitectura(s) esp32.

    Vale, Revisando un poco la información que corre por ahí, 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

    Como soy vago, pensé que alguien más habría tenido este problema, por lo que me puse a buscar una librería especifica (Que afortunadamente siempre ha preparado algún alma bondadosa). Pero como también tenía que mover los motores que os comentaba más arriba me puse a investigar el tema de la modulación de pulsos, ya que es la parte común a servos y regulación de motores con mi micro favorito.

    Rápidamente encontré que el tema podía complicarse bastante y he tenido que hacer un mini master sobre el tema, de servos por un lado y modulación de pulsos PWM con el ESP32, y el tema no va a dar para unos pocos tutoriales, pero vamos a empezar por lo más sencillo: Manejar un servo con el ESP32, una librería y cuanta menos complicación mejor. Vamos a ello

     

    Estudiando tu servo

     

    Para empezar, vamos a hacer algo que generalmente nadie hace: Leer el manual del servo SG90 que seguramente habrás usado más de una vez. Puedes descargarlo de aquí para el SG90. o por ejemplo para  cualquier otro que tengas en internet.

    Si miramos el manual del SG90 nos dice que, la frecuencia base de la señal PWM debe ser de 50 Hz, es decir, que el pulso que tenemos que modulas es de 1/50 = 20 ms, pero que DutyCycle debe moverse entre 1 y 2 ms (Es decir que no usamos todo el ancho del pulso base si no solo una parte)

    Fíjate en el párrafo de arriba donde te dice un pulso de 1ms, corresponde a todo a la izquierda. 2 ms es todo a la derecha y un pulso de 1,5 ms coloca el servo en la posición central (90º). El manual nos indica que debemos usar una frecuencia base de 50 Hz y que la modulación debe moverse en 1 y 2 ms (milisegundos)

  • Con mucha frecuencia los servos que usamos no son los MGS90 oficiales sino replicas chinas de dudosa procedencia. Eso significa que cada fabricante que hace un supuesto clon de la versión oficial le da… ¿Cómo decirlo? Su propia impronta
  • Es decir que puede pasar que tengas que variar esos valores de tiempos de la réplica, ya que puede que a cada chino se le ocurra cambiar los valores oficiales. No es grave pero como no vas a encontrar un manual razonable, tendrás que ir probando valores.
  •  

     

    Servo simple con el ESP32

     

    Si solo quieres mover un servo y no complicarte mucho la vida, puedes usar la librería Esp32Servo y el programa se parecerá bastante al que harías con nuestro venerable Arduino UNO, pero para ello tienes que descargar la librería que comentábamos más arriba: Esp32servo.h y la buena noticia es que está en el administrador de bibliotecas:

    Escribe esp32servo en la línea de búsquedas y te saldrán dos librerías. Una, la primera que es la que nos interesa, y otra para manejar servos de 360º que hoy no es la que queremos. Pulsa el botón de instalar y enseguida la tendrás lista:

    esp32servo en las bibliotecas de arduino

    Ahora tendrás una sección de ejemplos nueva con el nombre de la librería y varios programas disponibles, pero podemos empezar por el ejemplo Sweep (Barrido). Vamos a ver qué hace:

    La primera línea tiene que ser incluir la librería en tu programa:

    #include <ESP32Servo.h>

    La segunda línea es como con la librería de Arduino, crear una instancia de la clase Servo:

    Servo míservo;

    Y luego definimos el pin al que conectamos el control del servo, en mi caso el pin 4:

    int servoPin = 4;

    Hasta ahora, ninguna novedad, pero en el setup sí que vamos a hacer algo más extraño, que merece una pequeña explicación:

    ESP32PWM::allocateTimer(0);

    Esta línea, en principio asigna uno de los 16 Timers de los que dispone el ESP32 y aunque no es del todo imprescindible (Puedes probar a no ponerla y probablemente te funcionará igual) pero el manual recomienda incluirla.

  • No tengo mucho interés de enfangarnos ahora mismo con el asunto de los timers para manejar servos. Mas adelante le dedicaremos una sesión especifica al tema, pero por ahora pasaremos de puntillas a fin de que el manejo del servo sea lo más simple posible.[/fancy-ul] [/three-fourth]
  •  

    En los Arduinos, hasta donde yo se sé, no podemos tocar la frecuencia base de la señal PWM (Y normalmente ni siquiera sabemos cuál es ¿Te habías dado cuenta?) pero en los ESP32 sí que tenemos que saberlo. Baste por ahora decir que para la mayor parte de los servos sencillos que vamos a usar con nuestros Arduinos y ESP2 necesitan una frecuencia base de 50Hz.

  • En realidad, hay que leer el manual del servo, que es algo que apostaría algo a que no vais a hacer, por lo que en principio los 50 Hz van bien para los servos SG90 y similares e incluso algunos hermanos mayores de más potencia..[/fancy-ul] [/three-fourth]
  •  

    Y esa frecuencia la establecemos con esta instrucción:

    myservo.setPeriodHertz(50);

    Y ahora ya podemos hacer el Attach (Conexión del servo) al pin que definimos arriba, con alguna diferencia:

    myservo.attach(servoPin, 1000, 3000);

    El Servopin no tiene dudas, pero los dos valores posteriores son los valores mínimos y máximos, en µs (Micro segundos) que especifique el manual del servo para sus límites. Aquí he usado un par de valores aprox que podéis hacer variar para encontrar el límite de tu servo.

  • Si no te van bien siempre puedes ir cambiándolos e ir  afinando.[/fancy-ul] [/three-fourth]
  •  

    void setup()
    { ESP32PWM::allocateTimer(0);
    
      myservo.setPeriodHertz(50);    // standard 50 hz servo
      myservo.attach(servoPin, 1000, 2000); //
    }
    
    El resto es lo habitual con cualquier servo:
    void loop()
    {    for (pos = 0; pos < 180; pos ++ )
        { myservo.write(pos);
          delay(10);
        }
    for (pos = 180; pos > 0; pos-- )
        { myservo.write(pos);
          delay(10)
         }
    }

    Si pruebas este programa veras que tu servo empieza a moverse de un lado a otro siguiendo el programa. Si todo lo que quieres es mover un servo, no necesitas complicarte mas la vida y con una variante del programa Sweep podrás hacerlo y listo.

    Pero para los que vais a por nota, el ESP32 nos ofrece un sistema de control fino de las señales PWM que genera sin necesidad de bajar al nivel de registros del procesador y ese va a ser el tema de la próxima sesión de Prometec.