Da Arduino auf Processing basiert eignen sich die beiden auch perfekt dazu Daten untereinander auszutauschen. Auf der Arduino-Seite nutzt man dazu die Funktion Serial.print() um Daten an Processing zu schicken und Serial.read() um Daten von Processing zu empfangen. Auf Processing-Seite nutzt man die Serial library welche schon in Processing integriert ist. Um Daten vom Arduino in Processing zu empfangen nutzt man ebenfalls die read() Funktion und um Daten an das Arduino zu schicken die write() FunktionDazu verwenden wir die serielle Schnittstelle "Serial" die das asynchrone Austauschen von Daten ermöglicht.
Arduino zu Processing
Auf der Arduino Seite ist das Prinzip relativ simpel. Man aktiviert man die serielle Kommunikation Schnitstelle in der "setup" Funktion und setzt eine Baudrate im setup (bits/second) fest (z. B. Serial.begin(9600)). Dann schickt man einfach Dann schreibt man die betreffenden Werte/Variablen über Serial.print(VARIABLE). Man muss lediglich darauf achten, einen Delimiter zwischen den Werten und nach allen Werten einen carriage-return (Serial.println() od. Serial.print(‘r’)) zu schicken – das macht die Unterscheidung in Processing nachher umso einfacher. Als Delimiter eignen sich Sonderzeichen wie “,;.:“mit Kommas getrennt in einer Zeile.
Hier ein Beispiel, welches die Werte von zwei Sensoren über die serielle Schnittstelle sendet sendet:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
#define FIRST_PIN 0 // Define the Analog Pins add more if needed #define SECOND_PIN 1 int firstValue, secondValue; // Define Variables to store the analog Values void setup() {void setup() { // open the serial port with a baudrate of 9600 Serial.begin(9600); //Open} the Serial Portvoid withloop() baudrate{ set to 9600// }reading of pins void loop() {int firstValue = analogRead(FIRST_PINA0); // Read the first PIN int secondValue = analogRead(SECOND_PINA1); // Readwriting theof seconda PINsingle line to serial "100,200" Serial.print(firstValue); // Send the first Value Serial.print(','); // Send a delimiter Serial.print(secondValue); // Send second Value Serial.printprintln(','); // Send<- afinish delimiter Serial.println(); // Send a carriage-return of line } |
Auf Processing-Seite müssen wir zunächst die Serial Library implementieren. Dies geschieht über:
import processing.serial.*; // Import Library
Serial myPort; // Den Port instanzieren
Im setup() lassen wir uns dann eine Liste mit allen verfügbaren seriellen Schnittstellen ausgeben und wählen den entsprechenden Eintrag in dieser Liste als Port für die Verbindung mit dem Arduino (es ist meist der erste Eintrag) und setzen die Baudrate auf den gleichen Wert wie im Arduino (in unserem Fall 9600).
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
So sieht die Ausgabe bei Processing typischerweise aus…
Das Arduino ist der Eintrag “dev/tty/.usbmodemfa131″
Um die Daten von Arduino auszulesen gibt es im Processing eine Funktion, welche aufgerufen wird, sobald Daten an der Serielle Schnittstelle anliegen:
void serialEvent(Serial myPort)
{
// Hier werden die Daten der seriellen Schnittstelle gelesen
}
Innerhalb dieser Funktion filtern wir unsere Daten und suchen nach den Delimitern, welche wir in Arduino festgelegt haben. Damit können wir die einzelnen Variablen wieder “auseinanderpflücken” und im Processing verwenden.
Auf Processing Seite liesst folgender Code die Werte, welche wir von den zwei Sensoren über das Arduino senden …importieren, und die serielle Schnittstelle in der "setup" Funktion öffnen. Danach könne wir in der Callback Funktion "serialEvent" jeweils eine Zeile lesen, und die einzelnen Werte wieder rauslesen.
Hier ein Beispiel dass die beiden Werte ausliest und eine Ellipse zeichnet.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
import processing.serial.*; // Import the Processing Serial Library for communicating with arduino Serial myPort; // The used Serial Port int firstValue, secondValue; // fourthValue, fifthValue, ... // add more if needed void setup() { size(500, 500); println(Serial.list()); // Printsprint theall listavailable ofports serial available devices (Arduino should be on top of the list) println(Serial.list()); // open specific serial port myPort = new Serial(this, Serial.list()[0]"/dev/cu.usbmodem12131", 9600); } // Open a new port and connect with Arduino at 9600 baud } void draw() { } void draw() { // draw ellipse background(0); fill(255); ellipse(width/2, height/2, firstValue, secondValue); } void serialEvent(Serial myPort) //{ Is called everytime// therecheck is newif data tois readavailable { if (myPort.available() >== 0) { String completeString = myPort.readStringUntil(10);return; } // Readread thea Serialline portas untila therestring is a linefeed/carriageString returnstr = myPort.readStringUntil('\n'); if (completeStringstr !== null) // If there{ is valid data insode the Stringreturn; } { // remove leading and trailing trim(completeString); // Remove whitespace characters at the beginning and end of the string String seperateValueswhitespace str = trim(str); // split string String vals[] = split(completeStringstr, ","); // Split the string everytime a delimiter is received if (vals.length != 2) { return; } // convert values firstValue = int(seperateValuesvals[0]); secondValue = int(seperateValuesvals[1]); } }println(firstValue, secondValue); } |
Processing zu Arduino
Auf der Seite von Processing können wir einfach die Funktion *.write() aus der Serial Library nutzen. Es ist lediglich darauf zu achten, dass Werte als Strings an das Arduino gesendet werden. Mit der Funktion str(value) lässt sich jeder Wert (value) in einen String umwandeln. Zusätzlich senden wir zwischen jedem einzelnen Wert ein ‘,’ als Delimiter und ein carriage-return (“t”) als Indikator für das Ende der Übertragung.Für die Umgekehrte Kommunikation schreiben wir die Daten in Processing auch als Komma getrennte Werde in Zeilen:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
import processing.serial.*; // Import the Processing Serial Library for communicating with arduino Serial myPort; // The used Serial Port void setup() { background(0); size(500, 500); println(Serial.list()); // Printsprint theall listavailable ofports serial available devices (Arduino should be on top of the list) println(Serial.list()); // open specific serial port myPort = new Serial(this, Serial.list()[0]"/dev/cu.usbmodem14621", 9600); // Open a new port and connect with Arduino at 9600 baud } void draw() { // prepare values int firstValue = 111; int secondValue = 222; int thirdValue = 333; // write values myPort.write(str(firstValue)); myPort.write(","); myPort.write(str(secondValue)); myPort.write(","); myPort.write(str(thirdValue)); myPort.write("\n"); delay(1000); } |
Um auf der Seite des Arduino auf eingehende Nachrichten über die serielle Schnittstelle zu horchen müssen wir einige Funktionen benutzen. Diese sind:
charAt()
Diese Funktion retourniert das Zeichen in einem String an der angegebenen Position.
substring()
Diese Funktion erstellt einen Ausschnitt eines String von und bis zur angegebenen Position.
toInt()
Diese Funktion wandelt einen Sting in einen Int
Auf dem Arduino können wir dann diese Zeilen auch wieder in einzelnen Werte konvertieren:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
#define LED_PIN 6 #define NUM_OF_VALUES 3 String incomingString =""; int incomingValues[NUM_OF_VALUES]; void setup() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); // open the serial port with a baudrate of 9600 Serial.begin(9600); } void loop() { // check if data is available if (Serial.available() > 0) { incomingString// read string String str = Serial.readStringUntil('\n'); // split(incomingString data and write to incomingValues split(str, incomingValues, NUM_OF_VALUES); } // take first value and set LED analogWrite(LED_PIN6, incomingValues[0]); } void split(String inputString, int returnData[], int numOfValues) { int index = 0; int lastPos = 0; for for(int i = 0; i < i<inputStringinputString.length(); i++) { if (inputString.charAt(i) == ',' && index < numOfValues) { String tempStr = inputString.substring(lastPos, i - 1); returnData[index] = tempStr.toInt(); index++; lastPos = i + 1; } } } |