Processing serial.available issue

Hi to everyone,

First of all, I’m developing a simple program in processing that receives data via serial, from an arduino connected to a sensor. Once the data arrives in processing, is uploaded to a MySQL database.
But I have a sort of a problem, that I don’t know why does it happen. I’ll leave my code here and then I’ll explain my problem.

Processing code:

import de.bezier.data.sql.*;
import de.bezier.data.sql.mapper.*;
import processing.serial.*;

MySQL msql;      //Create MySQL Object
String[] a;
String val;     // Data received from the serial port
Serial myPort;  // Create object from Serial class

void setup()
{
  String user     = "adm";
  String pass     = "adm";
  String database = "bdsmce";
  msql = new MySQL( this, "localhost", database, user, pass );
  
  String portName = Serial.list()[1]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, portName, 9600);
  myPort.clear(); 
  val = myPort.readStringUntil(end);
  val = null;
}

void draw()
{
  if ( myPort.available() > 0) 
  {  // If data is available,
    val = myPort.readStringUntil('\n');         // read it and store it in val
  } 

  if (val != null) {
      a = split(val, ','); 
      println(a[0]);
      println(a[1]);
      function();
      delay(10000);
  }
}

void function()
{
  if ( msql.connect() )
    {
        msql.query( "insert into lect(Irms, FechaHora, Nodo_ID, Watt,)values(" + a[0] + "," + "now()" + "," + "7" + "," + a[1] + ")" );
    }
    else
    {
        // connection failed !
    }
    msql.close();  //Must close MySQL connection after Execution
}

Arduino Code:

#include "EmonLib.h"
EnergyMonitor energyMonitor;
 
float voltajeRed = 220.0; 

void setup()
{
  Serial.begin(9600);
  energyMonitor.current(0, 2.6);
}
 
void loop()
{
  double Irms = energyMonitor.calcIrms(1484);
  double potencia =  Irms * voltajeRed;

  Serial.print(Irms, 7);
  Serial.print(",");
  Serial.println(potencia, 7);
  delay(10000);
}

I set a delay in arduino from 10 seconds, get the data and printed it.
In processing, I set a serial.available to whenever detects the data from arduino, save it to a string, then (if it isn’t null) print it and send the data to the database.
But whenever I start the processing program, prints the first data, then wait 10 seconds, and the second data is ALWAYS the same as the first, but only the second, the third data and onwards works and prints okay.
I did some testing and it appears that the second time (and only the second time) reads the serial.available as 0, so it doesn’t assign a value, but it stills have the previous value, so it gets printed again and send to the database again. The third value an onwards, the serial.available gets detected correctly.

Does anyone have a clue for why this is happening? Any help would be appreciated, It’s my first time working with processing and arduino, so excuse me if the question is somewhat obvious, and I don’t realize.

One thing that jumps out as being a problem for me right away is the call to delay(10000); in your processing code. You simply don’t need it - please remove it. The fact that you’re checking for the next serial data being available is what “causes a delay” in your Processing code.

next, I would move ALL processing of your data INSIDE the conditional statement that checks to see if there is data. Like so:

void draw() {
  if ( myPort.available() > 0) {  // Is > 0 the right check here?
    val = myPort.readStringUntil('\n'); // read it and store it in val
    if (val != null) {
      a = split(val, ','); 
      println(a[0]);
      println(a[1]);
      function();  // TODO: Seriously, call this something else, like send_data()?
      // val = null; // Hrm. Might not need this.
    }
  } 
}

Anyway, try it with this draw function and see if that helps…?

3 Likes

That works perfectly, I didn’t realize that when I check the serial data availability, it’s because there is data coming from the sensor, so the delay function is not needed indeed. For best coding purposes it is better to move all the processing of the data inside the conditional statement, like you said, but I can leave it outside and set uncomment the val = null, and still works, but it is an unnecesary check of a conditional statement, so, I’ll go your way. Thank you!!

A question, why do you wrote if it is > 0 the right check here? When is equal to zero, is because there is no data coming, afaik.

I ask about the myPort.available() > 0 check, because, to me, it seems silly that myPort.available() would return a number! Either there is data, or there isn’t, so in my mind this should be returning either true or false, AKA a boolean value. I haven’t bothered to check, of course - it’s entirely possible it’s returning a number so it can report things like the port being closed (or other error messages) using negative numbers.

From what I undestand from the Processing reference page, Serial.available() returns an int, with the number of bytes available, from (I think) the data incoming. So it’s always zero until the data begins to arrive, in that moment is somewhere between 40 or 50 in my case, depending of the length of the data.

2 Likes