Go Down

Topic: processing, firmata, UDP, and libraries (Read 453 times) previous topic - next topic

soundanalogous

#5
Nov 03, 2013, 01:39 am Last Edit: Nov 03, 2013, 01:46 am by soundanalogous Reason: 1
This could be done using the Firmata protocol, but not using StandardFirmata. There is a huge misconception that StandardFirmata is "Firmata". However that said the only thing Firmata would give you is the ability to "frame" your data within a midi Sysex message.

You would write an Arduino sketch to read the sensors, using any sensor libraries you may have.  Then create a simple protocol to send the sensor data to processing (via UDP). You need a messaging protocol so Processing can understand what sensor data it is receiving (imagine a JSON String for example: "{\"accel\": {\"vector\": {\"x\": 233, \"y\": 110, \"z\": 2}}}"). Likewise if you need to send messages from Processing to the Arduino you could use a protocol to inform an accelerometer to start reading at a specified interval for example: ("{\"accel\": {\"cmd\": {\"start\": 10000}}}"). You could use JSON or xml but that is a lot of text processing for most Arduinos to handle (more of an issue receiving than sending). What Firmata could give you is a binary protocol to insert in your UDP packets. Here is an (incomplete) example. I'll warn you it is not as straightforward as sending a JSON or xml stream though, but can be lighter and faster to parse depending on how much data you need to send. If you don't understand the following pseudocode then this is probably not a good direction for you.

Code: [Select]

// This is an example of using the Firmata protocol simply to send data in a
// (somewhat) structured form. It accomplishes the same thing as something like
// "{\"accel\": {\"vector\": {\"x\": 233, \"y\": 110, \"z\": 2}}}" but is 17 bytes
//  instead of 44 bytes but at the expense of being a bit more cryptic.

#include <Firmata.h>
#include <Ethernet.h>
// include any other libraries you need

// define some constants to help identify data in the firmata sysex message
#define ACCEL        0x00  // use a different value < 0x15 to identify each sensor
#define VECTOR     0x00

EthernetClient client;
// and other ethernet setup (mac address etc)

// array for for accelerometer values
byte accelVector[6];

void setup () {
 Ethernet.begin(macAddress);
 delay(1000);
 client.connect(ip, port);
 // Firmata can use an Ethernet (or WiFi) stream instead of Serial stream
 Firmata.begin(client);

 // your other setup code
}

void loop () {
 // your loop code

 // imagine you are using an accelerometer library that reports x, y and z values
 onAccelRead(accel.x, accel.y, accel.z)
}

void onAccelRead(int xVal, int yVal, int zVal) {
  // Populate an array to send using Firmata.sendSysex
  // This must be an array of bytes. Cannot be array of ints or other type.
   accelVector[0] = VECTOR;  // subcommand: this is an arbitrary value that to identify the type of data
   accelVector[1] = (byte)(xVal & 0x00FF); // LSB
   accelVector[2] = (byte)(xVal >> 8 & 0x00FF); // MSB
   accelVector[3] = (byte)(yVal & 0x00FF);
   accelVector[4] = (byte)(yVal >> 8 & 0x00FF);
   accelVector[5] = (byte)(zVal & 0x00FF);
   accelVector[6] = (byte)(zVal >> 8 & 0x00FF);
   // note that sendSysex will split each byte in the accelVector array into 2 bytes
   // params: command, numBytes, byte array
   Firmata.sendSysex(ACCEL, 7, accelVector);
   // sendSysex will split each byte in the array into 2 bytes so it will actually send
   // 14 bytes + start, command and end bytes so 17 bytes total
}


If you have a firmata client library that can parse a Firmata sysex message then you'll be able to receive the data. You'll still have to interpret the data between START_SYSEX (0xF0) and END_SYSEX (0xF7) and reassemble all of the split bytes which can be some tricky shifting and masking if you are not used to such techniques.

Xzeion

Thank you for your post soundanalogous. That is a bit over my head though. I have not really gotten into bitshifting and such just yet.
I am more interested in reading than writing with the arduino.

I may be over complicating the issue.
I would like to be able to get sensor and or pin reads from the arduino when i ever i send a specific value to it over UDP

for example:
I want an analog reading but i only want a read when a command is recieved over UDP.
When the serial read is complete send the results over UDP.
The Processing sketch on the other end sorts out the input from the sensor making the arduios work much lighter.
The Processing sketch can also control what to do with the input after it comes in

The advantage to all of this is simple. If the code on the arduino remains constant I can update the software in processing
to re purpose the arduino without having to constantly write sketches for it. (allowing for a stable code base) I could also have a pile of libraries and sensor reading functions that just sit in the code until they are called. With the mega2560's 256k of code memory I could set up a ton of available sensors from my processing sketch. Then I could just write simple processing sketches, take in what i need from the arduino and have the processing sketch run more complex software and real time graphs and such.

does that clarify what I am attempting here ?
I a sentence, I am attempting to expand my options for data processing with arduino.
If life is unfair, why is it never unfair in my favor?

Go Up