Good practice for sending data from Arduino to Processing


#1

Hi! This is the first question I make in the forum! Is in the context of good practices sending data from Arduino to Processing, and vice versa.

Recenlty I made a VJ console that sends data from some potentiometers and buttons from an Arduino to Processing. As I’ve seen, there is some questions in the forum in regards of how should one send multiple data from Arduino to Processing and know from which sensor the data came. Now, the way I solved this is a simple, yet effective way that I learned in school. It’s useful for my purposes of using 4 potentiometers but I don’t know if it will represent a problem if I scale the project to have more sensors.

/*
  Reading multiple sensors
  Reads analog inputs on pin 0, 1, 2, 3, prints the result to the serial monitor.
  This example code is in the public domain.
*/

void setup() 
{
  //Initialize serial communication at 9600 bauds.
  Serial.begin(9600);
}

void loop() {
  //Read the input values of multiple analog sensors.
  int sensorValue1 = analogRead(A0);
  int sensorValue2 = analogRead(A1);
  int sensorValue3 = analogRead(A2);
  int sensorValue4 = analogRead(A3);
  //Print out the values the sensors read and add +1024 to 
  //each range of values to differentiate each other.
  Serial.println(sensorValue1);
  Serial.println(sensorValue2 + 1024);
  Serial.println(sensorValue3 + 2048);
  Serial.println(sensorValue4 + 3072);
  delay(1);        // delay in between reads for stability
}

Then, in Processing I read the data stream of values and can know which sensor send the data by comparing the range value.

Now, I was wondering if this way of sending multiple data is common? Is there any best practice to send mulitple data better than this way? Why it is better and what are the cons of using my code? Is there a fastest way of sending data from an Arduino Uno, or this will involve using another faster microcontroller?

Thanks in advance for your answers, I hope someone can guide me on better practices of integrating Arduino to Processing, and if this code is good enough for most projects, I hope it helps people in the community.


#2

there are many ways, but for datasets i use CSV style,

1024,1024,1024,1024,

per line what actually requires good documentation what data is what sensor…
and it is faster insofar as the line sending and line catching via serial/USB
( you would send 4 lines )
takes more time as the string separation.
( your way also needs that value decoding… )

but there are many other way,
the fastest still would be a byte stream ( not ASCII ) but i hate, as i can not read it in
Arduino IDE terminal
the slowest would be a full text way what i actually can recommend,
it is a JSON record

{ "unit1" : { "S1" : 1024 , "S2" : 1024, "S3" : 1024, "S4" : 1024 }, "unit2" : {....} }

so sending a lot of “redundant” text looks like a waste of “bandwidth”…
but is very clear, readable for us and a JSON function from reading to saving to file…
there is a kind of frame check ( too short lines would be rejected… )

is this to slow for you??
well why not run with

 Serial.begin(57600);

if you need slow 9600Bd to get connection you have heavy cable issues
like free wiring or too long cable…


#3

And how do you catch the data In processing code ?
I’m curious


#4

#5

update

example v02
// https://discourse.processing.org/t/good-practice-for-sending-data-from-arduino-to-processing/6339/2

// on arduino make and send a JSON String,

// in processing catch the line and use
// https://processing.org/reference/parseJSONObject_.html
// https://processing.org/reference/JSONObject.html

// add to Array and save to file:
// https://processing.org/reference/saveJSONArray_.html
//_________________________________________________________
// test on WIN7 32bit
// and processing IDE 3.4

import processing.serial.*;
Serial myPort;  // Create object from Serial class

String inString = "{ \"UNO_1\" : { \"A0\" : 1000 , \"A1\" : 1001, \"A2\" : 1002, \"A3\" : 1003, \"A4\" : 1004, \"A5\" : 1005 } }";
String outfilename = "data/arduinocatch.json";
// String outfilename = "/run/shm/arduinocatch.json";  // for RPI
//______
JSONArray  allArduinoLines = new JSONArray();
JSONObject arduinoLine     = new JSONObject();
JSONObject values          = new JSONObject();   // to catch just the value list ( of the inner {  } ) 
String remoteIOdevice = "UNO_1";
String[] channels = {"A0","A1","A2","A3","A4","A5"};
int bdrate = 115200;

//_________________________________________________________
void setup() {
  size(200,200);
  get_line();  // init
  printArray(Serial.list());
  String portName = Serial.list()[1];               // here it was "COM3"
  myPort = new Serial(this, portName, bdrate);
}

//_________________________________________________________
void get_line() {
  arduinoLine =  parseJSONObject(inString);
  println(" new inString: "+arduinoLine);
  allArduinoLines.append(arduinoLine);
}

//_________________________________________________________
void to_file() {
  saveJSONArray(allArduinoLines, outfilename);
}

//_________________________________________________________
void draw() {
  background(200,200,0);
  check_serial();
  show_line();
}

void check_serial() {
  while (myPort.available() > 0) {
    inString = myPort.readString();
    println("serial event: "+inString);
    if (inString != null) {
      get_line();
      to_file();
  }
 }
}

//_________________________________________________________
void show_line() {  // take JSON object "arduinoLine" appart and show as text
  int dpos=20, ypos =  dpos;                       // canvas text layout
  values = arduinoLine.getJSONObject(remoteIOdevice);
  //println(" data from: "+remoteIOdevice+" \n"+values);
  fill(0);
  text(remoteIOdevice            , dpos, ypos); ypos += dpos;
  for (int i = 0;i<6;i++) text(channels[i]+": "+values.getInt(channels[i]), 2*dpos, ypos +i*dpos);
}

//_________________________________________________________
/*
first time started: dir and file is created
/data/arduinocatch.json
content:
[{"UNO_1": {
  "A1": 1001,
  "A2": 1002,
  "A3": 1003,
  "A0": 1000
}}]

*/


/*    Arduino code used here:

// test on Arduino Leonardo USB to win7 PC found "COM3"
// to send a JSON like full text record
String JSON;
int channels[6];

void setup() {
  Serial.begin(115200);
  while (!Serial) { ; }  // wait for serial port to connect. Needed for LEONARDO..
}

void get_Ain() {
  for (int i=0;i<6;i++)   channels[i] = analogRead(i);
}

void makeJSON() {
 JSON = "{ \"UNO_1\" : { ";
 for (int i=0;i<6;i++)  {
  JSON += " \"A";
  JSON += i;
  JSON += "\" : ";
  JSON += channels[i];
  if ( i < 5 )JSON += " , ";  
 }
  JSON += " } } ";
}

void loop() {
  get_Ain();
  makeJSON();
  Serial.println(JSON);   // to processing
  delay(1000);
}

*/

@matheynen what hardware you have to test this?
update: i checked on Raspberry Pi 3B+
and there it was on

/dev/ttyACM0 (Arduino Leonardo )

and i recommend to change data storage from uSDcard to (temporary) RAM DISK
( because write every second to card wears it out in?? )

String outfilename = “/run/shm/arduinocatch.json”; // for RPI

//___________________

@rodrigogamboa i did notice in your arduino code

delay(1); // delay in between reads for stability

pls, that is one millisecond ( not one second )
so possibly you are up to high speed sampling,
then i would recommend a total different way.

  • -a- you sample to array as fast as possible
    ( add there is special speedy code if you sample one channel only )
  • -b- in a batch type communication you send that whole array to processing
  • -c- you build a oscilloscope like view

i play this on processing, python or webserver

35kHz on one channel for Arduino and 520kHz for MAX32.

check out my BLOG and search for PoorManScope