on Mar 9th, 2012From Arduino to Processing to god knows where

Since we’re all Arduino Masters by now, let’s use all this hardware knowledge to control some software! Instead of writing one big chunk of software, we’ll be learning how to communicate between different programs using a protocol called OSC (short for Open Sound Control).
If you want to know everthing there is to know about OSC, you can go to it’s website here: http://opensoundcontrol.org/introduction-osc

First, you’ll have to install the oscP5 library in Processing.

The library is here: http://www.sojamo.de/libraries/oscP5/

And you want to install/unzip it into your sketchbook folder, in a folder called “libraries” that you’ll have to make. Daniel Shiffman also says so here: http://www.learningprocessing.com/tutorials/libraries/

Next, we’ll use a simple program that reads from Arduino and sends stuff over OSC. We base the program off of Andreas Schegel’s OSC example included in the library.

Before we look at the code, let’s talk a bit about OSC. It’s a neat protocol in that it allows you to send more than just raw bytes, but floats, ints and what have you. The only caveat is that you kindof need to know what you’re looking for on the receiving end.
OSC is basically divided into 2 parts: the address and the data part. In the address, you write stuff that the receiving program will interpret as a string, so it’s convenient to use for communicating what’s going on in the data part. And in the data part you pack your data.

Lots of questions can be resolved once some example code is up and running, so let’s get to it! I will run a program called “Moviesandbox” that you can download from here: http://moviesandbox.net, and that allows me to visualize my sensor inputs using 3D-graphics! It runs on modern Macs and PCs.
I’ll help you set things up in MSB to get your sensor inputs going.
Also, there’s an example MSB project that you can plug your sensors into, that you can download from here:

http://moviesandbox.net/fish.zip

Once downloaded, unzip it to the projects folder in moviesandbox.

Here is the Processing Code (it’s a bit involved, feel free to leave some stuff out):

import oscP5.*;
import netP5.*;
import processing.serial.*;

 Serial myPort;        // The serial port
 //sensors
 float inByte1;
 float inByte2;
 float inByte3; 

OscP5 oscP5;
NetAddress myRemoteLocation;

//prefix is the indicator for the sensor number
//int prefix1 = 3;

//flag for the end of the signal
boolean myCatch1 = true;

void setup() {
  size(600,400);
  frameRate(25);
  /* start oscP5, listening for incoming messages at port 12000 */
  //we dont really need to listen, so we leave at port 12000
  oscP5 = new OscP5(this,12000);

  /* myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
   * an ip address and a port number. myRemoteLocation is used as parameter in
   * oscP5.send() when sending osc packets to another computer, device,
   * application. usage see below. for testing purposes the listening port
   * and the port of the remote location address are the same, hence you will
   * send messages back to this sketch.
   */
  myRemoteLocation = new NetAddress("127.0.0.1",31841);

   // List all the available serial ports
   println(Serial.list());
   // I know that the first port in the serial list on my mac
   // is always my  Arduino, so I open Serial.list()[0].
   // Open whatever port is the one you're using.
   myPort = new Serial(this, Serial.list()[0], 9600);
   // don't generate a serialEvent() unless you get a newline character:
   myPort.bufferUntil('\n');

}

void serialEvent (Serial myPort) {
 // get the ASCII string:
  String inString = myPort.readStringUntil(';');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    inString=inString.substring(0, inString.length()-1);
    // convert to an int and map to the screen height:
    inByte1 = float(inString);
    inByte1 = map(inByte1, 0, 1023, 0, 1.0);
   }
  inString = myPort.readStringUntil(';');
  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    inString=inString.substring(0, inString.length()-1);
    // convert to an int and map to the screen height:
    inByte2 = float(inString);
    inByte2 = map(inByte2, 0, 1023, 0, 1.0);
   }
  inString = myPort.readStringUntil(';');
  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    inString=inString.substring(0, inString.length()-1);
    // convert to an int and map to the screen height:
    inByte3 = float(inString);
    inByte3 = map(inByte3, 0, 1023, 0, 1.0);
   }
  inString = myPort.readStringUntil('\n');

  print(inByte1);
  print (" ");
  print(inByte2);
  print (" ");
  print(inByte3);
  println(";");
 }

void draw() {
  background(128);
  sendOSC();
}

void sendOSC() {
  /* in the following different ways of creating osc messages are shown by example */
//  OscMessage myMessage = new OscMessage("/pilot/vector3f/vector3f");
  OscMessage myMessage = new OscMessage("/pilot/float/vector3f");

  //head
    myMessage.add(inByte1); /* add a float value to the osc message */

    myMessage.add(0.0); /* add a float value to the osc message */
    myMessage.add(0.0); /* add a float value to the osc message */
    myMessage.add(inByte1); /* add a float value to the osc message */

  /* send the message */
  oscP5.send(myMessage, myRemoteLocation);
}

/* incoming osc message are forwarded to the oscEvent method. */
void oscEvent(OscMessage theOscMessage) {
  /* print the address pattern and the typetag of the received OscMessage */
  print("### received an osc message.");
  print(" addrpattern: "+theOscMessage.addrPattern());
  println(" typetag: "+theOscMessage.typetag());
}

And we’ll be using this Arduino Code, which is only a slight modification of the Analog Input example by David Cuartielles and Tom Igoe:

int sensorPinOne = A0;    // select the input pin for the potentiometer
int sensorPinTwo = A4;    // select the input pin for the potentiometer
int sensorPinThree = A2;    // select the input pin for the potentiometer

int ledPin = 13;      // select the pin for the LED
int sensorValueOne = 0;  // variable to store the value coming from the sensor
int sensorValueTwo = 0;  // variable to store the value coming from the sensor
int sensorValueThree = 0;  // variable to store the value coming from the sensor

void setup() {
  // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);  

  Serial.begin(9600);
  //set pull up resistors for all three input channels
  digitalWrite(14, HIGH);  //A0 pullup
  digitalWrite(16, HIGH);  //A2
  digitalWrite(18, HIGH);  //A4
}

void loop() {
  // read the value from the sensor:
  sensorValueOne = analogRead(sensorPinOne);
  sensorValueTwo = analogRead(sensorPinTwo);
  sensorValueThree = analogRead(sensorPinThree);
  Serial.print(sensorValueOne);
  Serial.print(";");
  Serial.print(sensorValueTwo);
  Serial.print(";");
  Serial.print(sensorValueThree);
  Serial.println(";");
  delay(20);
}

Comments are closed at this time.