Arduino‎ > ‎

Arduino to Flash communications

Last edited 02/08/2009

This was originally posted on the TeamPaulC blog, that blog entry will not be updated, but this page will be updated as required.

There are quite a few posts about getting communicating between an Arduino and Flash, but none that put it ALL in one place, so here's a quick tutorial. :)

OBJECTIVE
Setup two way communications between an Arduino Duemilanove and an Adobe AIR application written in FLEX. We will setup a photocell and two LEDs. The Arduino will sample the photocell every 2 seconds and send the results to the Flash application. The Flash application will graph the data from the Arduino and have three buttons that will toggle the LEDs on the Arduino and turn them both off. Useless, but it shows that it works. :) The protocol is SUPER basic, but again, its proof of concept.

HARDWARE SETUP
Connect one end of an orange LED to pin 10 of your Arduino the other to ground via the proper sized resistor.
Connect one end of a red LED to pin 12 of your Arduino the other to ground via the proper sized resistor. If you aren't sure of the proper resistor size you can use this calculator, or just use 120 ohms
Connect a photocell (Radio Shack 276-1657) to pin 5 of your Arduino like this:

SOFTWARE SETUP
Adobe AIR applications do not have access to the local machines serial port, so we will setup a proxy to proxy requests to and from the serial port to a TCP port on the local machine.

Download serial proxy and unzip it to a folder.
Edit the file serproxy.cfg and make sure that you have a line for the serial port that your Arduino is using. My Arduino is on com6 so I have the line
net_port6=5336
that means that any software trying to connect to my computer on TCP port 5336 will be proxied through to com6. You can get your serial port from the Arduino software menu "Tools", "Serial Port".
Run serialproxy.exe
Keep in mind, that if you are monitoring your serial port in the Arduino software, then serialproxy wont work.


Arduino Code

/*
* reads phototransistor
* sends to serial monitor
*/
#include <_avr_035.h>
#define orangeLED PORTB, 4
#define redLED PORTB, 2
#define SAMPLE_RATE 2000 // milleseconds between adc reads

int photoPin = 5;
int level = 0;
int sampleRate = 2000; // ms between light readings
uint8_t incomingByte = 0;
unsigned long currentTime = millis();
unsigned long startTime = currentTime;

void setup()                    // run once, when the sketch starts
{
SETBITMASK(DDRB, 0x14);
Serial.begin(57600);

Serial.println("Started...");
}

void loop()                     // run over and over again
{
currentTime = millis();
if( currentTime - startTime >= SAMPLE_RATE )
{
level = analogRead(photoPin);
Serial.print(level, DEC);
startTime = millis();
}
if (Serial.available() > 0) {
// we have data on the serial line, get it
incomingByte = Serial.read();
switch (incomingByte) {
case 255:
  C_FLIPBIT(orangeLED);
  break;
case 127:
   C_FLIPBIT(redLED);
   break;
default:
   C_CLEARBIT(orangeLED);
   C_CLEARBIT(redLED);
   break;
}
}
}



Flex Code

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init();"  width="600" height="600">

<mx:Script>
 <![CDATA[
 import mx.collections.ArrayCollection;
 import flash.net.Socket;
 import flash.events.*;

 public var arduinoSocket:Socket;
 [Bindable]
 internal var transactions:ArrayCollection = new ArrayCollection;
 internal var maxItems:int = 100;

 private function init():void
 {
  // the port "5336" is the port as set in the serproxy.cfg line
  //   net_port6=5336
  arduinoSocket = new Socket("localhost",5336);
  arduinoSocket.addEventListener(ProgressEvent.SOCKET_DATA,arduinoReadHandler);
 }
 private function arduinoReadHandler(event:ProgressEvent):void
 {
  var intensity:String = arduinoSocket.readUTFBytes(arduinoSocket.bytesAvailable)
  if (transactions.length >= maxItems)
  {
   transactions.removeItemAt(0);
  }
  transactions.addItem(intensity);
  lstTransactions.verticalScrollPosition=lstTransactions.maxVerticalScrollPosition + 1;
 }
 private function toggleLed(command:int):void
 {
  arduinoSocket.writeByte(command);
  arduinoSocket.flush();
 }

 ]]>
 </mx:Script>
<mx:LineChart x="2" y="180" id="lcTransactions"
 width="590" height="400" dataProvider="{transactions}"  showDataTips="true">
 <mx:series>
  <mx:LineSeries />
 </mx:series>
</mx:LineChart>
<mx:Button x="164" y="9" label="Toggle RED LED" id="btnToggleRed" click="toggleLed(127);"/>
<mx:Button x="164" y="39" label="Toggle Orange LED" id="btnToggleOrange" click="toggleLed(255);"/>
<mx:Button x="164" y="69" label="Turn off LEDs" id="btnOffLeds" click="toggleLed(1);"/>
<mx:List x="10" y="0" id="lstTransactions" dataProvider="{transactions}" width="120"></mx:List>
</mx:WindowedApplication>




Make sure that serialproxy is runing.
Load the Arduino code into your Arduino.
Compile and run the Flex AIR code.

I apologize for the non Arduino code in the sample, but I like to do some things with the native AVR C code. Well, its all native AVR C code, Arduino just has nicely packaged libraries.
If you don't have AVR035.h, here it is:

AVR_035.h

#ifndef _AVR035_H_
#define _AVR035_H_

// from AVR035: Efficient C Coding for AVR

#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))

#define SETBITMASK(x,y) (x |= (y))
#define CLEARBITMASK(x,y) (x &= (~y))
#define FLIPBITMASK(x,y) (x ^= (y))
#define CHECKBITMASK(x,y) (x & (y))

#define VARFROMCOMB(x, y) x
#define BITFROMCOMB(x, y) y

#define C_SETBIT(comb) SETBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CLEARBIT(comb) CLEARBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_FLIPBIT(comb) FLIPBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CHECKBIT(comb) CHECKBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))

#endif


If AVR035.h confuses you, then read this:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37871
and this
http://www.atmel.com/dyn/resources/prod_documents/doc1497.pdf

When you run the AIR application you should see a graph at the bottom that is graphing your photocell data live as well as a text area at the top with the raw data and three buttons for manipulating the LEDs. Turn a light off and on and note changes. But remember that we are only sampling the photocell every 2 seconds.

Yes, its a contrived project, but it shows bidirectional communication between an Arduino and an AIR application.

02/06/09 Update.
I accidentally left the AIR application running all night, and predictably "bad things" happened. The transactions array had no limit so it grew all night long. I updated the FLEX code above and added a variable "maxItems" which I have defaulted to 100.

Comments