"Error, disabling serialEvent() for COM3 null" Enviando y recibiendo datos

Hola, muchas gracias por la ayuda, he buscado por miles de sitios en hilos con la misma pregunta pero no logro dar con la solución, estoy realizando un proyecto donde tengo que utilizar múltiples sensores y visualizarlos en Processing, todo funciona bien la primera vez, pero supongamos que cierro la ventana del programa y lo vuelvo a iniciar es ahí cuando en processing me da ese error “Error, disabling serialEvent() for COM3 null” y no puede volver a iniciar a menos que yo desconecte y conecte de nuevo el USB, así que necesitaría resolver este asunto con código, saber qué estoy haciendo mal? Muchas gracias.

Código en Arduino:

#include <DHT.h>       
#define DHTPIN A5     
#define DHTTYPE DHT11 
String dato;           
int rawValue;           
const int led = 13;   
 const int led2 = 12;   
 char valor = 0;         
const int SENSOR = A0; 
 int aire = 0;         
 int analogPin=A4;         

DHT dht(DHTPIN, DHTTYPE);   
unsigned long TiempoAhora = 0;


bool heartbeatDetected(int IRSensorPin, int delay)
{
  static int maxValue = 0;
  static bool isPeak = false;
   
   
  bool result = false;
     
  rawValue = analogRead(IRSensorPin);
    rawValue *= (1000/delay);
 
 
  if (rawValue * 4L < maxValue) {    maxValue = rawValue * 0.8;  }   
  if (rawValue > maxValue - (1000/delay)) {
   if (rawValue > maxValue) {
      maxValue = rawValue;
    }
        if (isPeak == false) {
      result = true;
    }
    isPeak = true;
  } else if (rawValue < maxValue - (3000/delay)) {
    isPeak = false;
   
    maxValue-=(1000/delay);
 }
  return result;
}


void setup()
{
 Serial.begin(115200);       
dht.begin();           
analogReference(1);     
 pinMode(led,OUTPUT);     
 pinMode(led2,OUTPUT);
 digitalWrite(led,LOW);     
 
}

const int delayMsec = 30; // 100msec per sample
 
void loop()
{


static int beatMsec = 0;
  int heartRateBPM = 0;
  if (heartbeatDetected(analogPin, delayMsec)) {
    heartRateBPM = 60000 / beatMsec;
   digitalWrite(led2,1);
 
     
    beatMsec = 0;
  } else {
    digitalWrite(led2,0);
  }
  delay(delayMsec);
  //delay(30);
  beatMsec += delayMsec;

//  TiempoAhora = millis();
//  beatMsec += delayMsec;
//  while(millis()< TiempoAhora+delayMsec){
//  }

 
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  float hic = dht.computeHeatIndex(t, h, false);
  aire = analogRead(SENSOR)*1;
  dato = ",";
  dato += t;
  dato += ",";
  dato += aire;
  dato +=",";
  dato +=h;
  dato +=",";
  dato +=heartRateBPM;
  Serial.println(dato);
   
 if (Serial.available() > 0)
                             
 {
  valor = Serial.read();   
                           
                         
  if (valor == 'E')       
                           
  {                       
   digitalWrite(led,HIGH);
 }
  else if (valor == 'A')
                         
  {                     
   digitalWrite(led,LOW);
  }
   else                 
  {                     
   Serial.println("Caracter NO PERMITIDO"); 
  }
 }
}

Código en Processing: También tengo un “void apagar” para desconectar el puerto serie con un botón creado en el GUI y cuando lo uso el resultado es el mismo, luego de apagar y encender el puerto por segunda vez me da el mismo error.

import g4p_controls.*;
import processing.serial.*;
import peasy.*;
Serial puerto;
boolean encendido = false;
float datoanterior = 0;


float inByte[] = {0,0,0,0,0};
boolean newData = false;
int xPos = 0;         
int lastxPos=1;
int lastheight=0;
//Fin de gráfica...............


public void setup(){
  size(1000, 600, JAVA2D);
  createGUI();
  customGUI();
  //puerto = new Serial(this,"COM4", 9600);
   background(17,34,51);     
  rect(0, 95, 999, 355,1);
   stroke(196,196,196);
   fill(258,258,258);
   textSize(13);
   text("Amplitud",562,565);
   text("Zero",685,565);
 
   for (int i = 0; i < 999; i=i+20) {
  line(20+i, 95,20+i, 450);
  } 
  for (int i = 0; i < 350; i=i+20) {
  line(0, 95+i, 1000, 95+i);
  }
 
}


public void draw(){
    fill(17,34,51);
  rect(820, 0, 130, 80,1);
   fill(258,258,258);//Color del Texto arriba derecha.
    textSize(13);
    text("Fecha: "+day()+"/"+month()+"/"+year(),828,30);
    text("Hora: "+hour()+":"+minute()+":"+second(),828,50);
   
    fill(17,34,51); 
    rect(7, 451, 170, 80,1);
    fill(258,258,258);
    textSize(16);
    text("Temperatura: "+inByte[1]+"°C",7,470);
    text("Humedad: " + inByte[3]+"%",7,500);
    //text("BPM: " + inByte[4],7,530);
   
   
    if(inByte[4]>0){
    datoanterior = inByte[4];
    text("BPM: " + inByte[4],7,530);
    }
    else {
    text("BPM: " + datoanterior,7,530); 
    }
   
   
 if (newData) {
    stroke(17,34,51);     
   strokeWeight(1);       
    line(lastxPos, lastheight, xPos, height - inByte[0]);
    lastxPos= xPos;
    lastheight= int(height-inByte[0]);
   
   if (xPos >= width) {
      xPos = 0;
      lastxPos= 0;
      saveFrame( "Pantallazos Automáticos cada 30s"+"/"+day()+"-"+month()+"-"+year()+" a las "+hour()+"_"+minute() +" con "+ second()+"s"+ ".png") ;
     
      rect(0, 95, 999, 355,1);
     stroke(196,196,196);
   
      for (int i = 0; i < 999; i=i+20) { 
      line(20+i, 95,20+i, 450);
    } 
      for (int i = 0; i < 350; i=i+20)
      line(0, 95+i, 1000, 95+i);
  }
    }
    else {
      // Incrementa la posición horizontal.
      xPos++;
    }
   newData =false;
 }
}
 
public void customGUI(){

}

void serialEvent (Serial myPort) {
  // obtener la cadena ASCII:
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    inString = trim(inString);               
    inByte = float(split(inString, ','));
    inByte[0] = float(inString);         
    inByte[0] = map(inByte[2], 0, 1023, 0, height);
   newData = true;
   
   
  }
}

void Encender(){
  puerto.write('E');
}

void Apagar(){
  puerto.write('A');
 
}

void GuardarPNG(){
  saveFrame( "Pantallazos Guardados con Click"+"/"+day()+"-"+month()+"-"+year()+" a las "+hour()+"_"+minute() +" con "+ second()+"s"+ ".png") ; }

void onoff(){
  if (encendido == false) {
  puerto = new Serial(this,Serial.list()[0], 115200);
  encendido = true;
  }
  else {
 
  puerto.stop();
  encendido = false;
 
  }
}

void Terminar(){
  exit();
}

Muchas gracias.

1 Like

¿En qué número de línea se produce el error?

try a serial event like

https://gitlab.com/snippets/1928961 ,

means check if data exist ( inByte.length >= 5 )
before try to use them

also i would not use like

void onoff(){

start the arduino first and use

puerto = new Serial(this,Serial.list()[0], 115200);

in setup again.
a switch connection OFF and ON might not work anyhow…
– or even if, it forces a ( actually 2 ) reboot on most of the Arduino boards ( not Leonardo ?)
what might need some seconds wait / clean serial line… ??

Hola Jeremy, el error aparece en cualquier línea donde haya hecho un print de los datos de los sensores, este es el texto de error completo “ArrayIndexOutOfBoundsException: 4” y “Error, disabling serialEvent() for COM3 null”. Entonces en este caso el error aparece en la línea donde intento imprimir la Temperatura "text("Temperatura: “+inByte[1]+“°C”,7,470);”, pero si comento esa línea el error será en la siguiente línea donde intente imprimir algún dato, y si comento todas las líneas donde intento imprimir datos y pongo un simple println para ver los datos recibidos, el error será en ese printl.

Hi Kll, thanks for your reply.
Well, I commented that the “void onoff ()” function was removed and still closing the program and reopening it gives me the same error even if it lasts up to a minute.

Then the link that sent me https://gitlab.com/snippets/1928961 seems to handle the incoming data very well, however I cannot make a “println” of a single data with that code in processing, how could I achieve it?

I mean print the four data in a row, how could I print only the data I need?

not understand the question,
if you use my example code and log is ON then each line is printed to console
( if understood as integer CSV line )


show your actual code,
show what it prints
tell us how it should look like

Exactly, all the sensors are printed on the console line, but with that same code how can I have the value of only one of the sensors printed and not all of them?

still not understand the question,
in your very first code you do like

so you know how to use one value of an array?


other way would be to have readable variables

float temperatura,humedad,bpm;

// in serial event set it
temperatura = datai[1];
//...

//and in draw() can now use
text("Temperatura: "+temperatura+"°C",7,470);

I tried to do it as you suggested and it returned this error.

Captura

This was the code I used.

import processing.serial.*;

Serial myPort;
String datas; //_________________________________________ latest arduino text line
int[] datai; //__________________________________________ as array of integers
boolean log = false; //__________________________________ diagnostic print

float temperatura,humedad,bpm;



void setup_serial() { //_________________________________ USB arduino..
  printArray(Serial.list());
  String portName = Serial.list()[0]; //_________________ adjust 0.. x port
  myPort = new Serial(this, portName, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  //println("try connect to "+portName+"\n enable log print key [d]");
  
}

void serialEvent(Serial p) { //__________________________ handle serial data
  datas = trim(p.readStringUntil('\n'));
  temperatura = datai[1];
  if (datas != null) {
    //println(datas); //________________________ optional print every GOOD line
    datai = int( split(datas, ",") ); //_________________ create int array from CSV type line
    if ( datai.length >= 3 ) { //________________________ if find min 2 "," and understood 3 integer
       for ( int i=0; i < datai.length; i++ ) 
         if ( log ) print(datai[i]+" , ");
       if ( log ) println();
    } else println("shortline ",datas);
  }
}

void setup() {
  size(100, 100);
  setup_serial();
}

void draw() {
  background(0, 0, 80);
  println(datai[1]);
}

//void keyPressed() {
//  if ( key == 'd' ) { 
//    log = ! log;
//    println("log "+log);
//  }
//}

//tested win 10 / processing 3.5.3
//arduino 1.8.10 / arduino leonardo

I appreciate the help.

I tried it this way and it only returns values of 0.0.

import processing.serial.*;

Serial myPort;
String datas; //_________________________________________ latest arduino text line
int[] datai; //__________________________________________ as array of integers
boolean log = false; //__________________________________ diagnostic print

float temperatura,humedad,bpm;



void setup_serial() { //_________________________________ USB arduino..
  printArray(Serial.list());
  String portName = Serial.list()[0]; //_________________ adjust 0.. x port
  myPort = new Serial(this, portName, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  //println("try connect to "+portName+"\n enable log print key [d]");
  
}

void serialEvent(Serial p) { //__________________________ handle serial data
  datas = trim(p.readStringUntil('\n'));
  temperatura = datai[1];
  if (datas != null) {
    //println(datas); //________________________ optional print every GOOD line
    datai = int( split(datas, ",") ); //_________________ create int array from CSV type line
    if ( datai.length >= 3 ) { //________________________ if find min 2 "," and understood 3 integer
       for ( int i=0; i < datai.length; i++ ) 
         if ( log ) print(datai[i]+" , ");
       if ( log ) println();
    } else println("shortline ",datas);
  }
}

void setup() {
  size(100, 100);
  setup_serial();
}

void draw() {
  background(0, 0, 80);
  println(temperatura);
}

//void keyPressed() {
//  if ( key == 'd' ) { 
//    log = ! log;
//    println("log "+log);
//  }
//}

//tested win 10 / processing 3.5.3
//arduino 1.8.10 / arduino leonardo

Captura

again, only use data if you are sure they exist.

void serialEvent(Serial p) { //__________________________ handle serial data
  datas = trim(p.readStringUntil('\n'));
  //temperatura = datai[1];
  if (datas != null) {
    //println(datas); //________________________ optional print every GOOD line
    datai = int( split(datas, ",") ); //_________________ create int array from CSV type line
    if ( datai.length >= 3 ) { //________________________ if find min 2 "," and understood 3 integer
       for ( int i=0; i < datai.length; i++ ) 
         if ( log ) print(datai[i]+" , ");
       if ( log ) println();
       temperatura = datai[1];
    } else println("shortline ",datas);
  }
}

Perfect, it works perfect, thank you very much for the help. : D