Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

08 Arduino und Processing

Arduino und Processing

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() Funktion.

Arduino → Processing

Arduino

Auf der Arduino Seite ist das Prinzip relativ simpel. Man aktiviert die serielle Kommunikation und setzt eine Baudrate im setup() fest (z.B. Serial.begin(9600)). Dann schickt man einfach 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 ",;.:".

Code Arduino

Hier ein Beispiel, welches die Werte von zwei Sensoren über die serielle Schnittstelle sendet ...
#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()
{
  Serial.begin(9600); //Open the Serial Port with baudrate set to 9600
}

void loop()
{
  firstValue = analogRead(FIRST_PIN); // Read the first PIN
  secondValue = analogRead(SECOND_PIN); // Read the second PIN
  
  Serial.print(firstValue); // Send the first Value
  Serial.print(','); // Send a delimiter
  Serial.print(secondValue); // Send second Value
  Serial.print(','); // Send a delimiter
  Serial.println(); // Send a carriage-return
}

Processing

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.

Code Processing

Auf Processing Seite liesst folgender Code die Werte, welche wir von den zwei Sensoren über das Arduino senden ...
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()); // Prints the list of serial available devices (Arduino should be on top of the list)
  myPort = new Serial(this, Serial.list()[0], 9600); // Open a new port and connect with Arduino at 9600 baud
}

void draw()
{
}

void serialEvent(Serial myPort) // Is called everytime there is new data to read
{
  if (myPort.available() > 0)
  {
    String completeString = myPort.readStringUntil(10); // Read the Serial port until there is a linefeed/carriage return
    if (completeString != null) // If there is valid data insode the String
    {
      trim(completeString); // Remove whitespace characters at the beginning and end of the string
      String seperateValues[] = split(completeString, ","); // Split the string everytime a delimiter is received
      firstValue = int(seperateValues[0]);
      secondValue = int(seperateValues[1]);
    }
  }
}

Processing → Arduino

Arduino

Um auf der Seite des Arduino auf eingehende Nachrichten über die serielle Schnittstelle zu horchen müssen wir einige Funktionen benutzen. Diese sind: strtok() char *single = strtok ( char * str, const char * delimiters ); Diese Funktion splittet fine Sequenz von Bytes (*str) in einzelne Strings (*str). Dazu nutzt sie die vorhandenen Delimiter (*delimiters) http://www.cplusplus.com/reference/clibrary/cstring/strtok/ atoi() int value = atoi( const char * str ); Konvertiert einen String (*str) in ein Integer-Wert (value) http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/ memset() void * memset ( void * ptr, int value, size_t num ); Setzt die Bytes an einer speziellen Stelle (size_t num) in einem Array (*ptr) aug einen festgelegten Wert (value). http://www.cplusplus.com/reference/clibrary/cstring/memset/

Code Arduino

#define BUFFER_SIZE 20 // actual size of the buffer for integer values: (numberOfValsToRead*6)+(numberOfValsToRead-1)

char incommingBuffer[BUFFER_SIZE]; // buffer to store incomming values
char incomming; // primary buffer to store single incommning bytes
int incommingCounter = 0; // counter for counting the positions inside the buffer

int firstValue, secondValue, thirdValue; // fourthValue, fifthValue, ... // add more if needed

void setup()
{
  Serial.begin(9600);
}

void readSerial()
{
  while(Serial.available())
  {
    incomming = Serial.read(); // read single incommning bytes

    if(incomming != '\r') //if no carriage return is received proceed in reading the serial port
    {
      incommingBuffer[incommingCounter++] = incomming; // go on the next position in the buffer
    }
    else //read until a carriage ('\r') is received
    {
      incommingBuffer[incommingCounter] = '\0'; // set the last byte to NULL to sign it for the string operators

      char *a = strtok(incommingBuffer, ",.;"); // split the string after delimiters into tokens
      char *b = strtok(NULL, ",.;"); // ...
      char *c = strtok(NULL, ",.;"); // ...
      //char *d = strtok(NULL, ",.;"); // add another line if needed

      firstValue = atoi(a); // convert the strings into integers
      secondValue = atoi(b); // ...
      thirdValue = atoi(c); // ...
      //fourthValue = atoi(d); // add another line if needed    
      
      incommingCounter = 0; // reset the counter
      memset(incommingBuffer, 0, BUFFER_SIZE); //overwrite the incommingBuffer
    }
  }
}

void loop()
{
  readSerial(); // read the values available at the serial port
  
  Serial.print(firstValue); // debugging
  Serial.print("\t");
  Serial.print(secondValue);
  Serial.print("\t");
  Serial.print(thirdValue);
  Serial.print("\t");
  //Serial.print(fourthValue); // add these lines if needed
  Serial.println(); // send a carriage return for debugging 
}

Processing

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.

Code Processing

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()); // Prints the list of serial available devices (Arduino should be on top of the list)
  myPort = new Serial(this, Serial.list()[0], 9600); // Open a new port and connect with Arduino at 9600 baud
}

void draw()
{
  int firstValue = 111;
  int secondValue = 222;
  int thirdValue = 333;
  
  myPort.write(str(firstValue));
  myPort.write(",");
  myPort.write(str(secondValue));
  myPort.write(",");
  myPort.write(str(thirdValue));
  myPort.write(",");
  myPort.write("\r"); 
  delay(1000);
}

Weitere Informationen

Serial() auf arduino.cc Serial() auf processing.org