PWM – Pulse Width Modulation

En todo inicio de programador arduino deberemos enfrentarnos con el primero de los malos para pasar al siguiente nivel. Es bastante fácil ganarle y me refiero al servomotor. Los servomotores es un tipo de motor eléctrico de baja potencia muy utilizado en robótica, ya que su control es muy preciso y estable. Las partes de las que consta un servomotor se pueden observar en el siguiente video:

Tipos de servomotor .

Un servomotor es un motor eléctrico que puede controlar la posición o la velocidad según el tipo de motor. Los miniservos  controlan la posición y los servomotores de rotación continua controlan la velocidad.

Todos son iguales, aunque los fabricantes no se pongan de acuerdo en cuales son los colores de los tres cables que requieren para su funcionamiento, en las siguientes imágenes se muestran cuál es cuál. Un cable es el de alimentación a 5 voltios (siempre es el rojo) , otro es tierra (negro o marrón) y el otro es la señal PWM.

 

Servo Cables

Servo color cables

 

 

 

 

 

Lo que más nos importa es la señal PWM (Pulse Width Modulation). Es una señal cuadrada periódica de la que podemos variar su ciclo de trabajo. Este ciclo de trabajo D es el tiempo que esta en alto la señal entre su periodo de actuación. Cuanto más en alto esté, más energía se aporta y más girará el servomotor.

La señal PWM es una onda cuadrada. Esta señal cuadrada solo se transmite a través de unos pines concretos de nuestra placa que son: El pin 3,5,6,9,10 y 11 en la placa Arduino UNO y se pueden identificar facilmente observando el símbolo de la eñe.

Para entenderlo bien, necesitamos transmitir un valor concreto a partir de una salida digital. Si nos acordamos de las entradas y salidas digitales y analógicas. El motor es una salida digital, pero no podemos solamente transmitir un 0 o un 1, sino que tenemos que transmitir valor entre un rango de valores para moverlo a una posición concreta.

Por eso se ha creado este tipo de función. Para hacernos una idea, los servomotores están adaptados para entender cuántos ceros y cuántos unos se transmiten en una señal digital en un periodo definido. A esto se le llama ancho de pulso (pulse width). Cuántos más unos hay en cada periodo, estamos transmitiendo más energía al motor, y eso se traduce en un valor comprendido en un rango.

Arduino ya posee por defecto una libreria específica para servomotores que se llama Servo.h y se incluye en el encabezado del programa.

Existen dos ejemplos que vienen con el software de Arduino. El ejemplo Sweep utilizan la librería para servomotores y para girarlo utilizan la función Write(). Esta función opera solo con valores comprendidos entre 0 y 180, que son los grados de giro del servomotor, que inicializa en 90º como la posición de inicio. Para girarlo a izquierda habrá que aproximarse a 180º y hacia la derecha hay que introducir un número cercano a los 0º.

Como explican en Wikipedia los servos suelen trabajar a 50 hercios, es decir que su periodo de trabajo es de 20 milisegundos. Y la función que nos provee la librería de servo en Arduino es ServoWriteMicroseconds().

En esta función se introduce el valor en microsegundos del pulso que se mantiene en activo. Está definido en un rango de 1000 y 2000. 1500 es el valor neutro, por lo que no gira hacia ningún lado, cuando nos acerquemos a 1000 girará en sentido horario y si nos acercamos a 2000 en sentido antihorario.

Al ejecutar el siguiente código se puede introducir el valor de giro a través de consola (como vimos en el post anterior), y de esta manera probar el funcionamiento para los distintos ángulos. De esta manera podremos controlar desde el teclado del ordenador nuestro servo.


#include <Servo.h>
String readString;
Servo myservo1; /* create servo object to control a servo*/

void setup() {
   Serial.begin(9600);
   myservo1.attach(6); /*the pin for the servo control*/
   Serial.println("Servo Control");
}

void loop() {

   while (Serial.available()) {
      
      if (Serial.available() >0) {
         char c = Serial.read(); /*gets one byte from serial buffer*/
         readString += c; /*makes the string readString*/
      }
   }

   if (readString.length() >0) {
      int number = readString.toInt();

      Serial.println("Servo Position :");
      Serial.println(number); /*print to serial monitor to see number results*/

      myservo1.writeMicroseconds(number); /*set servo position*/
      /*myservo1.write(number);*/
      readString="";
   }
}

Para usar una u otra función solo hace falta comentar y descomentar las funciones write() y writeMicroseconds() e introducir los valores definidos en el rango correspondiente a la función.

Aunque parezca bonito, puede dar problemas para grandes giros, pero si se introducen pequeños desplazamientos angulares el servo responde perfectamente. Seguramente la comunicación se vea afectada por la comunicación con el puerto serie y dé problemas.

Nuestro siguiente paso es controlar el servo mediante un potenciómetro que defina el ángulo de giro.

IMPORTANTE: Todos los servomotores del mercado pueden experimentar vibraciones en los ángulos o 180º. Esto se produce debido a las tolerancias de fabricación y puede acortar la vida de tu motor. Si tu servo vibra en estos ángulos, prográmalos para moverse a un ángulo cercano como o 175º para evitar dichas vibraciones. Recuerda además poner siempre un bloque Esperar tras mover un miniservo ya que si realizas cambios de dirección a gran velocidad puedes llegar a quemarlo. Una pequeña espera después de cada movimiento protegerá al miniservo de movimientos bruscos.