Cuando haya que utilizar un servomotor, se deben tener en cuenta,
un mnimo de factores bsicos a considerar como:
Recorrido de giro o sea, intervalo angular, 0 - 180 grados o 360 grados (giro completo). Velocidad de giro. Par (torque o fuerza) que el servo puede generar. Tamao, peso, coste, etc. Como hemos visto, los servo-motores tienen engranajes reductores integrados y un eje que se puede controlar con precisin. Los servos estndar, permiten que el eje se controle con precisin en ngulos de pocos grados, por lo general entre 0 y 180 grados. Los servos de rotacin continua permiten la rotacin del eje a distintas velocidades. El control de parada, se puede realizar de forma automatizada (soft) o mediante la accin de un pot que permite modificar el ngulo de giro con cierta precisin. Para una descripcin ms detallada debe visitar este sitio. Tambin puede visitar el artculo sobre, cmo trucar un servo conservando la electrnica, en este blog. o trucar_servo_futaba_s3003.pdf, aqu
EJEMPLO 1. Ejercicio-1. Veamos un ejemplo de control de un servo, cdigo que, he tomado de la web de Barragan, he reducido un poco el cdigo, para mi propsito. En este cdigo, se aplica la seal PWM que dirigimos al pin digital 9. Como se puede comprobar no tenemos ningn modo de influir externamente en lo que hace el programa. En l, el servo, gira en un sentido y al llegar al final predeterminado (180), inicia un retroceso hasta volver al punto predeterminado (0), as de simple, no hay ms. El que sigue es el cdigo. Sweep (Barrido) // ejemplo 1 // by BARRAGAN <http://barraganstudio.com>
#include <Servo.h>
Servo myservo; // create servo object to control a servo // a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
void setup() { myservo.attach(9); // attaches the servo on pin 9 to the servo object }
void loop() {
for(pos = 0; pos < 75; pos += 1) // goes from 0 degrees to 180 degrees { // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } for(pos = 75; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees { myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } } En el cdigo de barrido, porque se trata de un barrido, como el limpia parabrisas de un coche. Un recorrido en un sentido y acto seguido cambia el sentido y hace otro barrido o recorrido. Con la seal PWM se controla el punto de ajuste de posicin, no la velocidad. En el cdigo, el punto de ajuste de posicin (pos) cambia en un grado cada 15 milisegundos. No tiene mucho sentido un cambio mayor de 15 milisegundos, porque el perodo PWM, base de los servos es de unos 20 milisegundos. Para controlar la velocidad del barrido, se necesita controlar la rapidez con que cambia el punto de ajuste. Por ejemplo un incremento de 3 grados (pos += 3), har un barrido tres veces ms rpido (naturalmente, sujeto a la velocidad mxima del servo en uso). Por lo tanto, este ejemplo tiene una aplicacin muy concreta y para mi propsito no es exactamente lo que esperaba. Voy a realizar algunos cambios a continuacin. Ejercicio-2. Pretendo aplicar al servo, una salida de Modulacin de Ancho de Pulso y mediante la variacin de una seal analgica (potencimetro), modificar el ancho del pulso, con lo cual variar el ngulo de giro del servo motor. Cdigo. Vamos a controlar el giro de un servomotor conectado a un pin analgico. Mediante la seal analgica del potencimetro, leda por el pin analgico 2 (analogPin), regularemos el ngulo de giro del servo segn el giro del eje del potencimetro. En este ejemplo, para reducir el cdigo, se utiliza la libreraServo.h. /* * potservo.pde * * by V. Garcia <http://www.hispavila.com> * Controlar un servo con Arduino, se utiliza un pot en el pin analogico 2 * el servo se conecta al pin 9 (PWM). * Utilizando Arduino v0018, funciona bien. Si utiliza la ver. 0013, debe * cambiar la librera Servo en Harware/libreries/Servo, para que funcione. */
#include <Servo.h> //include the servo libary
Servo myservo; // crea el objeto servo para control del servo // a maximum of eight servo objects can be created int analogPin = 2; int = 2; // Valor devuelto por el sensor analogico (pot.) int pos = 0; // variable para guardar posicin del servo
void setup() { myservo.attach(9); // attaches the servo on pin 9 to the servo object }
void loop() { analogValue = analogRead(analogPin); myservo.write(analogValue*8/50); // dice al servo la position en variable "analogValue" delay(15); // espera 15ms a que servo reaccione a la posicion } El cdigo anterior es sencillo (si utiliza una versin del IDE Arduino, anterior a la ver. 0018, debe cambiar la librera Servo.h ubicada en las libreras, para que funcione), el valor ledo, entrada del pin 2 (procede del potencimetro), ser convertido en un byte para indicar la posicin del servo. El pin de salida (PWM) es el pin 9, al mover el eje del pot, el servo reaccionar desplazndose en proporcin al total del giro permitido. Si dispone de un servo de giro continuo, haga la prueba, con este cdigo de ejemplo. Observe que, con el eje del pot girado a un extremo, el servo gira en una direccin y cuando pone el eje del pot en el otro extremo, el servo cambia tambin de direccin, girando de forma continua en ambos casos.
Trate de girar el pot lentamente; encontrar un punto en el que el servo se detiene. Reajuste el punto de giro del servo ajustando el potencimetro interno del servo (ver imagen anterior), para hacer coincidir el centro del recorrido del servo e igualar ambos lados de giro. Uf!, espero se me entienda EJEMPLO 2. En los dos cdigos que hemos descrito en el ejemplo anterior, se ha utilizado la librera Servo.h mediante la cual se tiene acceso a los comandos que (aunque, nos es transparente) reducen nuestro cdigo. En este ejemplo, voy a presentar un cdigo que permita el mismo resultado, obtenido en el ejemplo anterior, sin dicha librera. El Cdigo. Hay diferentes opciones para cubrir este tema, algunas versiones utilizan el map(), otras en cambio, utilizan otros medios, el caso es, respetar los parmetros de frecuencia con un perodo de 20ms y la modulacin por ancho de pulso, PWM entre 0'5 y 2'4 ms. Utilizando el cdigo de ms arriba y modificando unos detalles, podemos conseguir mover el eje de un sencillo servo, desde un extremo al otro de su habitual recorrido. El siguiente es el cdigo: Servo potenimetro /* * Pot_Servo.pde * --------- * * Uso de un potenciometro para mover el servo por PWM * * Como el mximo valor de salida del convertidor es 255, el * valor leido del potencimetro, tenmos que vividirlo por 4 * de esta forma podremos mostrar sus valores. * */
int potPin = 2; // selecciona el pin input para el potenciometro int ledPin = 9; // selecciona el pin para el servo int val = 0; // variable para guardar el value del sensor
void setup() { pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT Serial.begin(9600); }
void loop() { val = analogRead(potPin); // lee el valor desde el sensor val = val/4; // convierte desde 0- 1023 en 0-255 analogWrite(ledPin, val); // devuelve el ledPin on Serial.print(val); // imprime el valor devuelto pot por el panel debugger Serial.println(" "); } Servo control Como se puede comprobar, este cdigo es bastante endeble para su uso habitual, necesitamos un cdigo ms robusto, con el cual podamos asegurar el emplazamiento del eje motor del servo en una posicin ms ajustada al eje del potencimetro. Este cdigo que se muestra a continuacin puede servir. * Servo control, con una entrada analgica.
by Tom Igoe additions by Carlyn Maw & Rob Faludi Created 28 Jan. 2006 Updated 10 Jun. 2008 http://itp.nyu.edu/physcomp/Labs/Servo Funciona bien, necesita 2114 bytes */
int servoPin = 2; // pin para control servo motor int minPulse = 500; // posicion Minima servo int maxPulse = 2500; // posicion Maxima servo int pulse = 0; // cantidad de pulsos del servo
long lastPulse = 0; // el tiempo en milliseconds del ultimo pulso int refreshTime = 20; // tiempo necesario entre pulsos
int analogValue = 0; // valor devuelto por el sensor int analogPin = 2; // pin analogico para el sensor
void setup() { pinMode(servoPin, OUTPUT); // Set servo pin como un pin de salida pulse = minPulse; // Set del valor posicion motor para el minimo Serial.begin(9600); }
void loop() { analogValue = analogRead(analogPin); // read the analog input pulse = map(analogValue,0,1023,minPulse,maxPulse); // convert the analog value // para un rango entre minPulse y maxPulse. // el nuevo pulso al servo, si el tiempo de actualizacin (20 ms) han pasado: if (millis() - lastPulse >= refreshTime) { digitalWrite(servoPin, HIGH); // Enciende el motor delayMicroseconds(pulse); // La longitud del pulso establece la posicin del motor digitalWrite(servoPin, LOW); // Apaga el motor lastPulse = millis(); // guarda el tiempo del ltimo impulso } } Los valores mnimo (minPulse) y maximo (maxPulse), sern diferentes dependiendo de su servo motor especfico. Tericamente, deberan estar entre 1 y 2 milisegundos, pero en la prctica 0,5 a 2,5 milisegundos suele funcionar bien. Pruebe diferentes valores para ver qu nmeros son los mejores para usted. Este programa, como bien advierte T. Igoe, utiliza la funcin millis() para no perder de vista cuando fue impulsado el servo por ltima vez. As pues, la funcin millis() con el tiempo, produce un error de desbordamiento (es decir, genera un nmero que es demasiado grande para caber en una variable long) despus de 5 das. Si usted est haciendo un programa que tiene que correr por ms de 5 das, puede ser necesario tomar en cuenta de este dato. MOTOR DC. No entrare a describir que es un motor de corriente continua ya que, este es un conocimiento preliminar que, se supone debe tener el lector, para poder comprender lo que se describe en esta prctica. El motor, girar en el momento que se aplique una tensin de rango adecuado en sus bornes o terminales. Normalmente, los motores tienen una referencia en su cuerpo que nos indica sus caractersticas. QU PODEMOS HACER. Con la capacidad de Arduino, vemos que se pueden controlar dispositivos de bajo consumo, como los LEDs, servos, etc. sin embargo, cuando tratamos de mayores consumos, sobre todo, con cargas con inducciones, como un motor de corriente continua, rels, etc., por precaucin, se necesita utilizar al menos, un transistor externo. Un transistor externo, es increblemente til, con l, se controla una mayor cantidad de corriente con la pequea aportacin de la seal procedente de Arduino. Cuando a un transistor NPN, se le conecta la carga al colector y el emisor a tierra, de modo que aplicamos a la base, la salida de Arduino del pin elegido, podemos mover el motor que girar en proporcin a la seal que le entrega el pin.
CONTROLANDO LA VELOCIDAD. Anteriormente, en un ejemplo, jugamos con el control de brillo de un LED mediante la modulacin por ancho de pulso (PWM), ahora, vamos a utilizar la misma caracterstica, para controlar la velocidad de giro de un pequeo motor de juguete. En el mundo real, vemos girar un motor de parado a mxima velocidad, variando la tensin que aplicamos. En el mundo de la electrnica ocurre lo mismo, se pasa de 0 a 5 voltios y con la informtica se hace, mediante un byte de 0 a 255. Con Arduino, se puede utilizar algo llamado, modulacin por ancho de pulso (PWM), esto se consigue, mediante un A/D de 10bits, se basa en la capacidad de Arduino para operar muy, muy rpido. En lugar de controlar directamente la tensin procedente del pin, Arduino cambiar el pin de encendido a apagado muy rpidamente. Por ejemplo, si ponemos el PWM de Arduino al 50%, vemos una luz tenue, debido a la persistencia de nuestros ojos que, no reaccionan tan rpido como para ver que parpadea, la mitad del ciclo est apagada y la otra mitad del ciclo est encendida. El mismo principio, servir a nuestro propsito que, aplicando un transistor, dotar de una mayor capacidad de carga, al pin de salida que hayamos elegido, para manejar un motor, como podemos comprobar con el ejemplo que muestro a continuacin. Control Motor CC // // Funccion: CC_motor_control_pot // // Utilizar un potenciometro para controlar un motor CC
int ledPin = 9; // LED connected to digital pin 9 int analogPin = 2; // potentiometer connected to analog pin 3 int val = 0; // variable to store the read value
void setup() { pinMode(ledPin, OUTPUT); // sets the pin as output }
void loop() { val = analogRead(analogPin); // read the input pin analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023 // analogWrite values from 0 to 255 } Como puede verse el cdigo utilizado es muy simple, lo que no deja de tener calidad. El valor que entrega el potencimetro es dividido por 4, tratando de establecer una relacin entre los valores ledos y los valores de un byte, de un modo muy simple. Ahora presento un cdigo algo ms elaborado, con el que se obtiene un resultado algo ms preciso: // // Funcin: motor_cc_control_pot // // Uso de un potencimetro para controlar un motor CC
int sensor_pin = 2; int motor_pin = 9; // un pin digital PWM output