Anda di halaman 1dari 26

Universidad Nacional Mayor de San Marcos

Facultad de Ingeniera de Sistemas e Informtica


Arquitectura de Computadoras
Laboratorio 3 Conexin Java con Arduino y
Processing

I. Java
El Arduino IDE esta escrito en Java, y puede comunicarse al Puerto serial
a travs de la libreria RXTX. Esta libreria es muy similar a la extensin de
la Java Communications API. Internamente la IDE cual puerto y velocidad
en baudios que se uso la ultima vez. Desafortunadamente esta
implementacion interna no puede ser considerada API publica para uso
cotidiano. Por esa razon, el desarrollador tendr que determinar
manualmente cual puerto COM est usando su tarjeta Arduino.
Instalacion de RxTx
En primer lugar ubicar el lugar donde esta la librera, en este caso en la
versin IDE 1.0.5 y se observa que se encuentra en la siguiente carpeta:

Para poder usarlo en Java (en este caso con la IDE Eclipse) , se debe
crear el proyecto que se desee, y luego agregar la librera a travs de la
opcin Properties Java build path y agregarlo como librera externa:

Luego de hacer OK ya esta ingresada la librera, como se observa en el


proyecto:

Pero para completar su configuracin hay que determinar que librera dll
se ejecutara cuanto el jar sea invocado, por ello primero debe localizarse
el archivo rxtxSerial.dll, su carpeta es la siguiente:

Con esta ruta se busca la librera jar ya configurada para realizar la tarea
de agregar esta nueva ruta en la propiedad Native library location, como
muestra:

De esta manera est listo RxTx para trabajar el resto es cdigo de


implementacin:
El procedimiento de este laboratorio ser asi:
1. Una vez creado el proyecto y configurado el jar, se crean 2 clases:
ControlAcceso y Conectar.
2. ControlAcceso es una clase de tipo JFrame que ser la GUI que use
este programa para controlar la activacin/desactivacin de 2 leds,
colocados en el Pin 10 y Pin 11 de Arduino. La pantalla de esta clase es:

El cdigo de esta ventana es la siguiente:


package com.visual;

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

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JToggleButton;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;

import javax.swing.JLabel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JButton;

import com.conexion.Conectar;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.OutputStream;
import java.util.Enumeration;

public class ControlAcceso extends JFrame {


String condicion[] = { "ENCENDER", "APAGAR" };
int iled1 = 0;
int iled2 = 0;
private final String PORT_NAME = "COM20";
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 9600;
private OutputStream salida = null;

private static final String L1ALTO = "1";


private static final String L1BAJO = "2";
private static final String L2ALTO = "3";

private static final String L2BAJO = "4";

SerialPort pserial;
private JPanel contentPane;
private JButton btnled2;
private JButton btnled1;

private JFrame frame;

Conectar xcon;
private JLabel lblMensajes;

/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new ControlAcceso().setVisible(true);

} catch (Exception e) {
e.printStackTrace();
}
}

});
}

/**
* Create the frame.
*/
public ControlAcceso() {
setTitle("Control de dispositivos en Arduino");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 539, 390);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);

lblMensajes = new JLabel("Espere por favor...");

btnled1 = new JButton("ENCENDER");


btnled1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (iled1 == 0) {
xcon.enviarDatos(L1ALTO);
iled1 = 1;
} else {
xcon.enviarDatos(L1BAJO);
iled1 = 0;

}
btnled1.setText(condicion[iled1]);
}
});

btnled2 = new JButton("ENCENDER");


btnled2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (iled2 == 0) {
xcon.enviarDatos(L2ALTO);
iled2 = 1;
} else {
xcon.enviarDatos(L2BAJO);
iled2 = 0;
}
btnled2.setText(condicion[iled2]);
}
});

JLabel lblLed = new JLabel("Led 1");


JLabel lblLed_1 = new JLabel("Led 2");
GroupLayout
GroupLayout(contentPane);

gl_contentPane

gl_contentPane
.setHorizontalGroup(gl_contentPane

new

.createParallelGroup(Alignment.LEADI
NG)
.addGroup(
gl_contentPane
.createSequen
tialGroup()
.addGroup(
gl_contentPane
.createParallelGroup(
Alignment.LEADING)
.addGroup(
gl_contentPane
.createSequentialGroup()
.addGap(22)
.addComponent(
lblMensajes,

GroupLayout.PREFERRED_SIZE,
377,

GroupLayout.PREFERRED_SIZE))
.addGroup(
gl_contentPane
.createSequentialGroup()

.addGap(33)
.addGroup(
gl_contentPane
.createParallel
Group(

Alignment.TRAILING)
.addCompone
nt(

btnled2)
.addCompone
nt(

btnled1))
.addGap(34)
.addGroup(
gl_contentPane
.createParallel
Group(

Alignment.LEADING)
.addCompone
nt(

lblLed_1)
.addCompone
nt(

lblLed))))
.addContainer
Gap(114, Short.MAX_VALUE)));

gl_contentPane.setVerticalGroup(gl_contentPane.createParallelGroup(
Alignment.LEADING)
.addGroup(
gl_contentPane
.createSequentialGroup()
.addGap(28)
.addGroup(
gl_contentPane
.cr
eateParallelGroup(
Alignment.BASELINE)
.a
ddComponent(btnled1)
.a
ddComponent(lblLed))
.addGap(28)
.addGroup(
gl_contentPane
.cr
eateParallelGroup(
Alignment.BASELINE)

.a
ddComponent(btnled2)
.a
ddComponent(lblLed_1))
.addGap(202).addCompo
nent(lblMensajes)
.addContainerGap(24,
Short.MAX_VALUE)));
contentPane.setLayout(gl_contentPane);
comenzar();
}

private void comenzar() {


xcon = new Conectar();
boolean conecto = xcon.iniciarArduino();
if (conecto) {
lblMensajes.setText("Conectado a Arduino");
}else{
lblMensajes.setText("Error en conexion a Arduino");
}
}
private void verError(String cadena) {
// TODO Auto-generated method stub
JOptionPane.showMessageDialog(this, cadena, "Error",
JOptionPane.ERROR_MESSAGE);
}
}

3. A continuacin se define la clase Conectar, la cual ser la que


establezca la conexin con Arduino via las clases definidas en RxTx, su
codigo es el siguiente:

package com.conexion;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import javax.swing.JOptionPane;
public class Conectar {
private final String PORT_NAME = "COM20";
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 9600;
private OutputStream salida = null;
SerialPort pserial;
public Conectar() {
// TODO Auto-generated constructor stub
}
public boolean iniciarArduino() {
// TODO Auto-generated method stub
boolean hecho=false;
CommPortIdentifier portId = null;
Enumeration
portEnum
CommPortIdentifier.getPortIdentifiers();

// iterate through, looking for the port


while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier)
portEnum
.nextElement();
if (PORT_NAME.equals(currPortId.getName())) {
portId = currPortId;
break;
}
}
if (portId == null) {
hecho=false;

System.out.println("Error en acceso a puerto Arduino");


System.exit(0);
return false;
}
try {
// open serial port, and use class name for the
appName.
pserial
=
portId.open(this.getClass().getName(),
TIME_OUT);

(SerialPort)

// set port parameters


pserial.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
salida = pserial.getOutputStream();
hecho=true;
} catch (Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
return hecho;
}
public void enviarDatos(String data) {
try {
salida.write(data.getBytes());
} catch (IOException e) {
System.out.println("Error sending data");
}
}
}
4. A continuacin se escribe el codigo de la parte que corresponde a
Arduino, en este caso se esta usando Arduino UNO trabajando en
COM20, por lo que codigo para la conexin de los 2 leds seria el
siguiente:
const int LED1 = 10; //LED connected to digital pin 10

const int LED2 = 11; //LED connected to digital pin 11


int inByte = 0;

void setup(){
Serial.begin(9600); //Open the serial port
pinMode(LED1, OUTPUT); //Set the digital pin as output
pinMode(LED2, OUTPUT); //Set the digital pin as output
}

void loop(){

if(Serial.available() > 0){

inByte = Serial.read(); //read the incoming byte

if(inByte == '1')
digitalWrite(LED1, HIGH); //turn the LED1 on
else if(inByte == '2')
digitalWrite(LED1, LOW); //turn the LED1 of
else if(inByte == '3')
digitalWrite(LED2, HIGH); //turn the LED2 of
else if(inByte == '4')
digitalWrite(LED2, LOW); //turn the LED2 of
}
}

De esta manera se compila y transfiere el codigo Arduino para que corra


con la aplicacin Java descrita aqu.

5. Para compilar escribir en consola:


javac -classpath path_instalacion_biblioteca/RXTXcomm.jar:. <clases
java>
Despus de haber compilado nuestro programa Java, procedemos a
ejecutarlo, de la siguiente manera:
java
-Djava.library.path=.
-cp
path_instalacion_biblioteca/RXTXcomm.jar:. <clases java>
path_instalacion_biblioteca: Ruta de instalacin de la biblioteca, es decir,
donde estarn alojados los jar.

II. Processing

I. Comunicacin mediante driver:

No debemos olvidarnos antes de nada de cargar el firmare correspondiente en


Arduino.
El archivo de la librera Arduino para Processing esta en el archivo processing2arduino
Library for Processing v2.0: processing2-arduino.zip (Updated 6 Nov. 2013).
Dentro de ellos hay una carpeta que se llama Arduino y contiene la librera.
(\processing-arduino\arduino que esta en la direccion
http://playground.arduino.cc/Interfacing/Processing
Para que Processing pueda trabajar con la librera de Arduino debemos incluir
la carpeta
Arduino dentro de la carpeta libreras del IDE Processing:
\processing-0138\libraries
Para cargar el firmware en Arduino nos vamos a la librera processign-arduino y
en la
Carpeta \arduino\firmware\Standar que debemos cargar con el IDE Arduino y lo
debemos descargar sobre Arduino. En este archivo estn las funciones que
luego se utilizaran desde el IDE Processing para poder dialogar con Arduino.
Instrucciones para instalarla
1. Descompactar la librera y copia la carpeta "arduino" en la carpeta "libraries"
perteneciente al directorio de la aplicacin Processing.
2. Correr Arduino, abra la carpeta
Ejemplos> Firmata> y el sketch
StandardFirmata, y subirlo a la placa Arduino.
3.
Configurar
Processing
http://processing.org/reference/libraries/serial/

para

serial:

4. En Processing, abrir uno de los ejemplos que viene con la librera Arduino.
5. Modificar el cdigo de ejemplo seleccionando el puerto serie correcto.
6. Ejecute el ejemplo.
Para saber que puertos estn disponibles en Arduino se puede ejecutar el
siguiente codigo:
import processing.serial.*;
import cc.arduino.*;
println(Arduino.list());
La pantalla de salida mostrara los puertos reconocidos por lo que se escogera
el conveniente para el cdigo.
Las siguientes funciones se encuentran en la Librera Arduino para Processing y
comunican
(a partir de Processing) con un Arduino, una vez que el Firmata se ha instalado
en la tarjeta
Arduino.list():devuelve una lista con los dispositivos serie (puertos serie)
disponibles. Si
su tarjeta Arduino est conectada a la computadora cuando usted llama a esta
funcin, su
dispositivo estar en la lista.
Arduino(parent, name, rate): crea un objeto Arduino (objeto a nivel de
elemento de
programacin). parent debe aparecer sn comillas; name es el nombre del
dispositivo serie
(es decir, uno de los nombres devueltos por Arduino.list ()); rate es la velocidad
de la
conexin (57600 para la versin actual del de firmware).
pinMode(pin, mode): pin configura un pin digital como entrada (input) o
como salida
(output) mode (Arduino.INPUT o Arduino.OUTPUT).
digitalRead(pin): devuelve el valor ledo de una de las entradas digitales,
Arduino.LOW o

bien Arduino.HIGH (el pin debe estar configurado como entrada).


digitalWrite(pin, value): escribe Arduino.LOW o Arduino.HIGH en un pin
digital.
analogRead(pin): devuelve el valor de una entrada analgica leda (de 0 a
1023).
analogWrite(pin, value): escribe un valor analgico (seal tipo PWM) en un
pin digital
que soporta salida analgica (pines 3, 5, 6, 9, 10, y 11 para ATMEGA 168);
valores debes
estar comprendidos entre 0 (equivalente a of) y 255 (equivalente a on).

II. Comunicacin mediante puerto Serial


El circuito a implementar tiene las siguientes caractersticas:

a. En Arduino:

#include <Servo.h>

Servo myservo; // create servo object to control a servo

int potpin = 0; // analog pin used to connect the potentiometer


int val;

// variable to read the value from the analog pin

int analogVal = 0;

// define el pin de valor analgico

int smoothed = 0;
int alpha = 15;

// guardara el valor suavizado


// define el factor de suavizado

int inByte = 0; // define el valor del byte


int smoothed2 = 0; // define el valor suavizado y areglado

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
establishContact();

void loop()
{
val = analogRead(potpin);
(value between 0 and 1023)
val = map(val, 0, 1023, 0, 179);
between 0 and 180)

// reads the value of the potentiometer


// scale it to use it with the servo (value

myservo.write(val);
scaled value

// sets the servo position according to the

// lo suaviza

if (Serial.available() > 0) {
// recibe n byte
inByte = Serial.read();
// si el byte es una a
if (inByte == 'A') {
// mada el valor del sensor
Serial.write(val);
}
}
// espera 10 milisegundos

//delay(15);

// waits for the servo to get there

// mientras exista comunicacion, envia un byte con una A


void establishContact() {
while (Serial.available() <= 0) {
Serial.write('A'); // send a capital A
delay(300);
}
}

b. En Processing:

int tamano = 100;


import processing.serial.*; //importa la librera serial
Serial myPort; // define la variable de comunicacion
int[] serialInArray = new int[3]; // define la lista de valores de bytes qe recibira
int serialCount = 0; // define los bytes de informacion recibida
int tamanoRecibido = 0; // donde almacenara el valor del sensor
boolean firstContact = false; // define si a habido un primer contacto con la
placa

void setup(){
size(600,600);
fill(255,0,0);
stroke(255);
println(Serial.list()); // imprime en oantala la lista de pestos disponibles
String portName = Serial.list()[1]; // escoje el primer puerto
myPort = new Serial(this, portName, 9600); // inicializa el puero a 9600
}

void draw(){
//background(0);
fill(0,47);
rect(0,0,width,height);
//tamano ++;

tamano = tamanoRecibido*3; // assigna el valor del sensor al tamao de la


pelota
//fill(255,0,0);
noFill();
ellipse(width/2,height,tamano,tamano);

void serialEvent(Serial myPort) {


// read a byte from the serial port:
int inByte = myPort.read();
// if this is the first byte received, and it's an A,
// clear the serial bufer and note that you've
// had first contact from the microcontroller.
// Otherwise, add the incoming byte to the array:
if (firstContact == false) {
if (inByte == 'A') {
myPort.clear();
firstContact = true;
myPort.write('A');

// clear the serial port bufer


// you've had first contact from the microcontroller
// ask for more

}
}
else {
// Add the latest byte from the serial port to array:
serialInArray[serialCount] = inByte;
serialCount++;

// If we have 3 bytes:
if (serialCount > 0 ) {
tamanoRecibido = serialInArray[0];

// print the values (for debugging purposes only):


println(tamanoRecibido);

// Send a capital A to request new sensor readings:


myPort.write('A');
// Reset serialCount:
serialCount = 0;
}
}
}

El resultado se ve en la pantalla de Processing:

Observese la consola de Processing

Anda mungkin juga menyukai