OSC Arduino
OSC Arduino
Zusammenfassung
Das OSC Protokoll (Open-Sound-Control) erlaubt es, auf eine einfache Art und Weise Daten über ein Netzwerk zu schicken. Das Arduino hat leider keine direkte Möglichkeit, dieses Protokoll zu verwenden, weshalb man den 'Umweg' über Processing in Kauf nehmen muss. Dieses Beispiel zeigt, wie die Werte eines Potentiometers von Arduino nach Processing geschickt werden und dann via OSC an einen anderen Computer im Netzwerk.
Arduino Sketch
Für die Programmierung des Arduino müssen wir lediglich einen kleinen Sketch schreiben, welcher das Potentiometer ausliesst und die Werte via Serial.print() an Processing sendet.
#define POTI_PIN //Define the PIN of the Potentiometer
void setup()
{
Serial.begin(9600); //Setup Serial Communication
}
void loop()
{
Serial.print(analogRead(0)); // Read the Potentometer and send the Value via Serial
Serial.print(','); // Send a comma as delimiter
Serial.println(); // Send a carriage-return as end-sign
delay(100); // !!! Important: Wait a bit !!!
}
Serial_Send_Poti
Library für Processing
Für Processing existiert eine Library von
Andreas Schlegel, welche es für uns sehr einfach macht, das Protokoll zu verwenden. Zunächst muss die Library im Processing-Library-Ordner platziert werden. Diesen findet ihr unter "Dokumente/Processing/libraries". Wenn dieser noch nicht existiert, dann legt diesen an. Er beinhaltet alle von euch installierten Libraries. (Dies ist ein feiner Unterschied zu Arduino, wo wir die Libraries direkt im Programmordner platzieren).
oscP5-0
Processing Sender
In Processing bedienen wir uns der schon gelernten Methode um die Werte vom Arduino über die serielle Schnittstelle auszulesen. Wir initialisieren erst die Serial Library von Processing und verwenden dann das gelernte serialEvent() um die Daten vom Arduino zu erhalten.
Um diese nun per OSC an einen anderen Computer zu versenden müssen wir zunächst die OSC Library initialisieren:
import oscP5.*; // Import the OSC Libary
import netP5.*; // Import the net Library
OscP5 oscP5; // Make an instance of the OSC Library
NetAddress myRemoteLocation; // Set a net Address
Im nächsten Schritt übergeben wir die Werte für die OSC Kommunikation innerhalb des setup():
void setup()
{
...
oscP5 = new OscP5(this,12000); // start oscP5, listening for incoming messages at port 12000
myRemoteLocation = new NetAddress("172.31.224.73",12000); // The Address defined here is the Address of the Receiver
...
}
Um ausgehende Daten zu handeln kreiert man nun lediglich eine neue OSC Message, hängt die zu schickenden Daten (in unserem Fall die Werte des Potentiometers) an und versendet dann das gesamte Packet:
OscMessage myMessage = new OscMessage("Arduino"); // New Message
myMessage.add(theData); // Add Data
oscP5.send(myMessage, myRemoteLocation); // Send Message
Processing Code Sender
import oscP5.*; // Import the OSC Libary
import netP5.*; // Import the net Library
import processing.serial.*; // Import the Processing Serial Library for communicating with arduino
OscP5 oscP5; // Make an instance of the OSC Library
NetAddress myRemoteLocation; // Set a net Address
Serial myPort; // The used Serial Port
int firstValue, secondValue; // fourthValue, fifthValue, ... // add more if needed
void setup()
{
size(400,400);
frameRate(25); // Make a bit slower
oscP5 = new OscP5(this,12000); // start oscP5, listening for incoming messages at port 12000
myRemoteLocation = new NetAddress("172.31.224.73",12000); // The Address defined here is the Address of the Receiver
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()
{
background(0);
println(firstValue);
}
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]);
sendOSC(firstValue);
}
}
}
void sendOSC(int theData)
{
OscMessage myMessage = new OscMessage("Arduino"); // New Message
myMessage.add(theData); // Add Data
oscP5.send(myMessage, myRemoteLocation); // Send Message
}
OSC_Arduino_Send
Processing Empfänger
Auf der Seite des Empfängers nutzen wir die selben Funktionen wie beim Sender (OSC Library, net Library) nur diesmal brauchen wir keine serielle Kommunikation.
Um die Daten welche der andere Computer sendet auszulesen nutzen wir wieder die Funktionen der OSC Library.
void oscEvent(OscMessage theOscMessage)
{
print("### received an osc message.");
print(" addrpattern: "+theOscMessage.addrPattern());
print(" typetag: "+theOscMessage.typetag());
if(theOscMessage.checkTypetag("i"))
{
println( " message is: "+theOscMessage.get(0).intValue());
}
}
Processing Code Empfänger
import oscP5.*;
import netP5.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
void setup()
{
size(400,400);
frameRate(25);
oscP5 = new OscP5(this,12000);
myRemoteLocation = new NetAddress("172.31.225.181",12000);
}
void draw()
{
background(0);
}
void oscEvent(OscMessage theOscMessage)
{
print(" addrpattern: "+theOscMessage.addrPattern());
print(" typetag: "+theOscMessage.typetag());
if(theOscMessage.checkTypetag("i"))
{
println( " message is: "+theOscMessage.get(0).intValue());
}
}
OSC_Arduino_Receive
Links
oscP5 Seite
OSC Wikipedia