package org.sunspotworld.demo; import com.sun.spot.sensorboard.EDemoBoard; import com.sun.spot.sensorboard.peripheral.ITriColorLED; import com.sun.spot.sensorboard.peripheral.LEDColor; import com.sun.spot.sensorboard.peripheral.IAccelerometer3D; import com.sun.spot.util.Utils; import java.io.IOException; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; import com.sun.spot.sensorboard.peripheral.ISwitch; import com.sun.spot.sensorboard.peripheral.ITriColorLED; import com.sun.spot.util.*; import com.sun.spot.util.Utils; import com.sun.spot.sensorboard.peripheral.ISwitch; import com.sun.spot.sensorboard.peripheral.ISwitchListener; import com.sun.spot.util.Utils; import java.io.*; import javax.microedition.io.*; import com.sun.spot.util.Utils; /** * Clase cliente que es la base de la aplicacion que se cargará en el Sun Spot de * Rango Libre, principalmente encargada de mostrar a través de los leds un * pequeño demo y de enviar las mediciones del acelerometro hasta la estacion base. * * @author Mauricio Diaz, Daniel Zuleta */ public class SunSpotClientApplication extends MIDlet{ //variables agregadas int opcionSW1 = 0; int opcionSW2 = 0; private IAccelerometer3D accel = EDemoBoard.getInstance().getAccelerometer(); //para el acelerómetro private ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs(); //para los leds private ISwitch sw1, sw2; // para los dos botones /** * Metodo base de la clase cliente encargado de inicializar un demo en el * Sun Spot de rango libre y de iniciar el envio de informacion a traves * de la coneccion establecida por radio con la estacion base. */ public void demo() { for (int i = 0; i < 8; i++) { leds[i].setOff(); // turn off all LEDs leds[i].setColor(LEDColor.BLUE); // set them to be RED when lit } //botones (para ocupar el boton 2, hacer lo mismo pero con SW2: sw1 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW1]; sw1.addISwitchListener(new ISwitchListener(){ //esta función determina lo que ocurre cuando se presiona un boton: public void switchPressed(ISwitch sw) { opcionSW1++; if(opcionSW1==3)opcionSW1=0; } //Esta función determina qué se hace cuando se suelta un botón (por ahora nada) public void switchReleased(ISwitch sw) { } }); //Al presionar el switch 2, se setean los offsets guardando los valores //de aceleración para obtener las aceleraciones sw2 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW2]; sw2.addISwitchListener(new ISwitchListener(){ //esta función determina lo que ocurre cuando se presiona un boton: public void switchPressed(ISwitch sw) { opcionSW2++; if(opcionSW2==2)opcionSW2=0; switch(opcionSW2){ case 0: for (int i = 0; i < 8; i++) { //leds[i].setOff(); // turn off all LEDs leds[i].setColor(LEDColor.BLUE); // set them to be BLUE when lit } break; case 1: for (int i = 0; i < 8; i++) { // leds[i].setOff(); // turn off all LEDs leds[i].setColor(LEDColor.RED); // set them to be RED when lit } break; } } //Esta función determina qué se hace cuando se suelta un botón (por ahora nada) public void switchReleased(ISwitch sw) { } }); // We create a DatagramConnection (conección para envío por radio) DatagramConnection dgConnection = null; Datagram dg = null; try { //Intentar una coneccion por radio con quien este escuchando //a traves del puerto 37 dgConnection = (DatagramConnection) Connector.open("radiogram://broadcast:37"); //Entonces preguntamos por un datagrama con el maximo tamaño //permitido dg = dgConnection.newDatagram(dgConnection.getMaximumLength()); } catch (IOException ex) { System.out.println("No se puede establecer una conexion de broadcast"); ex.printStackTrace(); return; } //intentamos dejar sin offsets el sunspot try{ accel.setRestOffsets(); }catch(IOException exp){ } while (true) { try { //Lectura de la inclinación en cada uno de los ejes double tiltXrad = accel.getTiltX(); //returns [-Pi/2, Pi/2] double tiltYrad = accel.getTiltY(); //returns [-Pi/2, Pi/2] double tiltZrad = accel.getTiltZ(); //returns [-Pi/2, Pi/2] int tiltX = (int)Math.toDegrees(tiltXrad); // returns [-90, +90] grados int tiltY = (int)Math.toDegrees(tiltYrad); // returns [-90, +90] grados int tiltZ = (int)Math.toDegrees(tiltZrad); // returns [-90, +90] grados //Se mostrará en los leds la inclinacion del eje dependiendo de //cuantas veces se haya presionado el switch, comenzando con //opcionSW=0 (0->ejeX, 1->ejeY, 2->ejeZ) switch(opcionSW1){ case 0:{ int offset = -tiltX / 15; // convert angle to range [3, -3] - bubble goes to higher side if (offset < -3) offset = -3; if (offset > 3) offset = 3; leds[3 - offset].setOn(); // use 2 LEDs to display "bubble"" leds[4 - offset].setOn(); Utils.sleep(50); // update 20 times per second leds[3 - offset].setOff(); // clear display leds[4 - offset].setOff(); break; } case 1:{ int offset = -tiltY / 15; // convert angle to range [3, -3] - bubble goes to higher side if (offset < -3) offset = -3; if (offset > 3) offset = 3; leds[3 - offset].setOn(); // use 2 LEDs to display "bubble"" leds[4 - offset].setOn(); Utils.sleep(50); // update 20 times per second leds[3 - offset].setOff(); // clear display leds[4 - offset].setOff(); break; } case 2:{ int offset = -tiltZ / 15; // convert angle to range [3, -3] - bubble goes to higher side if (offset < -3) offset = -3; if (offset > 3) offset = 3; leds[3 - offset].setOn(); // use 2 LEDs to display "bubble"" leds[4 - offset].setOn(); Utils.sleep(50); // update 20 times per second leds[3 - offset].setOff(); // clear display leds[4 - offset].setOff(); break; } default: break; } //Obtencion de las aceleraciones en cada eje: double x = accel.getAccelX(); // get current acceleration along each axis double y = accel.getAccelY(); double z = accel.getAccelZ(); //Obtencion de las aceleraciones relativas en cada eje: double rx = accel.getRelativeAccelX(); double ry = accel.getRelativeAccelY(); double rz = accel.getRelativeAccelZ(); // We send the message (UTF encoded) dg.reset(); //se escribe en el datagrama en este orden : //dg=opcionSW1/incX/incY/incZ/accX/accY/accZ/opcionSW2 dg.writeInt(opcionSW1); dg.writeDouble(tiltX); dg.writeDouble(tiltY); dg.writeDouble(tiltZrad); dg.writeDouble(x); dg.writeDouble(y); dg.writeDouble(z); dg.writeInt(opcionSW2); dgConnection.send(dg); //envío } catch (IOException ex) { System.out.println("Error reading accelerometer: " + ex); ex.printStackTrace(); } Utils.sleep(25); //el ciclo while funciona cada 25 milisegundos } } /** * LLamado a MIDlet para comenzar nuestra aplicacion. */ protected void startApp() throws MIDletStateChangeException { SunSpotClientApplication app = new SunSpotClientApplication(); app.demo(); } /** * Pausar la aplicacion. */ protected void pauseApp() { // Esto nunca sera invocado por la MV Squawk, solo se pone porque debe //estar implementado para el correcto funcionamiento de la aplicacion. } /** * LLamado si el MIDlet es terminado por el sistema. * * Called if the MIDlet is terminated by the system. * Es decir si startApp arroja cualquier excepcion que no sea MIDletStateChangeException, * si VM.stopVM() es llamado. * * No es llamado si MIDlet.notifyDestroyed() fue llamado. * * @param unconditional Si es verdadero cuando este metodo es llamado, el MIDlet * debe limpiar y liberar todo recurso. Si es falso el MIDlet puede arrojar * MIDletStateChangeException para indicar que no desea ser destruido ahora. */ protected void destroyApp(boolean unconditional) throws MIDletStateChangeException { for (int i = 0; i < 8; i++) { leds[i].setOff(); } } }