Problem with the use of several sensors, arduino / processing

Cordial greeting, I am working on a project where I require the use of several sensors and visualize them in processing. I am currently using this code.

import processing.serial.*;

Serial puerto; // se declara una variable para la com. serial
boolean newData = false;
int xPos = 0;         // posición horizontal del gráfico
// Variables para dibujar una línea continua de la gráfica. 
int lastxPos=1;
int lastheight=0;
float inByte[] = {0,0,0,0,0,0,0}; // Datos seriales entrantes

void serialEvent (Serial myPort) { //Datos de la gráfica. 
  // obtener la cadena ASCII:
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    inString = trim(inString);                // recortar espacios en blanco.
    inByte = float(split(inString, ',')); 
    inByte[0] = float(inString);           // convertir a un número.
    inByte[0] = map(inByte[2], 0, 1023, 0, height); //mapa a la altura de la pantalla.
    newData = true; 
    
    
  }
}

public void setup(){
   size(1000, 600, JAVA2D); //Tamaño de la ventana principal
   background(17,34,51); 
   rect(-1, 95, 1001, 330,1); // Tamaño del rectángulo blanco donde se grafican los datos
   puerto = new Serial(this,Serial.list()[0], 9600); //Busca puerto serie conectado automáticamente.
   puerto.clear();
   puerto.bufferUntil('\n');
}

public void draw(){
   println(inByte[0],inByte[1],inByte[2],inByte[3],inByte[4]);
  if (newData) {
    stroke(17,34,51);     //Color de la línea graficadora. 
    strokeWeight(1);        //Grosor de la línea graficadora.
    line(lastxPos, lastheight, xPos, height - inByte[0]); 
    lastxPos= xPos;
    lastheight= int(height-inByte[0]);
    
     // Dibujando una línea desde Last inByte hasta la nueva.
     // en el borde de la ventana, regrese al principio:
    if (xPos >= width) {
      xPos = 0;
      lastxPos= 0;
      saveFrame( "Pantallazos Automáticos cada 30s"+"/"+day()+"-"+month()+"-"+year()+" a las "+hour()+"_"+minute() +" con "+ second()+"s"+ ".png") ; //dar nombre de fecha a los pantallazos
     // background(17,34,51);  //Clear the screen.
      rect(0, 95, 999, 355,1); // Tamaño del rectángulo blanco donde se grafican los datos
      stroke(196,196,196); // Color de la línea del cuadriculado

    } 
    else {
      // Incrementa la posición horizontal.
      xPos++;
    }
   newData =false;
 }
}

However I get this error if I close the program from the “x” and open it again. The only way to make it work again is to disconnect the USB completely and reconnect it which is not practical.

What would be the correct and infallible way to send data from several arduino sensors to processing avoiding this error that appears to me?
I have tried different methods but none works really well, so far this has been the best in my case that I need to graph one of the data and show the others.
What would be the best method to do this? Graph one data and show the others?

Thank you.

1 Like

I have some experience working with Multiwii which uses a protocol for communicating over the Arduino serial port. Multiwii boards combine multiple sensors and there is a GUI built for Multiwii in processing. The GUI reads the serial port and displays the different sensor values using the Multiwii serial protocol. The Arduino and Processing both use the same serial protocol and various messages can be turned on and off without killing the connection.

http://www.multiwii.com/

2 Likes

IF you visit the above link, there is a link to download Multiwii. Within that download is the GUI, multiwiiconf, that is written for processing/java. You could possibly extract the serial protocol and apply it to your project, as well as the techniques it uses for graphical display of data. Here is a screenshot of the GUI from the link.

1 Like

Hello, thank you very much for your response but I already have my graphic interface developed, how could I implement the multiwii protocol in the interface that I already have developed in Processing?

Hello,

Some code I wrote to explore Arduino transmitting data to Processing.
It runs fine at a BAUD rate of 1000000. :)
I use an Arduino MEGA 2560 R3.

Arduino Code
// Serial Incoming Test (Arduino Tx)
// v1.0.0
// GLV 2020-02-29

long count;

void setup() 
  {
  //Serial.begin(9600);
  Serial.begin(1000000);
  delay(1000);
  Serial.print('\n'); //same as Serial.println()
  Serial.print("incoming");
  Serial.print('\n'); //same as Serial.println()
  }
  
void loop() 
  {         
  float x = random(0, 2)*PI;
  float y = random(2, 4)*PI;
  float z = random(4, 6)*PI;
  float u = random(8, 10*PI);
  Serial.print(count++);
  Serial.print(',');
  Serial.print(x,12);
  Serial.print(',');
  Serial.print(y,12);
  Serial.print(',');
  Serial.print(z,12);
  Serial.print(',');
  Serial.print(u,12);
  Serial.print('\n'); //same as Serial.println()
  delay(1);
  }
Processing Code
// Serial Incoming Test (Processing Rx)
// v1.0.0
// GLV 2020-02-29

import processing.serial.*; 

Serial myPort;

String inString = null;

boolean newData = false;
boolean dataValid = false;
boolean serialConnect = true;

int dataCount1, dataCount2;

static final int BAUD = 1000000;
//static final int BAUD = 9600;

//String inByte[] = {"0", "0", "0", "0", "0"};
String inByte[] = null;

public void settings()
  {  
  size(500, 600, JAVA2D);  
  }

public void setup()
  { 
  printArray(Serial.list());
  textSize(24);
 
  try
    {
    myPort = new Serial(this, Serial.list()[6], BAUD);    
    myPort.clear();
    myPort.bufferUntil('\n');  
    }
  catch (Exception e)
    {
    println("Not connected!");
    serialConnect = false;
    }
  }

public void draw()
  {
  background(0);
  
  text("Incoming Data Test", 50, 100);  
  if (newData)
    {
    for(String i: inByte) print(i + "\t");
      
    text(dataCount1, 50, 150);
    text(dataCount2, 50, 200);
    int j = 0;
    for(int i = 0; i < inByte.length; i++)
      {
      text(inByte[i], 50, 250 + 50*i);
      }
    }
  newData = false;
  }

public void serialEvent (Serial myPort) 
  {    
  inString = myPort.readString();
  //println(inString);               // See all the data include "garbage"
  inString = inString.trim();
  //println(inString);             // See all the data include "garbage"
  
  if (inString != null && inString.equals("incoming")) 
    {
    dataValid = true;
    println();
    println("Valid incoming data:");
    }
  
  else if (dataValid) 
    {               
    inByte = split(inString, ',');
    
    dataCount1++;
    
    if (inByte.length == 5) 
      {
      dataCount2++;  
      newData = true;

      //println(inByte);      //gives a warning but works; fine for debugging
      
      //printArray(inByte);

      //Cleaner print
      //for (int i = 0; i< inByte.length; i++)
      //  {
      //  print(inByte[i]+ "\t");
      //  if (i == inByte.length-1 ) println();
      //  }
     
      //Even better!
      //for(String i: inByte) print(i + "\t");
      }
    }
  }    
  

There is a lot of “garbage” data in the buffers if Arduino is powered:

  1. And you do a reset (Arduino button) while Processing is running and receiving data.
  2. And you restart Processing while Arduino is sending data.
  • I check for “incoming” string to check for valid incoming data; I added a ‘\n’ before and after so I could detect this. I am buffering until ‘\n’ so needed a clean string to detect and this did the trick!
  • There is no garbage with a “power off” and “power on” of Arduino.

I added a try\catch to see if Arduino is connected.

I have a lot of print statements for debugging; these can be commented as required.

At 9600 BAUD data is coming in slower than each frame and will flash on the screen.
At 1000000 BAUD data is coming in faster than each frame and you will skip data each frame (too fast to see anyhow); see the console and watch the counters.
You may want to consider buffering data and using this in draw as required.

I have counters on data sent from Arduino and data arriving; this is for debugging.

:)

1 Like