zurück


Kommunikation Arduino Board zu Processing

Arduino Code


Um vom Arduino Board Daten an Processing zu schicken wird die serielle Schnittstelle des Boards verwendet. Diese ist über den USB-Seriell Wandler auf dem Board schon integriert.


Generell können über die serielle Schnittstelle des Boards Zeichenketten versendet werden:


Serial.print("Das ist eine Nachricht ohne Zeilenumbruch");


Serial.println("Das ist eine Nachricht mit Zeilenumbruch am Ende");


Damit diese Ausgabe auch funktionert muss in der setup() Funktion die Serielle Schnittstelle initiert werden:


void setup() {
  // init serial connection
  Serial.begin(9600);
}


Die Zahl in der Klammer gibt die Baudrate (siehe http://de.wikipedia.org/wiki/Baudrate) an. Diese definiert die Geschwindigkeitsrate mit der serielle Daten versendet bzw. gelesen werden. Für diesen Workshop verwenden wir eine Baudrate von 57600, welche für unsere Zwecke ausreicht.


Im folgenden Code wird eine Zeichenkette von den Meßwerten aller sechs Analogeingänge des Boards erstellt und über die serielle Schnittstelle versendet. Wir sehen später im Processing Code welche Vorteile diese Beschreibung der Daten bringt. Dieses Beispiel verwendet die Metro Library (http://www.arduino.cc/playground/Code/Metro), um die Daten nur alle 50 Millisekundne zu verschicken. Dieser Interval reicht für erste Experimente meist aus, da die serielle Kommunikation auf dem Arduino Board immer auch andere Prozesse verlangsamt. Nachdem die Bibliothek im Programmordner von Arduino unter “hardware/libraries” abgelegt wurde kann sie über “Sketch>Import Library>Metro” im Code importiert werden.


// libraries
#include 

// instantiate Metro object to slow down serial connection
Metro serialMetro = Metro(50);

void setup() {
  // init serial connection
  Serial.begin(57600);
}

void loop() {

  // check serial metro
  if(serialMetro.check()){
    // build message with values of analog inputs (0-5)
    for(int i=0; i< 6; i++){
      // value analog input
      Serial.print( analogRead(i) );
      // space
      Serial.print(" ");
    }
    // end of message
    Serial.println();
  }
}




Processing Code


Auf der Processing Seite können nun diese Daten über die Serielle Schnittstelle am Computer empfangen werden. Hierzu wird die processing.serial Library verwendet, die schon in der Grundinstallation von Processing enthalten ist. Die Serielle Schittstelle muss auch in Processing wieder initiert werden:


  // init connection to arduino
  port = new Serial(this, Serial.list()[0], 57600);


Die Zahl in der eckigen Klammer definert die Port Nummer für das Arduino Board. Da diese aber meist bei jedem Rechner anders ist, wird empfohlen alle Ports am Anfang des Codes auszugeben um den richtigen Port für das Arduino Board festzustellen:


  // print all available serial ports
  println(Serial.list());


Aus Erfahrung wird empfohlen, die seriellen Daten in der serialEvent() Funktion abzufangen. Da es vorkommen kann, das gelegentlich nicht interpretierbare Daten (Datenmüll) gesendet werden, sollte um die Abfrage eine try-catch Funktion geschrieben werden:


// serial event
void serialEvent(Serial p){

  // get message till line break (ASCII > 13)
  message = port.readStringUntil(13);
  // just if there is data
  if (message != null) {
    // try catch function because of possible garbage in received data
    try {
      elements = splitTokens(message);
      // loop through sensor values
      for (int i =0; i < elements.length && i < 6; i++ ) {
        sensorValues[i] = int(elements[i]);
      }
    }
    catch (Exception e){
    }
  }

}


Hier nun ein fertiger Code, der alle Sensordaten über die serielle Schnittstelle ausliest und diese als Graphen mit numerischen Angaben der Werte visualisiert. Dieser Code ist Ausgangspunkt für spätere Experimente zur Visualisierung von Sensordaten:


screensensorviz


/*

 reads values of analog inputs (0-5) of arduino board
 and vizualizes them as a graph

 */

// libraries
import processing.serial.*;
// serial connection
Serial port;
String message = null;
String elements[] = null;
// arduino
int[] sensorValues = new int[6];
// graphs
int distanceX = 110;
int distanceBottom = 40;
int graphWidth = 40;
color graphColor = color(255,255,255);
PFont fontGraph;

void setup() {

  // size
  size(800, 600);
  // no strokes
  noStroke();
  // Set the font and its size (in units of pixels)
  fontGraph = loadFont("Verdana.vlw");
  textFont(fontGraph, 12);
  // print all available serial ports
  println(Serial.list());
  // init connection to arduino
  port = new Serial(this, Serial.list()[0], 57600);

}

void draw() {

  // clear background
  background(0);

  // draw bars with values of analog inputs
  for(int i=0; i<6; i++){
    // color
    fill(graphColor);
    // draw bar
    rect(i*distanceX+distanceX,height-distanceBottom,graphWidth,-sensorValues[i]/2);
    // draw text
    text(sensorValues[i], i*distanceX+distanceX, height-distanceBottom+20);
  }
}

// serial event
void serialEvent(Serial p){

  // get message till line break (ASCII > 13)
  message = port.readStringUntil(13);
  // just if there is data
  if (message != null) {
    // try catch function because of possible garbage in received data
    try {
      elements = splitTokens(message);
      // loop through sensor values
      for (int i =0; i < elements.length && i < 6; i++ ) {
        sensorValues[i] = int(elements[i]);
      }
    }
    catch (Exception e){
    }
  }

}





Arduino Pong


arduinopong.zip