Arduino #2 : Flash, socket et Processing


arduino_header

Suite de nos expérimentations! Cette fois on va parler de Flash. Nous allons voir comment faire un petit serveur qui écoute le port série, et qui renvoie les infos sur un socket que nous écouterons avec Flash. C’est parti!

Un serveur série avec Processing


Nous allons reprendre le code Processing précédent, et faire quelques modifications. Le principe est d’utiliser la librairie processing.net pour créer et gérer notre serveur. Nous devons modifier légèrement les fonctions setup() et draw() de notre code.

setup


Dans l’initialisation, nous devons créer notre serveur. Il suffit tout simplement de définir un port (ici le 10001) :

import processing.net.*;
import processing.serial.*;

Serial port;
Server socket;
void setup() {

  println( Serial.list() );

  String usbPort = Serial.list()[0];
  port = new Serial(this, usbPort, 9600);

  socket = new Server( this, 10001 );

  port.bufferUntil('\n');

  port.write(65);
}

dessine moi un serveur


Nous allons enlevé le code concernant la scène 3D. C’est une applet serveur que l’on veut tout de même! Enfin moi je l’enlève.
Donc, nous allons nous servir de la fonction draw pour pousser les valeurs de l’accéléromètre au travers du socket. Je n’envoie que les valeur en X et Y, vue que l’on n’a pas (encore) de gyroscope associé à l’axe Z. On termine l’écriture sur le serveur par un byte de valeur 0. Histoire de préciser que, oui, c’est fini et qu’il peut transmettre. Je conserve le delay de 100 millisecondes, pour ne pas saturer Flash Player par des tonnes de valeurs.

void draw() {

  socket.write( xvalue+","+yvalue );
  socket.write( zero );

  delay(100);
}

Aller hop ! Le code du serveur complet :

import processing.net.*;
import processing.serial.*;

Serial port;
Server socket;

byte zero = 0;

float xvalue = 0;
float yvalue = 0;
float zvalue = 0;

void setup() {

  println( Serial.list() );

  String usbPort = Serial.list()[0];
  port = new Serial(this, usbPort, 9600);

  socket = new Server( this, 10001 );

  port.bufferUntil('\n');

  port.write(65);
}

void draw() {

  socket.write( xvalue+","+yvalue );
  socket.write( zero );

  delay(100);
}

void serialEvent(Serial port) {

  String serialStr = port.readStringUntil('\n');
  serialStr = trim(serialStr);

  int values[] = int(split(serialStr, ','));

  if( values.length == 3 ) { 

    xvalue =calculate( values[0], 512 );
    yvalue = -calculate( values[1], 500 );

  }
}

float calculate( float returnValue, int baseValue ) {

  float diff = returnValue - baseValue;
  returnValue = (diff*90) / 115; 

  // to radian
  returnValue = PI*returnValue/180;

  // trunc value
  returnValue = round( returnValue*100 );
  returnValue = returnValue /100;

  return returnValue;
}

Flaaaaaaaaash


Côté Flash, finalement c’est super simple. Un socket XML, connecté sur le port 10001, avec l’adresse local (127.0.0.1). A chaque réception de données, nous découpons la valeur reçue pour extraire les valeurs X et Y provenant du serveur Processing :

package
{
    import flash.events.DataEvent;
    import flash.events.Event;
    import flash.events.SecurityErrorEvent;
    import flash.net.XMLSocket;

    public class ArduinoSocket
    {
        private var _socket : XMLSocket;

        public function connect() : void
        {
            _socket = new XMLSocket();

            _socket.connect("127.0.0.1", 10001);
            _socket.addEventListener(Event.CONNECT, onConnect );
            _socket.addEventListener(DataEvent.DATA, onData);
            _socket.addEventListener(
                        SecurityErrorEvent.SECURITY_ERROR, onSecurityError);

        }

        protected function onConnect( event : Event ) : void
        {
            //connecté;
        }

        protected function onData( event : DataEvent ) : void
        {
            var str : String = event.data;
            var dataAr : Array = str.split(",");
            var pitch : Number = Number( dataAr[0] );
            var yaw : Number = Number( dataAr[1] );

            // faites ce que vous voulez ici
        }

        protected function onSecurityError( event : SecurityErrorEvent ) : void
        {
            //y'a une erreur
        }
    }
}

Et pour AIR(2)


Processing vous permet de compiler votre code en applet Java, mais aussi en .EXE, .DMG, .RPM. Comme ça on est bien. Le truc cool, c’est qu’avec AIR2, vous pouvez, via un packaging natif de votre application, embarquer, et lancer votre serveur directement depuis AIR (via native process, tout çà). Et c’est bien! du coup vous pouvez avoir un petit serveur qui écoute le port série, directement intégrable dans vos applications. Par extension, vous pouvez prévoir plein de choses avec cette base de petit serveur (un point d’écoute de vos périphériques bluetooth par exemple?)

Bonus track


Aller hop ! Je me jette à l’eau. Une petite séquence pour vous montrer que ce n’est pas du flan!



(Ouai bon j’aurais pu faire un gif animé… Mais la méthode old school marche pas si mal)

Pour finir


Voilà la fin de cette mise en jambe dans l’univers Arduino. J’aurais pu avoir un exemple plus « graphique » que le simple cube… Mais je laisse libre court à votre imagination! Pour la suite, et en fonction de vos retours, je pense aller plus loin dans ce montage analogique : dans un premier temps en ajoutant un gyroscope électronique, et puis j’aimerai bien vous proposer un tuto sur Arduino et les communications sans fil, notamment via une interface XBee. A vous!


Tags: ,


6 commentaires ...

» RSS des commentaires
  1. Hervé /
    -->

    Si c’est pas beau… Il faudrait une deuxième vie pour expérimenter tout ce qu’on peut faire avec ça !

  2. yoy /
    -->

    je kiffe le t-shirt :)

  3. Didier Brun /
    -->

    Merci, super article, ça donne autant envie de découvrir Arduino que Processing !

  4. y_nk /
    -->

    Hello,

    J’aurai aimé savoir si tu connaissais as3glue, la lib flex pour Arduino et ce que tu en pensais ?

    http://code.google.com/p/as3glue/

    Article génial :)

  5. Fabien /
    -->

    @y_nk oui je connais as3glue. C’est vraiment bien. Ici je voulais montrer comment faire un bidule « from scratch ». Et puis l’intérêt est de pouvoir créer un serveur série maison, utilisable comme on le veut dans nos applications (avec AIR2 et les package natif surtout), sans avoir a utiliser servproxy par exemple. Surtout que ce n’est pas bien compliqué, et qu’on évite de surcharger la mémoire de l’EEPROM avec le firmdata utilisé par as3glue.

  6. mrbbp /
    -->

    Euh, bonjour…
    C’est méga super ce truc (en vrai !) sauf que j’arrive pas à lancer cette belle appli via les nativeprocess de air…
    un complément d’infos m’sieur, sioupé


Sois pas timide...


Bad Behavior has blocked 271 access attempts in the last 7 days.