Sunday, December 9, 2012

Final project progress - Software

So, let`s talk a little bit more about the technology we are currently using in our piece [put your name here].

We are using now a combination of Arduino and Adobe Flash. Let me explain why we did it: Processing did not handle well the video size we had even using an Arduino Mega. As this time we actually made the videos (and we did it in a reasonable resolution), Processing was no longer an option. Luckily enough, the last release of Adobe Flash on the Creative Suite CS6 includes a library that allows it to communicate with Arduino through a Serial port:

Native extensions for AIR and Arduino

And we are using this library from Arduino:

Arduino Playground: Flash

Our Arduino code consists of three simple steps: getting the pressure read on the FSRs, transforming them into strings through an if block and sending this information to Flash using Serial Communication.
Our Arduino final code was:


int read1 = A0;
int read2 = A1;
int read3 = A2;
int read4 = A3;

void setup()
{
  Serial.begin(9600);
  Serial.print("\n");
}

void loop()
{
//read values
    int value1 = analogRead(read1);
    int value2 = analogRead(read2);
    int value3 = analogRead(read3);
    int value4 = analogRead(read4);
    // if you put 1 it`ll show the values and if you put 0 it`ll show the strings
    if (1) {
//print the values for debugging
      Serial.println(value1);
      Serial.println(value2);
      Serial.println(value3);
      Serial.println(value4);
      Serial.print("\n");
      delay(1000);
    } else {
//print the strings to flash
      if (value1 > 300 && value1 < 700) Serial.print("video1\n");
      if (value2 > 500 && value2 < 800) Serial.print("video2\n");
      if (value3 > 300 && value3 < 800) Serial.print("video3\n");
      if (value4 > 400 && value4 < 800) Serial.print("video4\n");

    }
}

Now, our Flash code contains a bunch of classes. The main goal of the whole Flash project is: 1. to be able to read the string sent by Arduino and play an embedded video according to which string; 2. Arrange the video display accordingly with the quantity of videos triggered by the sensors attached to Arduino. 3. Play all of that in fullscreen mode.

Flash Codes:
Main.as
 package  {

import flash.display.MovieClip;
import flash.events.Event;
import fl.video.FLVPlayback;
import fl.video.VideoScaleMode;
import flash.display.StageDisplayState;
import flash.display.StageScaleMode;
import fl.video.VideoEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import fl.video.VideoAlign;

public class Main extends MovieClip {

public var arduinoHandler:ArduinoHandler = new ArduinoHandler();
private var videos:Vector.<FLVPlayback>;

public function Main() {
arduinoHandler.addEventListener(ArduinoEvent.ERROR, showError);
addEventListener(Event.ADDED_TO_STAGE,startStuff);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDebugger);

videos = new Vector.<FLVPlayback>();
for (var i:uint = 0; i < 4; i++) {
var vid:FLVPlayback = new FLVPlayback();
videos.push(vid);
vid.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO;
vid.autoPlay = false;
vid.fullScreenTakeOver = false;
vid.addEventListener(VideoEvent.STATE_CHANGE, vidChange);
vid.align = VideoAlign.TOP;
}
videos[0].source = "video1.flv";
videos[1].source = "video2.flv";
videos[2].source = "video3.flv";
videos[3].source = "video4.flv";
arduinoHandler.addEventListener(ArduinoEvent.INBOUND, listen);
}

private function vidChange(e:VideoEvent):void {
var playingVids:Vector.<FLVPlayback> = new Vector.<FLVPlayback>();
for each (var vid:FLVPlayback in videos) {
if (vid.playing) {
playingVids.push(vid);
addChild(vid);
} else if (contains(vid)) removeChild(vid);
}

if (playingVids.length == 1) {
playingVids[0].width = stage.stageWidth;
playingVids[0].height = stage.stageHeight;
playingVids[0].registrationX = 0;
playingVids[0].registrationY = 0;
} else if (playingVids.length == 2) {
playingVids[1].registrationX = playingVids[0].registrationX = 0;
playingVids[0].registrationY = 0;
playingVids[1].width = playingVids[0].width = stage.stageWidth;
playingVids[1].registrationY = playingVids[1].height = playingVids[0].height = stage.stageHeight/2;
} else if (playingVids.length == 3) {
playingVids[2].registrationX = playingVids[0].registrationX = 0;
playingVids[1].registrationY = playingVids[0].registrationY = 0;
playingVids[1].registrationX = playingVids[2].width = playingVids[1].width = playingVids[0].width = stage.stageWidth/2;
playingVids[2].registrationY = playingVids[2].height = playingVids[1].height = playingVids[0].height = stage.stageHeight/2;
} else if (playingVids.length == 4) {
playingVids[2].registrationX = playingVids[0].registrationX = 0;
playingVids[1].registrationY = playingVids[0].registrationY = 0;
playingVids[3].registrationX = playingVids[1].registrationX = playingVids[3].width = playingVids[2].width = playingVids[1].width = playingVids[0].width = stage.stageWidth/2;
playingVids[3].registrationY = playingVids[2].registrationY = playingVids[3].height = playingVids[2].height = playingVids[1].height = playingVids[0].height = stage.stageHeight/2;
}

}

private function keyDebugger(e:KeyboardEvent):void {
if (e.ctrlKey) switch (e.keyCode) {
case Keyboard.NUMBER_1: videos[0].stop(); break;
case Keyboard.NUMBER_2: videos[1].stop(); break;
case Keyboard.NUMBER_3: videos[2].stop(); break;
case Keyboard.NUMBER_4: videos[3].stop(); break;
case Keyboard.A: videos[0].stop(), videos[1].stop(), videos[2].stop(), videos[3].stop(); break;
}
else switch (e.keyCode) {
case Keyboard.NUMBER_1: videos[0].play(); break;
case Keyboard.NUMBER_2: videos[1].play(); break;
case Keyboard.NUMBER_3: videos[2].play(); break;
case Keyboard.NUMBER_4: videos[3].play(); break;
case Keyboard.A: videos[0].play(), videos[1].play(), videos[2].play(), videos[3].play(); break;
case Keyboard.ENTER: stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE; break;
}
}

private function listen(e:ArduinoEvent):void {
switch (e.data as String) {
case "video1": videos[0].play(); break;
case "video2": videos[1].play(); break;
case "video3": videos[2].play(); break;
case "video4": videos[3].play(); break;
default: trace((e.data as String));
}
}

private function startStuff(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE,startStuff);
arduinoHandler.start();
stage.scaleMode = StageScaleMode.EXACT_FIT;
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}

private function showError(e:ArduinoEvent):void {
trace(e.data);
}
}
}

ArduinoHandler.as
package {
import flash.events.Event;
import flash.net.Socket;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.utils.Endian;
import flash.system.Security;
import flash.events.EventDispatcher;

public class ArduinoHandler extends EventDispatcher {

static private const _proxyAddress:String = "127.0.0.1";
private static const EOL_DELIMITER:String = "\n";
static private const _proxyPort:uint = 5331;
private var _socket:Socket;
private var buffer:String = "";

public function start():void {
_socket = new Socket();
_socket.addEventListener( Event.CONNECT, onConnect );
_socket.addEventListener( Event.CLOSE, onClose );
_socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );
_socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError );
_socket.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
_socket.endian = Endian.LITTLE_ENDIAN;
_socket.connect(_proxyAddress, _proxyPort);
}
private function onConnect(e:Event):void {
dispatchEvent(new ArduinoEvent(ArduinoEvent.READY));
}
private function onSocketData(event:ProgressEvent):void {
var data:String = _socket.readUTFBytes(_socket.bytesAvailable);
buffer +=  data;
var msg:String;
var index:int;
while ((index = buffer.indexOf(EOL_DELIMITER)) > -1) {
msg = buffer.substring(0,index);
buffer = buffer.substring(index + 1);
dispatchEvent(new ArduinoEvent(ArduinoEvent.INBOUND, msg));
}
}
public function sendMessage(message:String):void {
if (! _socket.connected) {
dispatchEvent(new ArduinoEvent(ArduinoEvent.ERROR, "You must be connected to send a command to the Arduino."));
return;
}
_socket.writeUTFBytes(message);
_socket.flush();
}

private function onClose(event:Event):void {
dispatchEvent(new ArduinoEvent(ArduinoEvent.CLOSED));
}

private function onIOError(event:IOErrorEvent):void {
dispatchEvent(new ArduinoEvent(ArduinoEvent.ERROR, "IOErrorEvent : " + event.text));
}
private function onSecurityError(event:SecurityErrorEvent):void {
dispatchEvent(new ArduinoEvent(ArduinoEvent.ERROR, "SecurityErrorEvent : " + event.text));
}
}
}

ArduinoEvent.as

package  {
import flash.events.Event;
public class ArduinoEvent extends Event {
public var data:Object;
public static const INBOUND:String = "inbound";
public static const READY:String = "ready";
public static const CLOSED:String = "closed";
public static const ERROR:String = "error";

public function ArduinoEvent(type:String, _data:Object = null) {
data = _data;
super(type);
}
}
}

No comments:

Post a Comment