« Interactive Wall | Main | Other Related Projects - Alec Rippberger »

Final Project - Alec Rippberger


View image
This is the completed physical tree, allowing you to interact with the virtual tree through agitation.
View image
This is the switch that converts physical interaction into the digital realm. The center ball of aluminum foil is attached to a wire that is connected to digital pin 4 of the arduino. The coil of aluminum surrounding the ball is attached to a wire connected to arduino's ground. When the tree is agitated the ball makes contact with the coil completing a circuit and sending digital information to the arduino.

This digital information is then sent to a MacBook Pro computer using the firmata software uploaded to the arduino board. When the data reaches the computer it is converted by another program,serproxy, so that it can be interpreted by Adobe Flash. Flash then interprets the data using a library class known as AS3 Glue.

The flash actionscript code I used:

stop();
import flash.utils.*;
import net.eriksjodin.arduino.Arduino;
import net.eriksjodin.arduino.events.ArduinoEvent;
import net.eriksjodin.arduino.events.ArduinoSysExEvent;
import flash.utils.ByteArray;
import flash.events.Event;
var a:Arduino;
var numEvents:Number=0;
var leaf:uint=0;
var frame:uint=1;
var myTimer:Timer=new Timer(200);
myTimer.addEventListener("timer", checkLeaves);
myTimer.start();

// connect to a serial proxy on port 5331
a=new Arduino("127.0.0.1",5331);

// listen for connection
a.addEventListener(Event.CONNECT,onSocketConnect);
a.addEventListener(Event.CLOSE,onSocketClose);

// listen for firmware (sent on startup)
a.addEventListener(ArduinoEvent.FIRMWARE_VERSION, onReceiveFirmwareVersion);

// listen for data
a.addEventListener(ArduinoEvent.ANALOG_DATA, onReceiveAnalogData);
a.addEventListener(ArduinoEvent.DIGITAL_DATA, onReceiveDigitalData);

//listen for sysex messages
a.addEventListener(ArduinoSysExEvent.SYSEX_MESSAGE, onReceiveSysExMessage);

// triggered when a serial socket connection has been established
function onSocketConnect(e:Object):void {
trace("Socket connected!");
// request the firmware version
a.requestFirmwareVersion();

}

// triggered when a serial socket connection has been closed
function onSocketClose(e:Object):void {
trace("Socket closed!");
}

// trace out data when it arrives...
function onReceiveAnalogData(e:ArduinoEvent):void {
trace((numEvents++) +" Analog pin " + e.pin + " on port: " + e.port +" = " + e.value);
}

// trace out data when it arrives...
function onReceiveDigitalData(e:ArduinoEvent):void {
trace((numEvents++) +" Digital pin " + e.pin + " on port: " + e.port +" = " + e.value);
leaf=leaf+1;
}

// trace incoming sysex messages
function onReceiveSysExMessage(e:ArduinoSysExEvent) {
trace((numEvents++) +"Received SysExMessage. Command:"+e.data[0]);
}


// the firmware version is requested when the Arduino class has made a socket connection.
// when we receive this event we know that the Arduino has been successfully connected.
function onReceiveFirmwareVersion(e:ArduinoEvent):void {
trace("Firmware version: " + e.value);
if (int(e.value)!=2) {
trace("Unexpected Firmware version encountered! This Version of as3glue was written for Firmata2.");
}
// the port value of an event can be used to determine which board the event was dispatched from
// this is one way of dealing with multiple boards, another is to add different listener methods
trace("Port: " + e.port);

// do some stuff on the Arduino...
initArduino();
}

function initArduino():void {
trace("Initializing Arduino");

// set a pin to output
a.setPinMode(13, Arduino.OUTPUT);

// set a pin to high
a.writeDigitalPin(13, Arduino.HIGH);

// turn on pull up on pin 4
a.writeDigitalPin(4, Arduino.HIGH);

// set digital pin 4 to input
a.setPinMode(4, Arduino.INPUT);

// enable reporting for digital pins
a.enableDigitalPinReporting();

// disable reporting for digital pins
//a.disableDigitalPinReporting();

// enable reporting for an analog pin
a.setAnalogPinReporting(3, Arduino.ON);

// disable reporting for an analog pin
//a.setAnalogPinReporting(3, Arduino.OFF);

// set a pin to PWM
a.setPinMode(11, Arduino.PWM);

// write to PWM (0..255)
a.writeAnalogPin(11, 255);

// trace out the most recently received data
//trace("Analog pin 3 is: " + a.getAnalogData(3));
//trace("Digital pin 4 is: " + a.getDigitalData(4));

}

function checkLeaves(eventArgs:TimerEvent):void {
if (leaf>=10) {
nextFrame();
trace("increase");
if (leaf>1000) {
leaf=leaf-100;}
if (leaf>100) {
leaf=leaf-10;}
if (leaf>10) {leaf=leaf-1;}
leaf=leaf-1;

} else {prevFrame();
trace("decrease");
if (leaf>1000) {
leaf=leaf-100;}
if (leaf>100) {
leaf=leaf-10;}
if (leaf>10) {leaf=leaf-1;}
}

}


This code is a modified version of the "simpleIO.fla" example included in the AS3 Glue Class Package. I modified it in several ways:

  1. added "stop();" to the first line of code in order to stop any flash movieclips from running without input from the arduino.

  2. Imported the timer class so that I could use the timer functions

  3. Created a timer that would run a specific function every 2000 milliseconds

  4. Added and defined the variables "leaf" and "frame" to track the input received from the arduino. I later decided not to use the variable "frame" for its original purposes.

  5. Modified the "onRecieveDigitalData" to add 1 to the variable leaf

  6. created the "checkLeaves" function in which the amount of digital input is checked. If the leaf function is higher than a certain threshold the function advances the timeline to the next frame and reduces the amount of the variable "leaf". If the threshold has not been met and the frame is more than 1, the function will advance the timeline to the previous frame and reduce the amount of the variable "leaf".



This diagram shows how the information travels from the physical tree to the digital tree.
MAIWEB.jpg