Ir al contenido principal

Te puede intersar

Conectando ESP8266 a la nube de Amazon(AWS) - Core IOT

Realizando un interfaz grafica en java para arduino + mq3

En esta entrada veremos un ejemplo de interfaz gráfica para un alcoholimetro desarrollado con arduino y el sensor MQ-3. Antes de empezar te recomiendo que revises la siguiente entrada Conectando arduino con java ya que ahí podrás ver algunos pasos previos que se deben realizar para poder ejecutar este programa. Bien comencemos...

Describiendo el proyecto

En este proyecto haremos un alcoholimetro con arduino, para ello como dijimos antes usaremos el MQ-3, un sensor especial para detectar alcohol en el aire, y desarrollaremos una interfaz gráfica en java la cual recibirá los valores sensados haciendo uso de la interfaz de comunicación serial de nuestra ordenador para luego mostrarla en nuestra pantalla.

Describiendo más a fondo el proyecto lo que haremos sera hacer que el arduino escuche constantemente por el puerto serial en busca de un carácter que activara la lectura del MQ-3, para ello implementaremos un botón en nuestra interfaz el cual al pulsarlo enviara dicho carácter, una vez activada la lectura y empezada a enviar la data sensada la mostraremos en la interfaz y la detendremos enviando otro carácter  nuevamente implementando un botón para esta tarea, así mismo durante todo este proceso implementaremos una caja de texto que nos valla mostrando los estados del proceso tales como el inicio de lectura de datos, la detección de niveles altos de alcohol, etc. También implementaremos un botón para conectar el puerto de comunicación serial por el se llevara a cabo la comunicación.

Entendido esto comenzamos con el desarrollo.


Preparando nuestro arduino

En arduino haremos el siguiente programa:

void setup() {
  Serial.begin(9600);
}

char c;
int f;

void loop() {
  //Leemos el puerto serial
  c = Serial.read();
  f=0;
  //En caso se envia el valor 'E' iniciamos la lectura del MQ-3
  if(c == 'E'){
  	//Entramos en un bucle de lectura
    while(f == 0){
      //Leemos el mq3
      double mq3 = analogRead(A0);
      //Ecuaciones para convertir la lectura a gr/l de alcohol en la sangre
      double volt = mq3*5/1023;
      double expo = (volt - 0.1535)/0.3958;
      double valor = pow(2.71828,expo);
      double alc = valor/1000;
      //imprimos el valor del alcohol
      Serial.print(alc);
      delay(500);
      c = Serial.read();
      //Si recibiimos una 'D' paramos la lectura
      if(c == 'D'){
        f = 1;
      }
    }
  }
}

Nota: Las ecuaciones que se presentan es una aproximación a la curva de respuesta  del sensor la cual fue obtenida consultando el datasheet del fabricante.

Ahora conectemos nuestro sensor con el arduino para ello realicemos el siguiente esquema de conexión:


Realizado esto verificamos y subimos nuestro programa al arduino. Proseguimos ahora con java.

Escribiendo el programa en java

Ahora vamos al eclipse, creamos nuestro proyecto e importamos las librerías de RXTX para comunicación serial, si quieres ver como ve a la entrada que comente lineas arriba. El codigo que utilizaremos es el siguiente:

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;


import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

public class alcoholimetro extends JFrame implements ActionListener {
	
	InputStream in;
	OutputStream out;
	//Elementos que usamos para nuesta interfaz
	JLabel lblPuerto;
	JLabel lblArduino;
	JButton btnVer;
	
	JPanel pnlLectura;
	JButton btnIniciar;
	JButton btnDetener;
	JLabel lblLectura;
	JTextArea lblDato;
	JTextArea txaDato;
	JTextArea txaLog;
	JScrollPane scpLog;
	
	String dato="";
	
	public alcoholimetro() {
    	//Titulo de la ventana de nuestro interfaz
		setTitle("IDE alcoholimetro");
        //Tamaño de nuestra ventana
		setSize(355,400);
		setLayout(null);
		setLocationRelativeTo(null); 
        //Terminamos la interfaz al dar X
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
        //Etiqueta de texo
		lblPuerto = new JLabel("Puerto Arduino :");
        //Asignamos coordenadas de posicion(x,y,ancho,largo)
		lblPuerto.setBounds(45, 10, 100, 20);
		
		lblArduino = new JLabel("");
		lblArduino.setFont(new Font("Arial",2,14));
		lblArduino.setForeground(Color.blue);
		lblArduino.setBounds(140, 10, 60, 20);
		
        //Creamos un boton
		btnVer = new JButton("Conectar");
		btnVer.setBounds(195,10,100,20);
        //Creamos un sensor de eventos de boton
		btnVer.addActionListener(this);
		
        //Creamos una caja de texo con barra de desplazamiento
		txaLog = new JTextArea();
		scpLog = new JScrollPane(txaLog);
		scpLog.setBounds(20, 200, 300, 140);
		
        //Agregamos los elementos a nuestro contenedor principal
		this.add(lblPuerto);
		this.add(lblArduino);
		this.add(btnVer);
		this.add(scpLog);
		
        //Creamos un panel contenedor
		pnlLectura = new JPanel();
		pnlLectura.setOpaque(false);
		pnlLectura.setBounds(20,40,300,150);
		pnlLectura.setLayout(null);
        //Le creamos un borde
		TitledBorder borde =new TitledBorder(new EtchedBorder(), "Lectura Alcoholimetro");
		borde.setTitleFont(new Font("Calibri",3,16));
		pnlLectura.setBorder(borde);
		
		btnIniciar = new JButton("INICIAR");
		btnIniciar.setFont(new Font("Calibri",3,15));
		Color color1=new Color(20, 150, 80);
		btnIniciar.setBackground(color1);
		btnIniciar.setBounds(30, 30, 100, 30);
		btnIniciar.addActionListener(this);
		pnlLectura.add(btnIniciar);	
		
		btnDetener = new JButton("DETENER");
		btnDetener.setFont(new Font("Calibri",3,15));
		Color color2=new Color(220, 60, 50);
		btnDetener.setBackground(color2);
		btnDetener.setBounds(170, 30, 100, 30);
		btnDetener.addActionListener(this);
		pnlLectura.add(btnDetener);	
		
		lblLectura = new JLabel("gr/L :");
		lblLectura.setFont(new Font("Arial black",2,14));
		lblLectura.setBounds(90, 100, 60, 20);
		pnlLectura.add(lblLectura);
		
		lblDato = new JTextArea("");
		lblDato.setFont(new Font("Arial black",3,28));
		lblDato.setBounds(140, 90, 100, 35);
		lblDato.setBackground(null);
		lblDato.setBorder(null);
		pnlLectura.add(lblDato);
		
		txaDato = new JTextArea("");
		
		this.add(pnlLectura);
		
	}
	
    
	public void encontrarArduino() {
		
		Enumeration numPuerto = CommPortIdentifier.getPortIdentifiers();
		String[] p=new String[10];
        
        
        while ( numPuerto.hasMoreElements() ) {
        	CommPortIdentifier puertoId = (CommPortIdentifier) numPuerto.nextElement();
        	lblArduino.setText(puertoId.getName());
        }
        
	}
	
	public void conectar(String portName) throws Exception{
		CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() )
            System.out.println("Error: Port is currently in use");
        else{
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
            
            if ( commPort instanceof SerialPort ){
                SerialPort puertoSerial = (SerialPort) commPort;
                puertoSerial.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
                
                in = puertoSerial.getInputStream();
                out = puertoSerial.getOutputStream();
 
                (new Thread(new SerialReader(in))).start();
                (new Thread(new SerialWriter(out))).start();
            }else
                System.out.println("Error: Only serial ports are handled by this example.");
        }     
	}
	
	public class SerialReader implements Runnable{
		InputStream in;
		
	    public SerialReader ( InputStream in ){
	            this.in = in;
	    }
	        
	    public void run (){
	    	byte[] buffer = new byte[1024];
	    	int len = -1;
	    	try{
	    		while ( ( len = this.in.read(buffer)) > -1 ){
	    			String temp = new String(buffer,0,len);
	    			txaDato.append(temp);
	    			if(txaDato.getText().length()>=4){
	    				double d = Double.parseDouble(txaDato.getText());
	    				if(d >0.4) {
	    					lblDato.setForeground(Color.red);
	    					txaLog.append("!!Se ha sobrepasado el limite permitido\n");
	    				}else {
	    					lblDato.setForeground(Color.black);
	    				}
	    				lblDato.setText(txaDato.getText());
	    				txaDato.setText("");
	    			}
	            }
	    	}catch (IOException e){
	                e.printStackTrace();
	        }            
	    }
	}
	
/Metodo para leer y enviar entradas desde el teclado (opcional)
public class SerialWriter implements Runnable{
	OutputStream out;
        
	public SerialWriter (OutputStream out){
            this.out = out;
	}
        
	public void run (){
		try{                
			int c = 0;
            while ( ( c = System.in.read()) > -1 ){
            	this.out.write(c);
            }                
		}catch ( IOException e){
                e.printStackTrace();
        }            
    }
}

//Metodos que se activan cuando se pulsa un boton
public void actionPerformed(ActionEvent e) {
	if(e.getSource().equals(btnVer)) {
		encontrarArduino();
		txaLog.append("Se ha detectado un dispositivo inicie para empezar\n");
		try {
			conectar(lblArduino.getText());
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
	
	if(e.getSource().equals(btnIniciar)) {
		try {
			out.write(69);
			txaLog.append("Se ha iniciado la rececpción de datos\n");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}	
	
	if(e.getSource().equals(btnDetener)) {
		try {
			out.write(68);
			lblDato.setText("");
			txaLog.append("Se ha detenido la recepcion de datos\n");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}	
}
//Metodo principal de ejecucion de nuestro programa	
public static void main(String[] args) {
		alcoholimetro a = new alcoholimetro();
		a.setVisible(true);
}

}

Ejecutamos el programa y tendremos la siguiente interfaz:



Para iniciar presionamos en el botón Conectar y Luego en INICIAR, empezara a mostrarnos la data leída por el MQ-3 como vemos en la siguiente imagen.


Como vemos se nos muestran dos mensajes, uno generado al pulsar el botón conectar y el otro al presionar en iniciar en la caja de incidencias, ademas se nos muestra el valor de alcohol en la sangre en gr/L,(como no se tiene interacción nos marca 0.0). Ahora probemos acercando un algodón con alcohol:


Ahora en la imagen notamos que al acercar el algodón se aprecia que el valor subió hasta 0.66 el cual se marca de color rojo indicando que este resultado esta por encima del umbral permitido (el cual definimos como 0.4 para este ejemplo) y nos muestra la indicación respectiva en el caja de incidencias. 

Si queremos terminar la lectura de datos simplemente presionamos en detener y dejaremos de recibir data, como vemos a continuación:


Observamos en la imagen que se detuvo la recepción de datos y se nos muestra el mensaje respectivo, si queremos comenzar a captar valores simplemente volvemos a dar clic en iniciar. 

Y listo ya tenemos una interfaz para nuestro alcoholimetro en java, podemos hacer diferentes variaciones o cambios a partir de ahora  o empezar nuevos proyectos con otros sensores ya que la idea es la misma. Lo que sigue sera una variante a este proyecto para enviar esta data a través de red pero eso lo dejamos para otra entrada.


Muchas gracias por tu tiempo.




Tambien puedes descargar el codigo utilizado en esta entrada dando clic en el botón de abajo





Comentarios

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  2. Que genial proyecto ... seria bueno si poner la guía del Arduino en físico para poder guiarnos, saludos.

    ResponderEliminar

Publicar un comentario

Entradas populares