lunes, 30 de diciembre de 2013

Arduino mostrar temperatura con un DS1820 en un LCD 16x2 I2C

Tras varios días de desesperación ya he conseguiguido echar a andar el DS1820 conectado a un display, este es el codigo que he utilizado:



Código:
/*
Autor: Aitor Martin
Fecha: 28-12-2013
Titulo: Sensor de temperatura DS1820
Placa: Arduino uno
Post: http://aitormartin-apuntes.blogspot.com.es/2013/12/arduino-mostrar-temperatura-con-un.html

Código de dominio publico. Se puede distribuir y modificar  libremente, 
siempre y cuando se mencione al autor y se proporcione un enlace a su web.
*/

#include <OneWire.h> //Configurar bus onewhire de Dallas
#include <DallasTemperature.h>//El ternometro de Dallas DS1820
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // 0x27 es la direccion del LCD 16x2

//Pata por la que van a entrar los datos al Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

void setup() 
  {
  lcd.init();
  lcd.backlight(); //enciende la iluminacion
  sensors.begin(); //Iniciamos la libreria del DS1820
  }

void loop() 
{

  sensors.requestTemperatures(); //leemmos la temperatura del sensor.
  lcd.setCursor(0, 0);
  lcd.print(sensors.getTempCByIndex(0)); 
  lcd.print(" *C");
  delay(3000);
  }



Nota:
A mi a la hora de compilar, las librerias del DS1820 me dierón problemas. Si este es tu caso mira este enlace:

http://aitormartin-apuntes.blogspot.com.es/2013/12/arduino-sensores-ds-1820-y-el-error.html

Arduino sensores DS 1820 y el error WConstants.h

Hace cosa de un par de días que me puse a hacer pruebas con los DS 1820 y no conseguia que me funcionase nada me daba un error el :

Error (TCL 3.7.1 Beta):
Documents/Arduino/libraries/DallasTemperature_371Beta/DallasTemperature.cpp:9:26: 
error: WConstants.h: No such file or directory

De internet me descargue muchas librerias diferentes, pero nada si no era un error, era el otro. Me fui a la que creo que es la web oficial y me descarge la versión TCL 3.7.1 Beta, pero me daba el error que aparace en el recuadro de arriba. A si que me decidi descargarme una versión mas vieja de la libreria. Me baje la libreria TCL 3.5.0 me me dio otro error muy diferente:

Error (TCL 3.5.0):
Documents/Arduino/libraries/DallasTemperature/DallasTemperature.cpp:9:26: error: WConstants.h: No such file or directory
Fuente: http://www.todomarino.com/forum/showthread.php?84914-Informativo-DS18B20-y-arduino-v-1-0

Esta ved me decia que no encontraba WConstants.h, a si que buscando por internet me encontre con una web en la que David Dicha Perez nos da la solución a este problema:

Solucion:
Si alguien se le ha dado por bajarse la ultima versión que han sacado los de arduino (la v 1.0) y usa los sensores de temperatura del tipo ds1820 o otros de dallas os va a fallar. A parte de bajar las ultimas versiones de las librerías onewire y dallastemperature hay que editar a mano la de dallastemperature y cambiar los sitios donde pueda poner WConstants.h o wiring.h por Arduino.h.

No se si ya lo sabíais pero me acabo de volver mico para encontrar esa referencia...

por si alguien quiere ver el resto de cambios echadle un ojo a los de la 1.0:

http://arduino.cc/en/Main/ReleaseNotes

A si que con el editor de textos abri el fichero DallasTemperature.cpp y cambie el texto que ponia WConstants.h por Arduino.h tal y como comentava David, compile y me funciono a la primera.

Antes:
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

#include "DallasTemperature.h"

extern "C" {
  #include "WConstants.h"
}

Despues:
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

#include "DallasTemperature.h"

extern "C" {
  #include "Arduino.h"
}

Si no quereis complicaros, en la sección de descargas suelo tener una copia de seguridad de mis librerias compartida con todo el mundo.


viernes, 27 de diciembre de 2013

Arduino funcion de alineación en un LCD

Esta tarde he estado practicando con los LCD via I2C, y he programado esta función que alinea el texto a la derecha, a la izquierda, lo centra, lo muestra aleatiramente en una fila especifica o muestra el texto aleatoriamnete por todo el display.




El codifo fuente es este:


Código:
/*
Autor: Aitor Martin
Fecha: 27-12-2013
Titulo: 007 Posicionar texto en el LCD
Placa: Arduino uno
Post: 

Código de dominio publico. Se puede distribuir y modificar  libremente, 
siempre y cuando se mencione al autor y se proporcione un enlace a su web.

--------------------------------------------------------------------------------------

LA funcion:
lcd_posiciona (16, 2, 1, 5, "Hola Mundo");
16 = Numero de columnas del LCD.
2  = Numero de filas del LCD.
1  = Fila en la que quieremos mostrar el texto (la primera es 1).
5  = Modo de alineacion.
"Hola Mundo" = El texto que vamos a mostrar.

Modos de alineacion:

1 = Izquierda
2 = Derecha
3 = Centro
4 = Aleatorio aciendo caso a la fila
5 = Aleatorio y no hace caso a la fila
*/


#include <Wire.h> //Para usar el I2C
#include <LiquidCrystal_I2C.h>//Para usar el display I2C

LiquidCrystal_I2C lcd(0x27,16,2); // 0x27 es la direccion del LCD 16x2
 
void setup()
    {
    lcd.init();        //Iniciamos LCD
    lcd.backlight();   //Enciende la iluminacion
    }
 
void loop()
  {
  lcd_posiciona (16, 2, 1, 1, "Alin. Derecha"); //Llamada a la funcion
  delay(2000);    //Espera 2 segundos
  lcd.clear();    //Borra el LCD
  
  lcd_posiciona (16, 2, 1, 2, "Alin. Izquierda"); //Llamada a la funcion
  delay(2000);    //Espera 2 segundos
  lcd.clear();    //Borra el LCD
  
  lcd_posiciona (16, 2, 1, 3, "Alin. Centro"); //Llamada a la funcion
  delay(2000);    //Espera 2 segundos
  lcd.clear();    //Borra el LCD

  for (int i=0; i<10; i++)
    {  
    lcd_posiciona (16, 2, 1, 4, "Alin. Aleatoria"); //Llamada a la funcion
    lcd_posiciona (16, 2, 2, 4, "Respeta fila"); //Llamada a la funcion
    delay(1000);    //Espera 2 segundos
    lcd.clear();    //Borra el LCD
    }
  
  for (int i=0; i<10; i++)
    {
    lcd_posiciona (16, 2, 1, 5, "Hola Mundo");
    delay(1000);
    lcd.clear();
    }
  }

void lcd_posiciona (int lcd_largo, int lcd_alto, int lcdy, int centrar, String texto)

  {
   int lcdx = 0;
   int largo = texto.length();
   int sobrante = lcd_largo - largo;
   int random_sobrante = random (0, (sobrante + 1));
   int random_y = random (0, lcd_alto);
   
   lcdy = lcdy - 1;
   
   switch (centrar)
     {
     case 1: lcdx = 0; break;
     case 2: lcdx = sobrante; break;
     case 3: lcdx = sobrante / 2; break;
     case 4: lcdx = random_sobrante; break;
     case 5:
             lcdx = random_sobrante;
             lcdy = random_y;
             break;
     default: 
     delay(0);// sentencias
     }

    lcd.setCursor(lcdx, lcdy);//Manda texto a las cordenadas calculadas
    lcd.print
(texto);
  } 


Arduino Display I2C parte 2

El ejemplo anterior no esta muy comentado, por eso lo voy a ir comentado paso a paso. He echo unas modificaciones en el codigo para poder insertar dos lineas de texto:

Código:
/*
Autor: Aitor Martin
Fecha: 27-12-2013
Titulo: 006 Display I2C Hola Mundo
Placa: Arduino uno
Post: http://aitormartin-apuntes.blogspot.com.es/2013/12/arduino-display-i2c-parte-2.html 

Código de dominio publico. Se puede distribuir y modificar  libremente, 
siempre y cuando se mencione al autor y se proporcione un enlace a su web.

Basado en un ejemplo de esta URL: 
http://blog.gotencool.com/2012/03/arduino-lcd-via-i2c.html?showComment=1388141296472
*/
#include <Wire.h>
  
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27,16,2); // 0x27 es la direccion del LCD 16x2
 
void setup(){
    lcd.init();
    lcd.backlight(); //enciende la iluminacion
    lcd.setCursor(0, 0);
    lcd.print("Hola mundo desde");
    lcd.setCursor(5, 1);
    lcd.print("el I2C");
}
 
void loop(){
    delay(1000);
}


Primero definimos las librerias que vamos a utilizar. La primera, Wire.h se encarga de manejar el bus I2C, y la otra libreria la LiquidCrystal_I2C.h se encarga de controlarnos el display I2C.

Código:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


A cada bus I2C se le pueden conectar 128 dispositivos. Eso no quiere decir que se puedan conectar 128 dispositivos iguales, ya que algunos fabricantes nos limitan en número de dispositivos iguales que se pueden conectar a un mismo bus I2C. Cada dispositivo tiene un código o dirección que lo disferencia respecto al resto como en este caso:

Código:
LiquidCrystal_I2C lcd(0x27,16,2); // 0x27 es la direccion del LCD 16x2

Cuando compramos una placa ya montada con su dispositivo I2C, normamente esa pcb tiene unos jumpers o puentes soldables en la PCB para que nostros personalicemos la dirección de nuestro dispositivo.

El siguente paso es activar el LCD:

Código:
    lcd.init();
    lcd.backlight(); //enciende la iluminacion
    lcd.setCursor(0, 0);
    lcd.print("Hola mundo desde");
    lcd.setCursor(5, 1);
    lcd.print("el I2C");

Con  lcd.init(); inicializamos el diplay.

lcd.backlight();  enciende la iluminación.

lcd.setCursor(0, 0); Pone el cursor en la primera columna (1 de 16) y en la primiera dila (1 de 2).

Ahora escribiremos un texto con lcd.print("Hola mundo desde");

El resto de código es igual, solo que escribe un texto en la fila de abajo del display.
 
lcd.setCursor(5, 1);
lcd.print("el I2C");


En el foro de donde he sacado la informacion del display, en uno de los comentarios una persona preguntaba para que se utilizan las resistencias de pul-up, y la respuesta es la siguiente:

Respuesta:
En el bus I2C es importante colocar una resistencia de pull-up a cada 
linea, tanto a la SDA como a la SCL, porque son con estas resistencias 
precisamente las que le marcan la velocidad de transmisión al bus.
 
Prueba con resistencias pull-up de 4K7 que suele ser un valor bastante 
estándar, pero recuerda que dependiendo de la velocidad hay que subir o 
bajar el valor de estas pull-ups.
 

Microchip en este documento:
http://ww1.microchip.com/downloads/en/DeviceDoc/i2c.pdf 
Microchip aconseja:
4K7 < 100kbps 2K2 > 100kps 1K > 400Kbps
Fuente: http://www.foroselectronica.es/f65/configuracion-sda-scl-i2c-1298.html 



Arduino Display I2C

Tras probar varios codigos que me he encontrado por internet, finalmente me he encontrado con este blog gacias al cual he podido aprender a manejar el display I2C:

http://blog.gotencool.com/2012/03/arduino-lcd-via-i2c.html

Arduino + LCD vía I2C

Hace una semana me llegó un display LCD 16x2 con interfaz de conexión i2c, no había tenido oportunidad de probarlo hasta hace unos días.
La gracia de este LCD está en la interfaz, que requiere sólo 4 pines:
  • Vcc (+5V)
  • GND
  • SDA (TX Data)
  • SCL (RX Data)
La comunicación de datos se efectúa mediante i2c, el que emplea un bus de comunicación de dos cables, los que alimentan y comunican dispositivos identificados por una dirección física. El bus permite velocidades entre 100Kbits/s a 400Kbits/s y la transmisión de datos se efectúa en palabras de 8bits.

Para conectar el LCD al Arduino se debe emplear los pines 4 y 5 para SDA y SCL respectivamente. Las conexiones quedarían así:
Finalmente, una vez que hemos efectuado las conexiones debemos cargar algún programa (se requiere la librería LiquidCrystal_I2C):


Código:
#include <Wire.h>
  
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27,16,2); // 0x27 es la direccion del LCD 16x2
 
void setup(){
    lcd.init();
    lcd.backlight(); //enciende la iluminacion
    lcd.setCursor(0, 0);
    lcd.print("Probando i2c");
}
 
void loop(){
    delay(1000);
}

Arduino instalar librerias en MAC OSX

Esta mañana a sido la primera vez que me he visto en la necesidad de utilizar una libreria con arduino. Como soy un novato con el MAC y con el Arduino, no me aclaraba muy bien donde se tenian que guardar las libreias. Si pulsaba sobre el "Sketch/Mostrar la carpeta Sketch" me mandaba a un directorio que estaba a tomar por saco...

Al final lo he soluciona tras leer estea web: http://arduino.cc/es/Hacking/Libraries

Las librerias en el OSX, se tienen que introducir en el siguiente direstorio ~~/Documents/Arduino/libraries/

jueves, 26 de diciembre de 2013

Adruino control de reles 4

Con este codigo se pueden encender 8 reles uno detras de otro al pulsar un pulsador, en la 9ª pulsación todos se apagan.

Si te animas puedes hacer una variariacón en la que al llegar a la 9ª pulsación los reles enpiezan a apagarse de uno en uno...





Código:
/*
Autor: Aitor Martin
Fecha: 26-12-2013
Titulo: Reles con pulsador
Placa: Arduino uno
Post: http://aitormartin-apuntes.blogspot.com.es/2013/12/adruino-control-de-reles-4.html

Código de dominio publico. Se puede distribuir y modificar  libremente, 
siempre y cuando se mencione al autor y se proporcione un enlace a su web.
*/

int ledPin = 13; // seleccionamos pin para el LED
int inPin = 11;   // seleccionamos pin para el pulsador
int val = 0;     // variable para leer estado del pulsador
int pinArray[] = {0, 1, 2, 3, 4, 5, 6, 7};
int count = 0;
int count_array = 0;

void setup()
  {

  pinMode(ledPin, OUTPUT);  // configuramos el LED como SALIDA
  pinMode(inPin, INPUT);    // configuramos el pulsador como ENTRADA
  
  for (count=0;count<8;count++)      // declaramos todas las variables a la vez
    {
    pinMode(pinArray[count], OUTPUT);
    digitalWrite(pinArray[count], LOW);
    Serial.print(count); 
    }
  }

void loop()
  {

  val = digitalRead(inPin);  // leemos el estado del pulsador
  if (val == HIGH)
    {
    digitalWrite(ledPin, HIGH);
    if (count_array <= 7)
      {
      digitalWrite(pinArray[count_array], HIGH);
      count_array ++;
      }
      else
      {
      for (count_array = 0; count_array < 8;count_array++)
        {
         digitalWrite(pinArray[count_array], LOW);
        }
      count_array = 0;
      }
    
    }
    else
    {
    digitalWrite(ledPin, LOW);
    }
    delay(200);
}