VAML

VAML
Victor Manzanero

jueves, 22 de diciembre de 2011

Sensor de temperatura con arduino y java

Sensor de temperatura LM35 y java


Saludos nuevamente de mi parte.
Estamos a qui para un nuevo tutorial, esta vez de nuevo con arduino y java, pero en esta ocasión utilizando un sensor de temperatura (LM35).

***************************************************************************
para llevar acabo este tutorial se da por hecho que  ha visto el post anterior ya que la manera en que arduino se comunicara con java es la misma por lo tantos los pasos a seguir son los mismo. no ser asi por favor miviste el   ----> post 
***************************************************************************

Un LM35 es un dispositivo electrónico capas de poder medir la temperatura, consta de tres bases o patas, cada una con su propio propósito uno para gnd o tierra, otro para vin o voltaje de entrada y por ultimo vout o voltaje de salida.

El LM35 funciona de la siguiente manera.
1°c = 10mlv                     lo que es igual a un grado centigrado es igual a 10 mili volts
por lo que si en  temperatura ambiente tenemos 32°c
el LM35 tendría en su base de salida  320 mlv;

La forma en que se conecta a arduino y la función de cada una de sus bases es la siguiente:


Con esta unión se pueden dar mil usos, desde mecánicos, electrónicos y por que no hasta médicos  como fue en mi caso, ver otro de mis blogs donde use este cirucitor para fines medicos.

paso 1.-
preparar java para la conexión con arduino llamando librerías y ajustando directorios de archivos. (visto en el post anterior mismos pasos) ir al post anterios

paso 2.- 
preparar la interfaz en java encargada de recibir los datos que arduino le ara llegar, para este tutorial yo he preparado un termómetro dibujado en el metodo paint() de una clase java. quedando asi


Esta interfaz ira representando los valores que arduino le haga llegar.

CÓDIGO

public void paint(Graphics g)
    {
   //super.paint(g);//para algunos sistemas windoxs
   repaint();
      //temp=(redonde((n/.30)));
        

        if ((x-c<=156)&&(x-c>=106))
        {
        fondo=Color.BLUE;
        }
         if ((x-c<=106)&&(x-c>=74))
        {
        fondo=Color.ORANGE;
        }
        if ((x-c<=74)&&(x-c>=34))
        {
        fondo=Color.RED;
        }
        //base
        //fuente de todas las letras en el termometro
        Font f = new Font( "Helvetica",Font.BOLD,16 );

     g.setFont( f );
       g.setColor(Color.BLACK);
    g.drawArc(90,230,50,50, 130,280);//base arriba
     g.drawArc(80,230,70,60, 130,277);//base abajo
     g.drawLine(100,80,100,235);
          g.drawLine(92,80,92,237);
     g.drawLine(132,80,132,235);

     g.drawLine(140,80,140,238);
      //base
g.drawArc(92,60,48,48,8,180);//tapa de arriba
g.drawArc(100,65,32,32,5,180);//tapa de abajo


      //g.drawArc(90,50,50,50, 540,360);
//rellono que simula al mercurio
        g.setColor(fondo);

g.fillArc(90,230,50,50, 0,360);
g.fillRect(101,80,31,156);//rellono mercurio
g.setColor(Color.WHITE);
g.fillRect(101,80,31,x-c);//rellono mercurio
//fuentes
g.setColor(Color.white);
 g.fillArc(100,65,32,32,5,180);//tapa de abajo
 g.drawString((c)+"ºC", 95,260);
       //letras
        
        g.setColor(Color.BLUE);
         g.drawString("0 -", 70,240);
            g.drawString("20 -", 65,220);
             g.setColor(Color.ORANGE);
             g.drawString("40 -", 65,200);
              g.drawString("60 -",65,180);
                  g.setColor(Color.RED);
               g.drawString("80 -", 65,160);
                g.drawString("100 -",55,140);
                  //g.drawString("120 -", 55,120);
                //g.drawString("140 -",55,100);
         
                if(x<=10)
                {
                g.setColor(Color.RED);
 g.fillArc(100,65,32,32,5,180);//tapa de abajo
                }
    }

Es fácil notar que el termómetro ira adquiriendo otro color mientras la temperatura vaya aumentando.

paso 3.

hasta ahora solo se ha preparado la interfaz de usuario, entramos a la parte de la conexión pues prepararemos arduino para mandar los datos a java.
el codigo es muy simple.

void setup()
{
//abrimos el puerto serie a una tasa de bits de 9600 estantar
Serial.begin(9600);
}//fin de setup

void loop()
{
//se prepara los datos para ser enviados  
/*primero se lee lo que esta en la entrada analógica 0 luego lo multiplicamos por 500 por que esta siendo alimentado con 5v y hay 500 veces 10 mlv en el. 10ml por 500 = 5v (LM35 usa 10ml para presesentar un 1°c)
esta es la explicación de por que por 500

luego se divide entre 1023.

esto por que es lo máximo que arduino puede leer de la estragada analogica

y por ultimo escribimos en el puerto serie la cantidad que nos quedo. ya en grados
*/
Serial.write((analogRead(0)*500.00)/1023.00);
//le decimos a arduino  que lee la entrada analógica  cada segundo  
delay(1000);
}

cabe aclarar que hay dos formas en las que arduino envía informacion por el puerto serie son Serial.write ();
y Serial.println();

uno envia el valor real y el otro pinta el resultado sin importarle cual es su valor.

ejemplo si estamos a 61°c
el método  Serial.write (); mandaría una a ¿por que? es simple por que en la tabla ascii a=61 entonces cuando java reciba esta "a" sabrá que es un 61 y lo graficara en el termómetro.

el metodo Serial.println (); este no le importara su valor real y simplemente pondrá en el puerto serie el 61
entonces cuando java reciba este  este 61, tomara el "6"  y graficara en el termómetro el 54, tabla ascci 6 =54
e inmediatamente tomara el  "1" y graficara en el termómetro el 49, por la misma razon 1 en  la tabla ascii=49.

por lo que el metodo Serial.println() no es valido para estas practicas.

el codigo sin comentarios queda asi:


paso 4 y ultimo:

recibir los datos de arduino


//importamos las librerias necesarias para la conexion
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.lang.reflect.*;
import java.io.InputStream;
import processing.app.Preferences;

creamos 

una variable de tipo Input para que este reciba los datos de arduino asi:

 static InputStream input;


luego en el metodo main que previamente fue preparado para la comunicacion 

asemos  int n=0; n=(input.read()) ;//Temperatura
temperatura(n);

y ese valor se lo mandamos a un metodo encargado graficarlo en el termómetro.

public static void temperatura(int t)
{
c=t;

}
 la "c" del código es la que se graficara en arduino.

el código quedara así sin el metodo paint :
import gnu.io.PortInUseException;
import gnu.io.UnsupportedCommOperationException;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import java.io.InputStream;
import java.io.OutputStream;
import processing.app.Preferences;
import java.util.*;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.awt.Color;
/**
 *
 * @author victor
 */
public class Temperatura extends javax.swing.JFrame {
int x=156;static int c=0;static int m=1;
double temp=0;
Color fondo=Color.GREEN;

static byte chunk[]={1};
static int n=0;
    static InputStream input;
    static OutputStream output;
    static SerialPort serialport;
            private static final String PORT_NAMES[] = {
//"/dev/tty.usbserial-A9007UX1", // Mac OS X
//"/dev/ttyUSB0", // Linux
                          "/dev/ttyACM0","/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2", "/dev/ttyUSB3", "/dev/ttyUSB4", "/dev/ttyUSB5", "/dev/ttyUSB6", "/dev/ttyUSB7", "/dev/ttyUSB8", "/dev/ttyUSB9", "/dev/ttyUSB10", "/dev/ttyUSB11", "/dev/ttyUSB12","/dev/ttyUSB13","/dev/ttyUSB14","/dev/ttyUSB15","/dev/ttyUSB16","/dev/ttyUSB17","/dev/ttyUSB18","/dev/ttyUSB19","/dev/ttyUSB20","/dev/ttyUSB21"
,"COM3","COM0","COM1","COM2","COM4","COM5","COM6","COM7","COM3","COM8","COM9","COM10","COM11","COM12" // Windows
};
    static public class MyPrefs extends Preferences {
        static public void init() {
      Preferences.init("/home/victor/.arduino/preferences.txt");
         //Preferences.init("c:/preferences.txt");
        }
    }
    /** Creates new form Temperatura */
    public Temperatura() {
        initComponents();
    }
public static void temperatura(int t)
{
c=t;

}
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Termometro");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 244, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) throws IOException, PortInUseException, UnsupportedCommOperationException {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Temperatura.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Temperatura.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Temperatura.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Temperatura.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Temperatura().setVisible(true);
            }
        });
        
        
          MyPrefs.init();
        System.out.println("puerto usado: " + MyPrefs.get("serial.port"));
        System.out.println("targeta utilizada: " + MyPrefs.get("board"));

        /*CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(
                MyPrefs.get("serial.port"));*/

        CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

// iteraciones para buscar el puerto
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName:PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}

  Temperatura m=new Temperatura();
        serialport = (SerialPort)portId.open(m.getClass().getName(), 9600);

        input = serialport.getInputStream();
        output = serialport.getOutputStream();
        serialport.setSerialPortParams(MyPrefs.getInteger("serial.debug_rate"),
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
        while(true){
                while(input.available()>0) {
                //System.out.println((char)(input.read()));
try {
    /*
int available = input.available();//esta linea regresa el valor de la cantidad de informaion en el puerto serie
byte chunk[] = new byte[available];//se crea una rreglo de tipo bite que tiene como limite el valor de avalible
input.read(chunk, 0, available);//lee lo que se encuentra pendiente en el puertoserie y lo guarda en el arreglo
// Displayed results are codepage dependent
                //despliega en pantalla todo lo que logro leer
                                System.out.println("");
//System.out.println("Arduino dice: "+new String(chunk));
               n=Integer.parseInt(new String(chunk));
               System.out.println(""+n);
*/int b=0;

 int n=0; n=(input.read()) ;//Temperatura
temperatura(n);
System.out.println(n);

              } catch (Exception e) {
System.err.println(e.toString());
}
//System.out.println(""+ban);
                           }
        }
        
        
        
    }
    
    static public double redonde (double x)
     {
    return  Math.rint(x*1)/1;
    }
   
}
código completos dudas comentarios y/o sugerencias a vctr.31@hotmail.com

un video de su implementacion.





Próximo tutorial comunicación de java con de Internet

4 comentarios:

  1. no me funciona muy bien la parte de graficación, como que no se mantiene estática sino que se muestra intermitente, como titilante..

    ResponderEliminar
  2. existe señales que le ponen ruido a la lectura serial, eso no es por el programa es mas por el hardware

    ResponderEliminar
  3. Hola Victor, muy bueno tu blog , quería consultarte lo siguiente , yo tengo un arduino uno funcionando con el IDE que descargue sobre W7, pero quería hacer algo como lo que hiciste vos de activar un led mediante dos botones en Java, yo tengo el eclipse pero no logro ubicar para importar processing.app.Preferences de donde la tengo que descargar? Muchas gracias por tu ayuda

    ResponderEliminar
  4. me podras pasar las librerias y el proyecto que cuando copio tu código me da error en import processing.app.Preferences; no la consigue tengo las librerias RXTXcomm y Arduino v2.5.0 y otra que se llama panamahitel este es mi correo alberto13711@gmail.com

    ResponderEliminar

Locations of visitors to this page