viernes, 27 de marzo de 2015

Termómetro LCD

Termometro LCD


En esta entrada vamos aprovechar nuestro montaje "estrella" del termómetro con un TMP36, para explicar el uso de una pantalla LCD.

Como podeis apreciar en la fotografia la pantalla consta de 16 pins que explicaremos brevemente a continuación.



El esquema de conexiones:


Siendo los pines en orden del 1 al 16, los siguientes:

  1. VSS, o GND
  2. VCC, 5 Volts, (comprobarlo en el datasheet, pues hay fabricantes que usan 3,3V)
  3. Contraste, (llevarlo al puntero de un potenciómetro de 10K para ajustar) 
  4. RS
  5. RW
  6. Enable,
  7. DB0, (de DB0...DB7), se usan para transmisión de datos
  8. DB1
  9. DB2
  10. DB3
  11. DB4
  12. DB5
  13. DB6
  14. DB7
  15. LED+, alimentación positiva para la retroiluminación.( no para todas las pantallas)
  16. LED-, GND para la retroiluminación. 
La pantalla del ejemplo tiene retroiluminación y funciona a 5V. Por tanto el esquema de conexión será el siguiente:



Estas pantallas pueden funcionar con 4 u 8 líneas de datos. Para la aplicación que nos ocupa, y para la mayoría, con cuatro tendremos suficientes.


Para este ejemplo, y otros que seguirán con este tipo de display, usaremos una pantalla compatible con el chipset de HITACHI HD44780. En este ejemplo, usaremos una pantalla de 16x2, es decir, 2 líneas de 16 caracteres cada una.

El motivo de usar este tipo de  pantalla compatible, es el de usar una librería ya creada para el entorno Arduino, que tendremos que llamar con una línea como ésta al principio de nuestro sketch.


#include <LiquidCrystal.h> //libreria necesaria para el uso del LCD


Esta librería facilita enormemente la gestión de la pantalla, y realizar las operaciones más habituales, con unos sencillos comandos. Una vez incluida la librería, deberemos crear una variable para el LCD, definiendo los pines a los cuales la hemos conectado.
Por orden serán, RS, Enable, D4, D5, D6 y D7.

LiquidCrystal lcd(4,5,6,7,8,9);


Por último, y para terminar de configurar la pantalla deberemos incluir en el void setup{} la siguiente instrucción:

lcd.begin(16,2);

Esta instrucción configura nuestra pantalla LCD de 16 columnas y 2 filas, definida previamente como variable lcd.

Veamos ahora algunas de las instrucciones que usaremos en nuestro ejemplo. 

   lcd.clear();


Con esta instrucción , borramos el contenido de la pantalla.

 
  lcd.setCursor(0,0);


Sirve para posicionar el cursor donde queremos emplazar el texto. Para colocarlo en la primera línea entre paréntesis usaremos los valores (0,0). Para colocarlo en el inicio de la segunda fila, la instrucción debe ser (0,1).


  lcd.print("Temperatura:");


Escribe el texto entre parentesis. Funciona igual que la instrucción print, escribiendo tal cual el texto que se encuentra entre las comillas .


  lcd.print(Temperatura);


Presenta el valor de la variable Temperatura.

Pues estas son las nociones básicas que deberían ser suficientes para completar esta primera parte del ejercicio propuesto. Si recuperamos de esta entrada, y sustituimos las líneas que muestran el resultado  en el serialmonitor, por las LCD , y configuramos la pantalla, deberíamos conseguir finalizar el ejercicio....

Que no lo conseguimos, de acuerdo  pues os muestro mi propuesta, que podéis descargar desde aquí.


/* Ejemplo practico para mostrar la temperatura de un TMP-36
en una pantalla LCD. La explicacion necesaria la encontramos
aqui http://arduinopractico.blogspot.com.es
 */
 
#include <LiquidCrystal.h> //libreria necesaria para el uso del LCD

LiquidCrystal lcd(4,5,6,7,8,9);// definicion de los pins conectados al 
// Arduino, por este orden RS, Enable, D4, D5, D6 y D7.

void setup() 
{
  Serial.begin(9600); // Iniciamos puerto serie, solo necesario si usamos PC 
  lcd.begin(16, 2); // Definimos el tamaño de pantalla que usaremos
  lcd.setCursor(0,0);// Posicionamos el cursor enel punto 0
  lcd.print("Arduino practico"); // Imprimimos nuestro logo...usad el vuestro
  lcd.setCursor(0,1);// vamos a la segunda linea
  lcd.print("*Termometro LCD*"); // Y explicamos que haremos
  delay(3000); //Esperamos 3 segundos para dar tiempo a leerlo
  lcd.clear(); // Y borramos la pantalla
}

float temperatura = 0; // Variable para leer la temperatura

void loop()
{
  
  delay(200);
    temperatura = analogRead(0);           // Lectura del TMP36 en pin0
    temperatura = (temperatura*5000)/1024; // Convertimos el valor en milivolts
    temperatura = temperatura-500;         // Restamos el offset de 0.5V
    temperatura = temperatura/10;          // Convertimos los milivolts en º Celsius
    lcd.clear();              // Borramos pantalla
    lcd.setCursor(0,0);       // vamos al inicio de la primera linea
    lcd.print("Temperatura"); // Mostramos el texto temperatura
    lcd.setCursor(0,1);       // Saltamos a la segunda linea
    lcd.print(temperatura,2); // mostramos la  temperatura con 2 digitos decimales
    lcd.print("C");           // la unidad de medida, grados Celsius
    delay(1000);              //
}


Os dejo con unas imágenes del montaje, y del resultado en pantalla que obtendréis.


Y funcionando:



Nos vemos.



miércoles, 18 de marzo de 2015

Trucar servo a giro contínuo

Hola de nuevo. Tal y como adelantaba en la entrada anterior tenía pendiente mostrar como trucar un servo de 180º para que sea capaz de girar continuamente, es decir convertirlo en un servo 360 o de giro continuo.

Mas tarde veremos los pros y los contras de esta operación. Pero primero os presento a la "víctima":


Una vista más de perfil, nos ayudará a encontrar el orden correcto de los piñones. Es muy importante si es la primera vez, realizar varias fotos para que no aparezcan las dudas cuando intentemos montarlo.


La tornillería es especialmente pequeña, por lo que hará falta un destornillador de precisión para poder extraer los tornillo.


Un servo se compone de un motor eléctrico, una reducción de engranajes, un potenciómetro y una placa de control. En esta foto podemos observar las conexiones del motor y la placa de control. Las soldaduras son de mirame y no me toques. Una flexión en el cable o un tironcito de más y tendréis que sacar el soldador para repasarlas. Yo lo tuve que hacer en tres ocasiones.


Momento delicado...

Pues si lo hacemos con cuidado, podremos obtener una foto más del orden correcto de los engranajes. Yo no tuve tanta suerte y los tuve que agrupar para que saliesen en la foto de familia.


Bien, ahora llega el quid de la cuestión. En esta vista tenemos el piñón de ataque del motor ( a la derecha), y el eje del potenciómetro a la izquierda. 


Llegados a este punto hay que decidir si queremos continuar pues el proceso no es reversible. Yo he estropeado un servo para hacer el brico de esta entrada, y el segundo ha quedado operativo al 90%. Funciona pero se calienta en exceso, aunque creo que debe ser inherente al uso para el que no ha sido diseñado.

De acuerdo pues, si habéis reflexionado y decidís continuar, necesitareis un adhesivo no conductor y que no sea fluido. (NO VALE EL LOCTITE, se escurre hacia la pista del potenciómetro y se come el plástico, además al ser conductor si toca pista puede modificar la lectura del cursor). Yo he usado una gota de cola caliente pues tenía una pistola de cola a mano. Un pegamento en dos fases tipo Araldit, también es válido.

También necesitaremos conectar el servo a nuestra placa de Arduino, para cargar el siguiente sketch. El esquema de conexión es este:


Y el programa que debemos ejecutar:


// Programa para fijar el servo en la posicion neutra
// o de 90, quenos permita fijar el potenciometro cuando
// pare el piñon de ataque

#include <Servo.h> 
 
Servo myservo;  // Creamos un objeto servo 
 
void setup() 
{ 
  myservo.attach(9);  // Indicamos en que pin tenemos el servo conectado 
} 
 
void loop() 
{ 
  myservo.write(90); // Fijamos el servo en la posicion 90  
  delay(15);    // Damos tiempo de alcanzar la posicion
                // en este punto movemos el eje del potenciometro
                //hasta alcanzar el paro

El programa sirve para posicionar el servo en su posición neutra o de 90º.

Una vez ejecutado el sketch, el piñón de ataque comenzará a girar. En este momento deberemos girar con los dedos el eje del potenciómetro. Si se nos escurre entre los dedos o no tenemos suficiente precisión, podemos ayudarnos del último piñón que va montado en el eje, que tiene una especie de encaje.

Debemos encontrar la posición del potenciómetro en la que el motor deja de girar. Observaremos que conforme nos acercamos a esta posición el motor gira cada vez más despacio hasta llegar a aparar. En ese punto de equilibrio debemos fijar el potenciómetro con una gota del adhesivo escogido.

Mientras actúa el adhesivo vamos a por el piñón que actúa de tope. Los servos, para no forzar los extremos del potenciometro tiene un tope mecánico que evita movimentos superiores a los 180º. Algunos servos tienen una pestaña en la carcasa, pero en el caso que nos ocupa es un pequeño saliente que hay que cortar antes colocarlo.             
                                                                                                                                     

Una vez eliminado el tope, seguimos trabajando con el mismo piñón. Si observáis el diámetro interior, este tiene una especie de encaje para impedir el giro libre del piñón sobre el eje del potenciometro. Vale, pues hay que eliminarlo, porque lo que ahora buscamos precisamente es permitir que este piñón gire libre sin arrastrar el eje del potenciometro. Para conseguirlo lo mejor es una broca de 1mm. Si no la localizamos, se puede con paciencia y maña eliminarlo con la punta del destornillador.


El resultado final tras la manualidad:


Pues ya lo tenemos. Ahora es momento de revertir los pasos de montaje y ensamblarlo. En algunos casos, como el del servo que nos ocupa los dos ejes son de distinto diámetro, lo que resultará de gran ayuda en el proceso de montaje.

Resumiendo:

- Realiza fotos antes de tocar nada, será de gran ayuda.

- Ojo con dar tirones, por pequeños que sean y vigila también con girar las soldaduras, se parten y sueltan con una facilidad extrema. Ten un soldador y estaño a mano.

- Elige bien el adhesivo  a utilizar, si es conductor o ataca el plástico nos inutilizará el servo.

- Por último si mientras se seca o durante el montaje se desplaza el eje del potenciometro, el piñón volverá a funcionar. Tranquilo, no está todo perdido. Puedes probar a averiguar cual es el ángulo que lo para y anotarlo. Cuando lo uses en algún sketch deberás recordar que este ángulo, y no el de 90 , será el que pare el servomotor.

- Insisto, en el momento en que retires el tope del piñon, el proceso será irreversible.

Suerte si os animais a intentarlo.

Nos vemos!



domingo, 15 de marzo de 2015

Trabajando con servos (II). Termómetro analógico

Hola de nuevo.

Ya vimos el día anterior como mover un servo en función del valor leído en una resistencia. En otra entrada anterior, también vimos como usar un sensor de temperatura.

Bien, pues hoy vamos a montar un termómetro analógico juntando estos dos proyectos.

Antes de nada , para nuestro sketch necesitaremos definir las dos temperaturas extremas que querremos mostrar, nuestro máximo y mínimo. Aquí no os puedo ayudar, no es lo mismo Burgos que Sevilla. Yo he usado un rango que va de -15ºC a +45ºC, aunque reconozco que nunca he visto nada parecido por estos lares.

El circuito a implementar es muy sencillo. Vamos a utilizar un sensor de temperatura TMP-36, y un servomotor, además de nuestra placa de Arduino compatible.

Los conectaremos siguiendo el siguiente esquema:


Un ejemplo de como quedaría en placa:


El sistema que he utilizado para mostrar la temperatura, es un tanto, sencillo, pero nos servirá para la ocasión. Aún es más sencillo como he fijado el servo a la escala de temperaturas, pero este ejemplo tiene solo fines demostrativos.


Y la fijación:



De acuerdo, después de haber demostrado que las artes plásticas no son lo mío, vamos a explicar el sketch que hará que por lo menos el funcionamiento sea correcto.

Antes de nada, deberíamos conocer cuales son los parámetros de tiempo que llevan nuestro servo a su posición de 0º y de 180º. Una ojeada a esta entrada debería ser suficiente para aclarar las ideas.

De todas maneras podeis cargar este programa e ir sustituyendo los valores, valormin y valormax, hasta encontrar los que se ajusten. Recordad cargar el programa, y anotar los valores correctos.


// Programa para encontrar los valores en ms limites de un servo

#include <Servo.h> // instruccion para incluir la libreria en el sketch
 
Servo myservo;  // creamos el objeto servo, para luego controlarlo
 
int valormin=450;  //valor minimo en ms para conseguir los 0º
int valormax=2100; // valor maximo en ms para llegar a los 180º
int grados;
void setup() 
{ 
  myservo.attach(9,valormin,valormax);  // Pin conectado al servo 
} 
 
void loop() 
{ 
  grados=0; //lo llevamos a minimo y observamos si ratea
  myservo.write(grados);       // esta instrucción envía al servo a la 
                               //posición indicada en grados. 
  delay (200);
  grados=180; // lo llevamos al otro extremo y observamos si ratea  
  delay (200);                             
  
  // variar los valores minimos y maximos hasta encontrar los que 
  // se ajusten. Recordad cargar el programa despues de cada cambio
}


Una vez encontremos estos dos valores, podemos proceder a programar nuestro sketch , que quedaría de la siguiente manera:



/* Lectura de temperatura
Con un TMP-36, y repreentacion analogica a traves de un
servo y arduino
 */

#include <Servo.h> 

// Declaración de constantes
Servo myservo; 
const int sensorPin = A0; // Pin conectado al TMP36
float voltaje; //variable para calcular la tensión 
float temperatura; //variable para almacenar la temperatura;
int temperaturamin=-15; // Temperatura mínima de nuestro termometro
int temperaturamax=45; // Temperatura máxima de nuestro termometro

void setup()
{
  // Empezamos la comunicación con el puerto serie
  // para mostrar los valores en el serial monitor
  Serial.begin(9600); 
  myservo.attach(9,465,2200);//,540,2100);  //pin conectado a nuestro servo 

}


void loop(){
  // Leemos el valor de tensión en el pin
  // donde está conectado el sensor TMP36
  int sensorVal = analogRead(sensorPin);

  // Convertimos el valor de la lectura digital
  // en voltaje
  float voltaje = (sensorVal/1024.0) * 5.0;

  // Mostramos el valor del voltaje en pantalla
  Serial.print(", Volts: ");
  Serial.print(voltaje);
  
  // Convertimos el valor de tensión en temperatura
  // en grados Celsius. Para ello usamos la formula
  // explicada en http://arduinopractico.blospot.com.es
  // restando al voltaje el offset de 0.5V que tiene el sensor
  // e incrementando la temperatura en 1ºC por cada 10 mV
  // T = (V-0.5)*100 , siendo V el voltaje leido
  
  Serial.print(", Temperatura en C: "); 
  float temperatura = (voltaje - .5) * 100;
  Serial.println(temperatura);
  
  // Ahora preparamos el dato para mostrar con nuestro
  //servo de forma analogica primero restringiendo el valor
  // de temperatura a los definidos 
  constrain(temperatura,temperaturamin,temperaturamax);
  //Luego mapeamos los valores para mostralos proporcionalmente
  //en el arco recorrido de 180ºC
  
  temperatura=map(temperatura,temperaturamin,temperaturamax,0,180);
  
  //Ttrasladamos el valor al servo en forma de grados
  
  myservo.write(temperatura);
  
  
   delay(1000);
}


El ejemplo es muy parecido a las entradas anteriores, con las siguientes particularidades.

 myservo.attach(9,465,2200);

En esta línea, le decimos al Arduino cuales son los calores correctos que definen los limites de funcionamiento de nuestro servo.

 constrain(temperatura,temperaturamin,temperaturamax);

La temperatura ya aprendimos como calcularla. Pero en esta línea lo que hacemos con las instrucción constriain, es despreciar cualquier valor por encima o por debajo de los definidos en el inicio.

 temperatura=map(temperatura,temperaturamin,temperaturamax,0,180);

Y con esta instrucción hacemos la salida proporcional para que la representación en nuestro termómetro "ardulógico" tenga cierta precisión.



De acuerdo, que el ejemplo es muy sencillo pero muestra la manera de hacer proporcional el movimiento de un servo entre dos valores conocidos y definidos. En la próxima entrada, veremos como "hackear" un servo para que gire 360º.

Nos vemos

martes, 3 de marzo de 2015

Trabajando con servos (I)

Trabajando con servos (I)


Hola a todos. Vamos a introducir un nuevo elemento en nuestro repertorio. Un servomotor, o más comúnmente conocido como servo.

Un servo es un dispositivo electrónico actuador que tiene un eje de rendimiento controlado, el cual podemos ubicar en cualquier posición dentro de su rango de actuación y mantenerlo estable en esa posición. Habitualmente su rango está comprendido entre los 0 y 180 grados.



Como podemos observar, consta de 3 entradas, 5V, GND y señal de control. Dentro de este elemento podemos encontrar un motor de corriente contínua, una caja reductora y una tarjeta de control.

La tarjeta de control será la encargada de realizar el control de la posición del servo, mediante el uso de un controlador proporcional. No vamos a entrar en detalle de que como realiza esa acción, pero podéis encontrar una explicación bastante completa aquí.

Lo que si que nos interesa saber, es que la posición se controla por una señal de onda cuadrada, siendo la duración del nivel alto de la señal el que determina la posición.

Típicamente, aunque depende del fabricante, los valores son de 1ms para el 0º, 1,5ms para el valor central o 90º, y 2ms para los 180º. El tren de pulsos debe permanecer constante para mantener la posición del servo. El tiempo que debe permanecer la señal a 0V no es crítico, aunque no debe superar un valor (nuevamente determinado por el fabricante) para que el siervo no entre en modo de latencia y pierda la posición.

La ondas que debemos generar son del estilo PWM, y deben ser algo cómo esto:




Para realizar nuestro ejemplo montaremos el siguiente esquema:



Que llevaremos a la placa, por ejemplo así:



Y el sketch, pues la propuestas a continuación. La podes descargar desde aquí:


//Ejercicio para pilotar un servo con tren de pulsos
//generados con PWM, desde cualquier pin del Arduino

int pinpot; // pin conectado al potenciometro
int valorpot; // valor leido en el potenciometro
int servo = 9; // pin conectado al servo
int pulso; // Variable usada para generar el pulso de control

void setup()
{
  pinMode (pinpot,INPUT);
  pinMode (servo,OUTPUT);
}

void loop()
{
valorpot = analogRead (pinpot); // lectura del potenciometro
pulso = map(valorpot, 0, 1023, 1000, 2000); //calculamos el valor del ancho
//del pulso en microsegundos, de forma propocional entre los dos valores
//correspondientes a 0 y 180 grados
digitalWrite(servo, HIGH); // activamos el servo
delayMicroseconds(pulso); // durante el tiempo necesario para llevarlo a la posicion
digitalWrite(salida, LOW); // desactivamos el flanco positivo
delayMicroseconds(20000); // tiempo a 0 para generar la seal cuadrada
}


Para el servo que yo utilizo, con valores 1ms y 2ms, no consigo alcanzar los extremos, (0º y 180º) por lo que en mi caso uso 0,550ms y 2,1ms.


Bueno, después de esta pequeña introducción teórica, ¿como generamos ese tren de pulsos de otra forma más sencilla? Pues gracias a una librería creada para el IDE de Arduino, la librería servo.h, el tema es muy sencillo.

Antes de nada, y como es la primera vez que usaremos  librería externas, especificar que se llaman en la primera parte de nuestro programa con una instrucción de este tipo:

#include <Servo.h>

Las instrucciones necesarias para trabajar con servos son:

attach ()


En esta instrucción especificamos el pin donde conectaremos nuestro servo. La sintaxis es la siguiente:

servo.attach(pin, min, max)

Donde :

servo:  indica que se trata de una variable del tipo servo,

pin:      pues eso, el pin donde hemos conectado la señal de control del servo,

min:     es opcional, e indica el ancho del pulso positivo, en microsegundos para la posición de 0                     grados. Si no se indica, usará por defecto 544 microsegundos,

max:   también opcional, indicaría el ancho del pulso positivo para la posición de 180º. Si no se indica, por defecto el valor es de 2400.


Ejemplo 2


Como previo a nuestro proyecto con el termómetro, vamos a adaptar nuestro programa para usarlo con la librería servo.h . Este ejemplo es una adaptación del que podéis encontrar en la web oficial de Arduino, aquí.

El montaje es el mismo que en el ejemplo anterior, y el sketch lo podéis descargar desde aquí.


// Control de un servo a traves de la libreria servo.h

#include <Servo.h> // instruccion para incluir la libreria en el sketch
 
Servo miservo;  // creamos el objeto servo, para luego controlarlo
 
int pinpot = 0;  // pin conectado al potenciometro
int valorpot;    // variable para almacenar la lectura del potenciometro 
int grados; // variable para almacenar la posicion del servo 
void setup() 
{ 
  myservo.attach(9);  // Pin conectado al servo 
} 
 
void loop() 
{ 
  valorpot = analogRead(potpin);        // Leemos el valor del potenciometro entre 0 y 1023
  grados = map(valorpot, 0, 1023, 0, 179); // Lo reescalamos para un valor proporcional de entre 0 y 180grados
  myservo.write(grados);       // esta instrucción envía al servo a la 
                               //posición indicada en grados. 
  delay(15)           // Esperamos que alcance la posición 
}

En este caso , a mi en el valor máximo mi servo "ratea", porque los 2400 son superiores a los aproximadamente 2100, que he comprobado. Por tanto para mi caso, debería sustituir la instrucción attach, por esta:

   myservo.attach(9,540,2100);

Nos vemos en la siguiente entrada para realizar un el termómetro analógico...