Serial.read() gives null value from Arduino and or the port is not open on processing side

I’m writing a program that reads sensor data sent from Arduino and then processes it and turns it into a graph which is the exported as PDF. I originally managed to get the serial communications working between processing and Arduino, but after a few weeks of getting the rest of the project to work, I tried to re-implement the serial communication. I first had an if statement checking if the port was open but that statement was never true so I removed it and just asked processing to read whatever the port says. The null makes sense here i suppose, the port isn’t opening for some reason, but when i open the serial monitor on Arduino IDE it shows everything correct and working.

-Sorry about messy and roundabout code, I keep adding and removing little bits trying to get it to work so it all over the place now.

import processing.pdf.*;
import processing.serial.*;


float delayBetweenRecordings = 0; 
float dataPoints = 8; 
int totalGraphs = 1; 


float maximum = 0;
float minimum = 0;
float data[] = new float[int(dataPoints+1)];
float i = 0;
float graphs = 0;
float buffer = 27;
float xSpacing = (400-buffer)/dataPoints;
float ySpacing = maximum/dataPoints;
float x1;
float x2;
float y1;
float y2;
int arduinoData = 0;

Serial myPort = new Serial(this, Serial.list()[0], 9600);



void setup() {
  dataPoints += 1;
  size(400, 400);
  background(0);
  data[0] = 0;
}



void draw() {


  if (graphs < totalGraphs) {
    graphs++;
    beginRecord(PDF, "graph " + int(graphs) +".pdf");
    dataCollection();
  }

  background(51);
  gridLines();
  drawGraph();
  //debugging();
  endRecord();
}




void debugging() {

  textSize(10);
  text(mouseX, 10, 10);
  text(mouseY, 10, 20);
  text(maximum, 100, 30);
  text(minimum, 100, 40);
}

void dataCollection() {

  for (int i = 1; i < dataPoints; i++) {
    delay(int(delayBetweenRecordings*1000));
    
    arduinoData = myPort.read();
    data[i] = float(arduinoData);
    println(data[i]);


    if (data[i] > maximum-10) {
      maximum = data[i]+10;
    }

    if (data[i] < minimum+10) {
      minimum = data[i]-10;
    }
  }
}

void drawGraph() {
  for (int i = 1; i < dataPoints; i++) {
    x1 = (i-1)*xSpacing+buffer;
    x2 = (i)*xSpacing+buffer;
    y1 = height-map(data[i-1], minimum, maximum, 0, height);
    y2 = height-map(data[i], minimum, maximum, 0, height);
    stroke(0, 255, 0);
    strokeWeight(10);
    strokeWeight(1);
    line(x1, y1, x2, y2);
  }
}

void gridLines() {
  for (int i = int(minimum/10); i <= (maximum/10); i++) {
    textSize(10);
    fill(0, 255, 0);
    text(i*10, 5, height-map(i*10, minimum, maximum, 0, height));
    stroke(100);
    line(buffer, height-map((i-1)*10, minimum, maximum, 0, height), width, height-map((i-1)*10, minimum, maximum, 0, height));
  }
}

1 Like

What does the error exactly say?

What line is hightlighted when Processing throws the error?

Kf

Hi,

  1. In the serial examples SimpleRead has the “…new Serial…” in setup while yours is in the global area at the top. I don’t know if that makes any difference.

  2. portName = Serial.list()[0]; - this assumes that your device is first in the list. With the coming and going of Ardino(s) and other devices yours might not be the first. Try printing the list, or hard-coding the name e.g. portName = “COM32”. (Cheaper so-called Arduinos with the Chinese CH340 chip can change their com name depending on which usb socket they are plugged in.)

  3. When your Processing program starts, it opens the port, which will reset the Arduino, and presumably, after a set time, it will start sending serial. Is the processing program ready by then? Try a delay before Ard starts sending to make sure Processing is ready.

Richard

1 Like

Actually this is important. This line is in the global scope. You should do instead

Serial myPort;

void setup(){
   myPort = new Serial(this, Serial.list()[0], 9600);
   ....

}

At the end of setup() you should add a delay of 500 or 1000 ms as some units seem to go into a reset cycle. This delay will ensure the unit is ready. However, I am not sure if this applies in your case. Just add delay(1000);.

Kf

1 Like

Thanks for the replies.
I moved the myPort line into setup, and change the serial list to explicitly say “COM5” instead of Serial.list()[0].

Serial myPort;

void setup() {
  myPort = new Serial(this, "COM5", 9600);

The port gives me just nulls if I use println(myPort.readString()), and if I do println(myPort.read()) it outputs lots of -1’s. Obviously I get a NPE if I try to convert the null into a float for use in the graph, but the -1 goes fine and i just get a straight line.

Arduino IDE Serial Monitor

Please provide your ino code. Or a short portion of your output data from the serial monitor.

Make sure the serial monitor is not running when you run your Processing code.

Also, look at @GoToLoop’s code here: https://forum.processing.org/two/discussion/16618/processing-with-arduino-void-serialevent#Item_5 and see if you can modify it for your case. Use it for testing your unit independent of your code changes and other implementations there in your first code.

Lastly, make sure you are processing at the same speed aka. bps in the serial monitor instantiation.

Kf

1 Like
/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface. The device's I2C address is either 0x76 or 0x77.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;

void setup() {
  Serial.begin(9600);
//  Serial.println(F("BME280 test"));

  bool status;

  // default settings
  status = bme.begin();
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  //Serial.println("-- Default Test --");
  delayTime = 1000;

  //Serial.println();

  delay(100); // let sensor boot up
}


void loop() {
  printValues();
  delay(delayTime);
}


void printValues() {
//  Serial.print("Temperature = ");
  Serial.println(float(bme.readTemperature()));
//  Serial.println(" ");
//
//  Serial.print("Pressure = ");
//  Serial.print(bme.readPressure() / 100.0F);
//  Serial.println(" hPa");
//
//  Serial.print("Approx. Altitude = ");
//  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
//  Serial.println(" m");
//
//  Serial.print("Humidity = ");
//  Serial.print(bme.readHumidity());
//  Serial.println(" %");
//
//  Serial.println();
}

There’s the Arduino code. Its just example code for the sensor I’m using with some of the println’s commented out so I could get one thing working at a time and then include all the println’s later or change how they are presented to processing.

The baudrate in processing and Arduino are the same (9600) and I always close the serial monitor in Arduino before running the processing code. Processing stops responding and Arduino says the port is in use if I try running one while the other is already open.
The correct data comes through on serial monitor, but processing gives either -1’s or null.

Hi again,

Your Arduino program is occasionally printing a few ascii characters e.g. 24.35 followed by crlf. So that’s a total of 7. They are bytes reprisenting ascii characters e.g the 2 is byte value 50 (see an ascii table, lots on web).

Arduino’s println confuses things by being helpful and converting other data types to string, so even if you’ve put float( it will convert to string - as you see printed on the serial monitor.

The processing program is using Serial.read which might give you the value of one of the bytes, or -1 in the periods in-between a character arriving.

You have to chose between sending binary values, or string values. The processing serial library example SimpleRead uses a binary value. The value as sent from the Arduino is not printable on the serial monitor. It works for 1 value in 1 byte, but if you add more there’s nothing to make sure you interpret the received bytes starting in the right place.

Using printable characters as from your Ard program is probably better to start, because you can see them on the monitor, and then on Processing’s console.

I suggest you try this in Processing. See various uses of “if Serial.available()” If there is an input char available, append it on to the end of a String variable. Then print out the growing string. Now you can see the values arriving. Next use the first space in the string to identify the portion with the first value. String functions to convert the first value to float, and delete it from the string.

I hope that makes sense we can discuss details as you try things.

Richard.

Richard, the problem I’m having is that none of the correct values even get over to processing side. I’m not sure if I said but when I use myPort.available(), it is always false and nothing gets printed. I made a new Arduino and new processing script to just try get the serial part working without the rest of the mess and I can’t even get that to work correctly.

New processing code:

import processing.serial.*;

Serial myPort;
String data;
void setup() {
  myPort = new Serial(this, "COM5", 9600);
}

void draw() {
  data = myPort.readString();
  if (myPort.available()>0) {
    println(myPort.readString());
  }
}

Here’s the new Arduino code:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(random(10));
  delay(500);
}

Processing opens a blank window and outputs nothing into the console.
Arduino Serial monitor (and also a third party serial monitor I got just to check that it’s not being stupid) shows the random numbers from the code. No I do not have the third party serial monitor open when I am trying to get processing to read the serial port.

Comment out this line from draw:

data = myPort.readString();

Make sure all reading is done inside the “if available” block.

1 Like

I’ve just tried it (with noabuddy’s change) and it’s working for me. Printing the numbers with a blank line in-between because the Ard println puts end-of-line, that goes into Processing’s string, and Processing prints an eol of its own.

1 Like