Home » Arduino, Flex 3, _Featured

Arduino and Flex: connect a joystick to your application

29 October 2009 3 Comments

In this sample, we’ll connect a joystick to a Flex application.
Using Firmata 2.* and as3Glue library, your Arduino board can then communicate with your Flash/Flex/Air application.

The final result :

Required Software:

1) Flex 3.*

2) as3Glue: an actionscript library that allows to connect a Flash application with your Arduino extending the Socket class

3) Last Firmata 2 version: a protocol for communicating with microcontrollers

4) A serial proxy (included with AS3Glue but you need to configure it modifying the .cfg file)

ARDUINO SKETCH

Connect a joystick to your arduino board (you can get more info in the article Arduino: control a LED and one servo motor using a joystick)

Upload the Firmata firware to your microcontroller.
I used this one:

/* This firmware supports as many analog ports as possible, all analog inputs,
 * four PWM outputs, and two with servo support.
 *
 * This example code is in the public domain.
 */
#include <Firmata.h>
#include <Servo.h>
 
/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/
 
/* servos */
Servo servo9, servo10; // one instance per pin
/* analog inputs */
int analogInputsToReport = 0; // bitwise array to store pin reporting
int analogPin = 0; // counter for reading analog pins
/* timer variables */
unsigned long currentMillis;     // store the current value from millis()
unsigned long nextExecuteMillis; // for comparison with currentMillis
 
 
/*==============================================================================
 * FUNCTIONS                                                                
 *============================================================================*/
 
void analogWriteCallback(byte pin, int value)
{
    switch(pin) {
    case 9: servo9.write(value); break;
    case 10: servo10.write(value); break;
    case 3: 
    case 5: 
    case 6: 
    case 11: // PWM pins
        analogWrite(pin, value); 
        break;
    }
}
// -----------------------------------------------------------------------------
// sets bits in a bit array (int) to toggle the reporting of the analogIns
void reportAnalogCallback(byte pin, int value)
{
    if(value == 0) {
        analogInputsToReport = analogInputsToReport &~ (1 << pin);
    }
    else { // everything but 0 enables reporting of that pin
        analogInputsToReport = analogInputsToReport | (1 << pin);
    }
    // TODO: save status to EEPROM here, if changed
}
 
/*==============================================================================
 * SETUP()
 *============================================================================*/
void setup() 
{
    Firmata.setFirmwareVersion(0, 2);
    Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
    Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
 
    servo9.attach(9);
    servo10.attach(10);
    Firmata.begin(9600);
}
 
/*==============================================================================
 * LOOP()
 *============================================================================*/
void loop() 
{
    while(Firmata.available())
        Firmata.processInput();
    currentMillis = millis();
    if(currentMillis > nextExecuteMillis) {  
        nextExecuteMillis = currentMillis + 19; // run this every 20ms
        for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
            if( analogInputsToReport & (1 << analogPin) ) 
                Firmata.sendAnalog(analogPin, analogRead(analogPin));
        }
    }
}

FLEX CODE

1) Create a new Flex Project and link it to the as3Glue AP folder net.eriksjodin .

2) Launch your serial proxy server to allow the communication between Arduino and your swf file

3) Use or modify following script to get values from Arduino and update the Flex interface.
See the video above to see how it should work.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="vertical"
	creationComplete="init()">
 
	<mx:Script>
		<![CDATA[
			import net.eriksjodin.arduino.Arduino;
			import net.eriksjodin.arduino.events.ArduinoEvent;
			import net.eriksjodin.arduino.events.ArduinoSysExEvent;
			import flash.events.Event;
 
			private var a:Arduino;
			private var numEvents:Number=0;		
 
			private function init():void {
 
 
				// Set the PORT of your Arduino board
				a = new Arduino("127.0.0.1", 5335); // Port 5 (First Arduino Board)
				//a = new Arduino("127.0.0.1", 5336); // Port com 6 (Second Arduino Board)
 
				// 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
			private function onSocketConnect(e:Object):void {
 
				trace("Socket connected!");
 
				// request the firmware version
				a.requestFirmwareVersion();
			}
 
 
			// triggered when a serial socket connection has been closed
			private function onSocketClose(e:Object):void {
				trace("Socket closed!");
			}
 
 
			// trace out data when it arrives...	
			private function onReceiveAnalogData(e:ArduinoEvent):void {
 
 
				switch(e.pin) {
 
					case 4:
						vSlider.value = e.value
						break;
 
					case 5:
						hSlider.value = e.value
						break;
 
					default:
						trace((numEvents++) +" Analog pin " + e.pin + " on port: " + e.port +" = " + e.value);
						break;
				}
 
 
			}
 
			// trace out data when it arrives...
			private function onReceiveDigitalData(e:ArduinoEvent):void {
 
				trace((numEvents++) +" Digital pin " + e.pin + " on port: " + e.port +" = " + e.value);
				/* 
				if (e.pin == 7) {
					a.writeDigitalPin(13, Arduino.LOW);
					trace("Digital pin 4 is: " + a.getDigitalData(4));	
				} 
				*/
			}
 
 
			// trace incoming sysex messages
			private function onReceiveSysExMessage(e:ArduinoSysExEvent):void {
				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.
			private 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();
 
			}
 
 
 
			private function initArduino():void {
 
				// set a pin to PWM
				//a.setPinMode(11, Arduino.PWM);
 
				// Set a pin to INPUT
				a.setPinMode(7, Arduino.INPUT);
 
				// set a pin to high
				// a.writeDigitalPin(13, Arduino.HIGH);
 
				// enable reporting for digital pins
				a.enableDigitalPinReporting();
 
				// disable reporting for digital pins
				//a.disableDigitalPinReporting();
 
				// enable reporting for an analog pin
				a.setAnalogPinReporting(4, Arduino.ON);
				a.setAnalogPinReporting(5, Arduino.ON);
 
 
				// write to PWM (0..255)
				//a.writeAnalogPin(11, 255);
 
				// trace out the most recently received data
				//	trace("Analog pin 3 is: " + a.getAnalogData(4));
				//trace("Digital pin 4 is: " + a.getDigitalData(4));	
 
			}
		]]>
	</mx:Script>
 
	<mx:VSlider x="51" y="74" id="vSlider" minimum="0" maximum="1023" snapInterval="2" allowTrackClick="true"/>
	<mx:HSlider x="51" y="74" id="hSlider" minimum="0" maximum="1023" snapInterval="2" allowTrackClick="true"/>
 
</mx:Application>

Related content:
- Arduino and Flash: control your Flash applications from external hardware
- Arduino: control a LED and one servo motor using a joystick

3 Comments »

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.