viernes, 26 de noviembre de 2010

Codigo en flash

//Clase que reproduce un video de fondo
package {
 import flash.display.MovieClip;
 import flash.events.AsyncErrorEvent;
 import flash.net.NetConnection;
 import flash.net.NetStream;
 import flash.events.NetStatusEvent;
 import flash.media.Video;
 import flash.events.Event;
 import flash.media.SoundTransform;

 public class ElVideo extends MovieClip {
  var nc:NetConnection;
  var ns:NetStream;
  var vid:Video;
  var reproducir:Boolean;
  var contador:int;
  var paradaManual:Boolean;
  var celula:Celula;
  public function ElVideo() {
   cargarVideo();
  }

  public function cargarVideo() {
  nc=new NetConnection  ;
   nc.connect(null);
   ns=new NetStream(nc);
   ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncErrorHandler);
   ns.play("video.flv");
   ns.addEventListener(NetStatusEvent.NET_STATUS,terminoDeReproducirHandler);
   vid=new Video(width,height);
   vid.attachNetStream(ns);
   addChild(vid);
   var sonido:SoundTransform=ns.soundTransform;
   ns.soundTransform=new SoundTransform(0,0);
  }

  public function asyncErrorHandler(evento:AsyncErrorEvent):void {
  }// omitir error

  public function terminoDeReproducirHandler(evento:NetStatusEvent):void {
   if (evento.info.code=="NetStream.Play.Stop") {
    ns.seek(0);
   }
  }
 }
}


//clase Celula, representa cada celula que se crea en processing
package {
 import flash.display.MovieClip;
 import flash.events.Event;

 public class Celula extends MovieClip {
  var contador:int=10000;
  var frames:int=0;
  var estado:int=0;
  var escenario:Escenario;
  var remover:Boolean=false;
  var movimiento:int=5;

  public function Celula(escenarioNuevo:Escenario,posX:int,posY:int,nuevoEstado:int) {
   escenario=escenarioNuevo;
   x=posX;
   y=posY;
   estado=nuevoEstado;
   switch (estado) {
    case 0 :
     contador = 1000 ;
     break;
     case 1 :
     contador = 3000;
     break;
    case 2 :
     contador = 8000;
     break;
    case 3 :
     contador = 15000;
     break;
    case 4 :
     contador = 25000;
     break;
    case 5 :
     contador = 35000;
     break;
   }
   addEventListener(Event.ENTER_FRAME,enterFrameHandler);
   addChild(new CelulaUno  );
  }

  public function enterFrameHandler(evento:Event) {
   contador+=escenario.contadorTiempo;
   frames++;

    if (contador<0) {
    remover=true;
    }
   if (contador>=0) {
    removeChildAt(0);
    addChild(new CelulaUno  );
    estado=0;
   }
   2
   if (contador>=35000) {

    removeChildAt(0);
    addChild(new CelulaSeis  );
    estado=5;
   } else {
    if (contador>=25000) {
     removeChildAt(0);
     addChild(new CelulaCinco  );
     estado=4;
    } else {
     if (contador>=15000) {
      removeChildAt(0);
      addChild(new CelulaCuatro  );
      estado=3;
     } else {
      if (contador>=8000) {
       removeChildAt(0);12345665544333111222333
       addChild(new CelulaTres  );
       estado=2;
      } else {
       if (contador>=1000) {
        removeChildAt(0);
        addChild(new CelulaDos  );
        estado=1;
       }
      }
     }
    }
   }

   x += Math.round(Math.cos(Math.random()* movimiento*(360*3.14/180)));
   y += Math.round(Math.sin(Math.random()* movimiento*(360*3.14/180)));
   switch (estado) {
    case 0 :
     movimiento=15;
     if (frames%400==0) {
      trace("here");
      reproducirse();
     }
     break;
    case 1 :
     movimiento=30;
     if (frames%320==0) {
      reproducirse();
     }
     break;
    case 2 :
     movimiento=45;
     if (frames%240==0) {
      reproducirse();
     }
     break;
    case 3 :
     movimiento=60;
     if (frames%200==0) {
      reproducirse();
     }
     break;
    case 4 :
     movimiento=75;
     if (frames%180==0) {
      reproducirse();
     }
     break;
    case 5 :
     movimiento=90;
     if (frames% 80==0) {
      reproducirse();
     }
     break;
   }
  }
  public function reproducirse() {
   if (remover == false) {
   escenario.crearCelula(estado);
   }
  }
 }
}


Clase principal de la aplicacion. Crea una conexion TCP con Processing para la recepcion de datos, y maneja la lógica de la aplicación

package {
 import flash.display.MovieClip;
 import flash.net.Socket;
 import flash.events.Event;
 import flash.events.IOErrorEvent;
 import flash.events.SecurityErrorEvent;
 import flash.events.ProgressEvent;
 import flash.display.Stage;
 import flash.display.StageDisplayState;
 import flash.display.DisplayObject;
 import flash.utils.getDefinitionByName;
 import flash.utils.getQualifiedClassName;

 public class Escenario extends MovieClip {
  var socket:Socket;
  var valor:int;
  var contadorTiempo:int;
  var sonidos:Array;
  var cuantosSonidos:Array;
  var sonidoReproduciendo:int;
  var cantidadFrames:int;

  public function Escenario() {
   socket=new Socket  ;
   socket.connect("localhost",4500);
   socket.addEventListener(Event.CONNECT,conectarHandler);
   socket.addEventListener(IOErrorEvent.IO_ERROR,listenerErrorIO);
   socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,listenerSecurityError);
   socket.addEventListener(ProgressEvent.SOCKET_DATA,listenerDatosRecibidos);
   addEventListener(Event.ENTER_FRAME,enterFrameHandler);
   crearCelula(0);
   var sonidoUno:Sonido=new Sonido("1.mp3");
   sonidoUno.setReproducir();
   var sonidoDos:Sonido=new Sonido("2.mp3");
   var sonidoTres:Sonido=new Sonido("3.mp3");
   var sonidoCuatro:Sonido=new Sonido("4.mp3");
   var sonidoCinco:Sonido=new Sonido("5.mp3");
   var sonidoSeis:Sonido=new Sonido("6.mp3");
   var sonidoFondo:Sonido=new Sonido("AMBIENT1.mp3");
   sonidoFondo.setReproducir();
   sonidos=new Array(sonidoUno,sonidoDos,sonidoTres,sonidoCuatro,sonidoCinco,sonidoSeis);
   cuantosSonidos=new Array(0,0,0,0,0,0);
  }
  public function enterFrameHandler(evento:Event) {
   cantidadFrames++;
   if (cantidadFrames>10) {
    cuantosSonidos=new Array(0,0,0,0,0,0);
    if (valor==0) {
     if (contadorTiempo>-1000) {
      contadorTiempo-=10000;
     }
    } else {
     if (contadorTiempo>-10) {
      contadorTiempo--;
     }
     else {
      contadorTiempo = -10;
      crearCelula (0);
     }
    }
  trace("hijos: "+numChildren+" contador "+contadorTiempo);
    for (var i:int = 0; i < numChildren; i++) {
     //trace ("hijos: "+numChildren+" i: "+i);
     if (getDefinitionByName(getQualifiedClassName(getChildAt(i)))==Celula) {
      var celulita:Celula=getChildAt(i) as Celula;
      if (celulita.remover==true) {
       removerCelula(celulita);
      }
      cuantosSonidos[celulita.estado]+=1;
     }
    }

    if (numChildren==1) {
     for (var k:int = 0; k < sonidos.length; k++) {
      sonidos[k].parar();
     }
     sonidos[0].cargar();
     sonidos[0].setReproducir();
    } else {
     var valorSonidoMax:int=0;
     var sonidoMax:int=0;
     for (var j:int = 0; j < sonidos.length; j++) {
      if (cuantosSonidos[j]>valorSonidoMax) {
       valorSonidoMax=cuantosSonidos[j];
       sonidoMax=j;
      }
     }
     if (sonidoMax!=sonidoReproduciendo) {
      for (var l:int = 0; l < sonidos.length; l++) {
       sonidos[l].parar();
      }
      sonidos[sonidoMax].cargar();
      sonidos[sonidoMax].setReproducir();
      sonidoReproduciendo=sonidoMax;
     }
    }
   }
  }

  public function removerCelula(celulaBorrar:Celula) {
   removeChild(celulaBorrar);
  }

  public function crearCelula(estadoNuevo:int) {
   var celula:Celula=new Celula(this,Math.random()*width,Math.random()*height,estadoNuevo);
   addChild(celula);
  }

  public function conectarHandler(evento:Event) {
   trace("conectado");
  }
  public function listenerSecurityError(evento:SecurityErrorEvent) {
   //conn_txt.text="security error";
  }

  public function listenerErrorIO(evento:IOErrorEvent) {
   //conn_txt.text="fuck";
  }
  public function listenerDatosRecibidos(evento:ProgressEvent) {
   if (socket.bytesAvailable>=4) {
    valor=socket.readInt();
    valor;
    contadorTiempo+=valor;
   }
  }
 }
}

Codigo Processing

Clase Ejecutable

import processing.serial.*;

Serial myPort;
int linefeed = 10;
int sensor = 0;
HServidor Servidor;

void setup() {
size(200, 200);
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil(linefeed);
Servidor = new HServidor(this);
Servidor.start();
}

void draw() {
println (sensor);
}

void serialEvent(Serial myPort) {
String myString = myPort.readStringUntil(linefeed);
if (myString != null) {
myString = trim(myString);
sensor = int(split(myString, ',')) [0];
}
}

void keyPressed () {
sensor = key-48;
}

Clase HCliente

public class HCliente extends Thread{

DataInputStream dis;
DataOutputStream dos;
Socket aceptado;
String mensaje;
int posX;

public HCliente(Socket aceptado){
this.aceptado = aceptado;
try{
dis = new DataInputStream(new BufferedInputStream(aceptado.getInputStream()));
dos = new DataOutputStream(new BufferedOutputStream(aceptado.getOutputStream()));
}
catch(SocketTimeoutException e){
}
catch(IOException io){
}
}

public void run(){
while(true){
try{
enviar();
sleep(40);
}
catch(InterruptedException ie){
}
catch(Exception e){
}
}
}

public void enviar(){
try{
dos.writeInt(sensor*2);
dos.flush();
}
catch(IOException io){
}
}
}

Clase HServidor

public class HServidor extends Thread{

ServerSocket socket;
Socket aceptado;
ArrayList misClientes;
HCliente miCliente;
PApplet app;

public HServidor(PApplet app){
this.app = app;
try{
socket = new ServerSocket(4500);
misClientes = new ArrayList(6000);
}
catch(IOException io){
}
}

public void run(){
while(true){
try{
aceptado = socket.accept();
miCliente = new HCliente(aceptado);
miCliente.start();
misClientes.add(miCliente);
sleep(40);
}
catch(InterruptedException e){
}
catch(IOException io){
}
}
}
}

Codigo Wiring

int val;

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

void loop()
{
val = analogRead(0);
int enviar = 0;
if (val < 220) {
enviar = 5;
}
if (val < 200) {
enviar = 4;
}
if (val < 160) {
enviar = 3;
}
if (val < 120) {
enviar = 2;
}
if (val < 100) {
enviar = 1;
}
if (val < 60) {
enviar = 0;
}

Serial.print(val, DEC);
Serial.println (",");
delay(40);
}

Minutas de diseño

Para realizar el diseño de este circuito, era necesario primero que todo, saber la cantidad de pulsadores que se pulsaban. En este caso, eran 16 posibles pulsaciones. Para poder determinar la cantidad de pulsadores que se encuentran pulsados (no era necesario determinar cuales, sino cuantos), se podía desarrollar un circuito que conectara cada uno de los pulsadores a una entrada digital, pero para poder optimizar los materiales, se decidió utilizar otra solucion, la cual fue, sumar las corrientes de los pulsadores que estaban presionados, para así, poder determinar cuantos estaban pulsados.

Para eso, se diseño el siguiente circuito:




El circuito está compuesto por 16 módulos, en el diagrama se ve uno, que está por encima de la línea roja. Estos módulos, consisten de un pulsador, que al ser presionado, activa un relevo que permite prender un bombillo, además de que al ser presionado, permite el paso de corriente a una resistencia.

Se están utilizando 5V como entrada de voltaje, los cuales al pasar por la resistencia de 9.1K, obtenemos una corriente de 0,549 mA. Si sumamos las 16 corrientes de 0,549 mA, obtenemos una corriente teórica total de 8,79mA. Para poder leer este dato en wiring, es necesario convertir esta corriente a un voltaje, por lo que, los 8,79mA, deberian equivaler a 5V, por lo que era necesario utilizar una resistencia de 569Ohmnios. La resistencia comercial más cercana a esta, es de 560, por lo que fue la q utilizamos para la instalación.

Una vez se tiene el valor de cuantos pulsadores están presionados a la vez, se envía dicho dato a wiring, el cual lee el valor análogo del voltaje, y por medio del conversor AD que posee, lo convierte en un valor discreto. Una vez se tiene el valor, se establece un rango de valores, que va de 0 a 5, asumiendo q una persona no podrá presionar más de esos pulsadores.

Esos números son enviados vía serial al software Processing, el cual se encarga de recibir esos datos y enviarlos utilizando el protocolo TCP a Flash, en donde existe un código encargado de recibir los datos y actuar con ellos.