Vamos a realizar un programa con servo y potenciómetro, lo primero que debemos saber es qué es un potenciómetro. Un potenciómetro no es nada más que una resistencia variable cuyo valor es proporcional al ángulo de giro o carrera si tratamos con potenciómetros lineales . Existen otros tipos que no son necesariamente proporcionales, como son los logarítmicos, pero no vamos a ser tan tiquismiquis.

Este elemento electrónico nos permite simular la acción de un sensor y que podemos manipular nosotros mismos. Esto nos es muy útil para hacer pruebas de nuestro sistema y depurar el código con otros elementos que dependan de variables externas y para tratarlo con una placa Arduino vamos a presentar los valores que toma nuestro potenciometro desde el Serial Monitor.

Lo primero que debemos saber es que los potenciómetros poseen 3 patillas. Las 2 que suelen estar juntas o las exteriores son la alimentación y tierra. Da igual cuál de las dos es cuál porque al ser una resistencia su modo de operación no depende de el sentido de la corriente. Y la patilla intermedia es la que proporciona valores de tensión entre 0 y el valor de alimentación. Podemos considerar este valor como un porcentaje de la tensión total que será leido a través de un pin analógico de la placa y ésta lo representará en pantalla. Aquí se puede observar el modo de conexión.

Arduino_pot

 

Por cierto, el potenciómetro del dibujo es de los caros. Para este tipo de aplicación hay unos mucho más baratos que pueden costar 20 céntimos. La diferencia reside en que los caros tienen una manivela para variar el valor de la resistencia fácilmente y los pequeños hace falta un destornillador para manipularlo… y si no, con un palillo.

PotentiometerpotRes

 

 

/* Lectura analogica con potenciometro
 * ----------------------------------- */

int potPin = 2; /* seleccionamos pin para el potenciometro*/
float val=0;
float value;

void setup() {
   /* los pines de entrada analógica
no es necesario configurarlos*/
   Serial.begin(9600);
   Serial.println("Potentiometer");
}

void loop() {
   val = analogRead(potPin); /* leemos el valor del potenciometro*/
   value=val/1023;
   Serial.println(value);
   /*Serial.println(PotRange(0,1,value)); *//*print to serial monitor
 to see number results*/
   delay(50);
}

int PotRange(int init, int final,float value){
   int result;
   float aux;
   aux=final-(final-init)*value;
   result = (int) aux;
   return result;
}

A  la hora de comprar, seguramente os preguntarán de que valor queréis que sea la resistencia máxima del potenciómetro. No hagáis como yo que dije un número al azar. Dependiendo de el tipo de aplicación se necesitará una resistencia suficientemente grande que limite la corriente para no petar otros elementos del sistema. Al final opté por coger cinco de variados valores… por si acaso.

Ahora procederemos a usar este potenciómetro para cambiar el ángulo de un servomotor. Es lo mismo que comenté en un post anterior, pero ahora utilizaremos el porcentaje del valor del potenciometro para introducirlo a la función Write() o WriteMicroseconds() de la librería de servomotores.  Fijaos bien que he creado una función que opera en un rango definido para estas funciones y que su valor es un entero. Hay que tener cuidado porque primero leemos el valor del potenciómetro con la función analogRead()  y Arduino posee un conversor analógico-digital de 10 bits que nos porporciona un valor de 0 a 1023. Por ello lo dividimos como un float para obtener un porcentaje. Pero a la hora de establecer un punto intermedio de un rango lo pasamos a entero.


#include <Servo.h>
int potPin = 2; /* seleccionamos pin para el potenciometro*/
Servo myservo1;
float val=0;
float value;

void setup() {
   /* los pines de entrada analógica
no es necesario configurarlos*/
   Serial.begin(9600);
   myservo1.attach(6); /*the pin for the servo control*/
   Serial.println("Potentiometer");
}

void loop() {
   val = analogRead(potPin); /* leemos el valor del potenciometro*/
   value=val/1023;
   Serial.println(PotRange(700,2300,value)); /*print to serial monitor
 to see number results*/
   myservo1.writeMicroseconds(PotRange(500,2300,value)); /*set servo position*/
   /*Serial.println(PotRange(0,180,value));*/
   /*myservo1.write(PotRange(0,180,value));*/
}

int PotRange(int init, int final,float value){
   int result;
   float aux;
   aux=final-(final-init)*value;
   result = (int) aux;
   return result;
}

Para utilizar una función u otra solo hay que comentar y descomentar la que queráis utilizar en ese momento.
El resultado obtenido será algo como lo que presento en el siguiente video.

Una cosa que me ha llamado la atención es que el servomotor nos da un tiempo de respuesta aceptable, pero si el cambio de valor es muy rápido o se cambia la dirección bruscamente puede dar algún de problema. Aunque se recupera rapidamente, tiene un fallo asociado a los cambios bruscos de intensidad que lo alimentan y de la misma manera a la placa que pierde la comunicación USB.