under construction - send comments!

Connecting Flash with Arduino

TinkerProxy
Last updated May 2007

tinkerproxy.png

To connect Flash and Arduino using the code provided, you’ll need to download TinkerProxy from tinker.it

When starting to work with more advanced physical computing and micro-controllers, one of the first things to do is set up a serial connection between the physical device and Flash.

In this example we’re using the Arduino micro-controller and a small proxy application called TinkerProxy. An overview of interfacing Arduino with Flash is also available on the Arduino Playground website and more information on using serial ports and XML sockets with Flash as well as Processing are available on Tom Igoe’s website and in his book Making Things Talk.

NOTE: Flash can also talk to Arduino. To do this you’ll need to use another proxy application instead of TinkerProxy such as serproxy from Arduino, SerialServer by Dan O’Sullivan, or a host of others available on the Arduino Playground site. These programs are a bit more complicated, which is why we start out using TinkerProxy.

Overview

This is actually a simple process to get the communication started, but there are a few steps involved. Here’s a list of what we’ll have at the end of the tutorial:

  1. Code running on the Arduino that sends serial data over USB
  2. Serial to socket application running on computer
  3. Flash code to read the incoming data

First things first

First we want to connect our Arduino micro-controller via USB to the computer and upload our Arduino code. This step is no different than uploading Arduino source code for any other use,

Be sure your baud rates are set to the same speed.

Arduino Code

Here is the source code that goes in your Arduino file.

/* ARDUINO CODE ////////////////////////////////////////*/

int butterfly1 = 5;

void setup() {
  //initialize the serial port
  Serial.begin(115200);
}

void loop() {

  // send the value to the external application.
  // Notice how we are using Serial.print instead of Serial.println
  Serial.print(”first”);
  Serial.print(61, BYTE);
  Serial.print(butterfly1);

  //Flash needs a 0 as the item delimiter, this needs to be sent separately.
  Serial.print(0, BYTE);

  while(1) {
   delay(1);
  }

}

From Stephen Wilson:

/* ————————————————
* General Purpose computer serial IO — ver 41 4/07
* copyleft Stephen Wilson http://userwww.sfsu.edu/~swilson/
* Created October, 2006
* The code activates most arduino functions
* (digital in, digital out, analog in, analog out)
* by sending ascii strings via serial communication
* It can be used by any program that can send & receive strings.
* For example, I use it in Director with the serial Xtra.
* The code lets the Arduino board function as an I/O device for the computer
* Your host program will need to prepare the strings to send
* and extract the data from the incoming text
*====
* send “A” = read Arduino Analog in pins into computer
* (Send ascii “A”. Arduino returns a sequence of
* lines with ascii encoded number of the current analog pin value 0-1024
* eg 0 398
* 1 599
* 2 888
* 3 0
* 4 22
* 5 222
* and “$” to indicate end )
*====
* send “B” = output analog values to arduino pins 9,10,11
* compose a string with “B” followed by 3 ascii equivalents
* (0-255) of values to be send
* eg “B”ascii(128)ascii(255)ascii(10)
*====
* Send “E” = read Digital pins in from arduino into computer
* You need to the adjust header to indicate which pin starts
* the digital output seqquence. Eg declare pin 8 to start output
* means that 2-7 will be input and 8-13 will be output.
* Arduino returns a string starting with letter F
* followed by H’s and L’s to indicate state followed by $ to end
* eg FHLLLHH$ - pin 2=high 3= low etc…7=high)
*====
* Send “D” = send Digital from computer to control arduino digital pins
* adjust header indicates which range of digital pins to be declared output eg 8-13
* Send ascii “D” followed sequence of letters to indicate desired values
* (eg DHLLLHH pin 8 = make high 9=low…13= high)
*====
* This routine based on SERIAL COM and other examples
* SERIAL COM - HANDELING MULTIPLE BYTES inside ARDUINO - 04_function development
* by beltran berrocal created 16 Decembre 2005;
* copyleft 2005 Progetto25zero1
* ————————————————— */

char serInString[11]; // array that will hold the bytes of the incoming string.
// you need to adjust so it can hold the max values to be expected
// eg if you declared 7 digital in it would be 8 to
// include first id letter and the following 7 H’s & L’s
char serOutString[11];
// array to hold string of arduino read values of digital pin
char anOutString[6];
// array hold output of analog out — not used

int val=0; // temporary value for inputs & outputs
int val4=0; //temp
char val2=2;
char val3=0;
char val1=0;
int p=0; // temporary value for pin
int digout = 8; // start pin for digital out sequence
// here 8-13 will be output and 2-7 will be read in
// can be changed depending on your needs
int digseq = 6; //temp value for number of output pins

//read a string from the serial and store it in an array
//you must supply the array variable
void readSerialString (char *strArray) {
int i = 0;
if(Serial.available()) {
//Serial.print(”reading Serial String: “); //optional: for confirmation
while (serialAvailable()){
strArray[i] = Serial.read();
i++;
// Serial.print(strArray[(i-1)]); //optional: for confirmation
}
// Serial.println(); //optional: for confirmation
}
}

// cleanout the arrays
void cleanup(char *strArray){
for (int i=0; i= 8; i++){
serInString[i]=0;
serOutString[i]=0;
}
}

//Print the whole string at once - will be performed only if thers is data inside it
//you must supply the array variable
void printSerialString(char *strArray) {
int i=0;
if (strArray[i] != 0) {
while(strArray[i] != 0) {
//Serial.print( strArray[i] );
strArray[i] = 0; // optional: flush the content
i++;
}
}
}

//utility function to know wither an array is empty or not
boolean isStringEmpty(char *strArray) {
if (strArray[0] == 0) {
return true;
}
else {
return false;
}
}

void setup() {
Serial.begin(9600);
// digout starts at digout (8 in this example)
for (int i=digout; i <= 13; i++){
pinMode(i, OUTPUT);
}
for (int i=2; i <= digout-1; i++){
pinMode(i, INPUT);
}
}

void loop () {
//simple feedback from Arduino that it is working - optional
//Serial.println("Hello World");

//read the serial port and create a string out of what you read
readSerialString(serInString);

if( isStringEmpty(serInString) == false) {
//it will do the following if there actually is some info

//--------
// "D" = code for digital out to arduino looks for D as first
// character in the input string (ascii 68)
// then looks for H & L letters
// for example computer sends DHLHHLL
if (serInString[0]==68)
digseq= 13-digout+1; // how many output pins

{

for (int i=1; i <= digseq; i++){
p = i+digout-1; // output to the right pins
// for example if output starts at pin 8
// then second item in string will be applied to pin 1+7
val=serInString[i]; // what is the letter
// if it is an H (high - ascii 72- then subtract 71 to make high)
//
// if it is a L (low - ascii 76- then subtract 76 to make low)
if (val == 72)
{
val = 1;
}
else
{
val=0;
}

digitalWrite(p, val);// output to the pin

}
//Serial.println("digoutconfirm");
}

//-------
// "E" (ascii69) = code for read & send arduino digital state to computer
if (serInString[0]==69) // just send an E from computer

{

serOutString[0] =70; // F for return to computer
// read pins from 2 to one below digout
serOutString[1] =65;

for (int i=2; i <= digout-1; i++){
val = digitalRead(i);
if (val == HIGH)
{
//val = digitalRead(i);
//val4=i-1;
serOutString[i-1]=72; //H for high
// Serial.println("high");
}

if (val == LOW)
{
// val = digitalRead(i);
//val4=i-1;
serOutString[i-1]=76; //L for low
// Serial.println("low");
}

}

Serial.print(serOutString);
Serial.println("$");// for end
}

//-----------
// A (asci65) = code for send analog read pins to computer
if (serInString[0]==65)
{
//Serial.println("F");
for (int i=0; i <= 5; i++){
val = analogRead(i);
val2=val/4;
anOutString[i]=val2;
Serial.println(i);
Serial.println(val,DEC);
//Serial.println(val2,DEC); // 1 byte version
}

//Serial.println(anOutString);
Serial.println("$");
}

//----------
// B = code for analog sent to control arduino analog out
if (serInString[0]==66)
{
val1=serInString[1]; //pwm0 - pin9
val2=serInString[2]; //pwm1 - pin10
val3=serInString[3]; //pwm2 - pin11
//Serial.println(val1);
// Serial.println(val2);
//Serial.println(val3);
analogWrite(9,val1);
analogWrite(10,val2);
analogWrite(11,val3);
//Serial.println("anaconfirm");
}

// Serial.println();
}

// Serial.println();
//cleans out arrays
for (int i=0; i <= 11; i++){

serInString[i]=0;
serOutString[i]=0;
anOutString[i]=0;

}
//slows down the visualization in the terminal
delay(200);
}

tink.png

Flash Code

Here is the source code that goes in your Flash file.

/* FLASH CODE ////////////////////////////////////////*/

stop();

_root.butterflyNum1 = 0;

//———————————————————————— Basic Arduino

import Arduino;

var port:Number = 5333;// What socket port are we configured to use?
// See the net_port entries from serproxy.cfg

// Create a custom object from Flash’s XMLSocket
var a:Arduino = new Arduino(port);

//———————————————————————— Listeners

// You can trigger custom actions by adding listners to the Arduino object. For example, you can setup your
// ActionScript code to run a setup function when Flash successfully connects to the socket listener

aListener = new Object();

aListener.onConnect = function() {
  setupBoard();
};

aListener.onReceiveData = function(evtObj:Object) {
  //Store the received data in a string
  var str = evtObj.data;

  trace(”Arduino says — “+str);

  _root.butterflyNum1 = str;

  play();

  var queryStr:String = str;

  var butterflies:LoadVars = new LoadVars();

  butterflies.decode(queryStr);

  _root.butterflyNum1 = butterflies.first;

  trace(_root.butterflyNum1);
};

// Binds your custom listeners to the Arduino object (a)
a.addEventListener(”onConnect”,aListener);
a.addEventListener(”onReceiveData”,aListener);

From DanO:

Flashes XML Socket (don’t ask me why they call it an XML socket you don’t have to send XML) wants you to put a 0 character at the end of all your bytes to mark the end of transmission. This means that you cannot send a byte worth zero, only bytes 1-255 (remember to add something to getPins which tend to be 0 or 1). On the bright side, this can be handy if you are recieving multiple bytes. Basically the “onData” callback will not happen until it gets a zero byte which you can send at the end of all the data bytes to signify that they have all arrived. Flash will also append a zero byte with each call to the send method so on the serial device side, you will have to either ignore the zero character or use it as a demiliter as just described. In any case the SerialServer generally just passes the zero bytes back and forth without prejudice unless you use the Sub0ForChar parameter in which case it substitutes a 0 character every time it sees the character you specify with this parameter. For sending binary numbers you might look into the String.fromCharCode() command. Here is some very boring code from this fla or swf that you can just paste into the first frame of an emply flash movie.

createSocket
();

function createSocket () {
_root.createTextField(”inputlabel”,4,50,100,50,20);
inputlabel.text = “Input:”;
_root.createTextField(”outputlabel”,5,50,300,50,20);
outputlabel.text = “Output:”;
_root.createTextField(”inputer”,3,100,100,200,20);
_root.createTextField(”outputer”,2,100,300,200,20);
outputer.type = “input”;
outputer.border = true;
inputer.border = true;
serialServer = new XMLSocket ();
trace (”made it” + serialServer);
//127.0.0.1 is the same as “localhost” ie an alias to your local machine
//it is concievable to that you would want to connect from another machine and you would change this
serialServer.connect (”127.0.0.1″, 5333);
serialServer.onConnect = function (success) {
trace (”connected ” + success);
serialServer.send (”HOWDY FROM FLASH” + new Date().toString());
};
serialServer.onClose = function () {
trace (”closed”);
};
serialServer.onData = function (data) {
trace (”incoming” + data);
inputer.text = inputer.text + data;
};
outputer.onChanged = function () {
serialServer.send (outputer.text);
trace (”output” + outputer.text);
outputer.text = “”;
};
}

Here is some code fla swf for recieving the values of three sensors AS TEXT from a microcontroller and sending back the mouse position

createSocket ();

//Here is some code for recieving the values of three sensors from a microcontroller and sending back the mouse position:
function createSocket () {
myThing = _root.attachMovie(”circle”,”thing”,1);
myThing._y = 200;

serialServer = new XMLSocket ();
trace (”made it” + serialServer);
//127.0.0.1 is the same as “localhost” ie an alias to your local machine
//it is concievable to that you would want to connect from another machine and you would change this
serialServer.connect (”127.0.0.1″, 9001);
serialServer.onConnect = function (success) {
trace (”connected ” + success);
serialServer.send(”A”);
//serialServer.send (”HOWDY FROM FLASH” + new Date().toString());
};
serialServer.onClose = function () {
trace (”closed”);
};
serialServer.onData = gotSomething ;
}

function gotSomething(datar) {
//trace (datar + “incoming ” + datar.length + ” ” + datar.charCodeAt(0) + ” ” + datar.charCodeAt(1) + ” ” + datar.charCodeAt(2));
parts = datar.split(”,”)
if(parts.length >= 3){
myThing._x = number(parts[2]); //scale it up from 1-255 to stage witht
myThing._alpha = number(parts[1]); //scale it down from 1-255 to 0-100
myThing._width = 50 + number(parts[0])*50
myThing._height = 50 + number(parts[0])*50
}
mousePos = _root._xmouse;
serialServer.send(String.fromCharCode(mousePos));
}


Leave a code sample or comment

You must be logged in to post a comment.



under construction - send comments!