Can't figure out how to fix this NullPointerException

I am new to Processing, only have been working with it for a few months now, and I’m trying to create a program that takes data from Arduino and uses that to send out a tweet using Twitter4j.

I’ve narrowed down the code to where I think the problem areas might be, but I keep on getting the NullPointerException error where it says “sensorInt = int(sensorValue);”. I was wondering if anyone could help me out on this one. Thanks! :slight_smile:


Arduino arduino;
Twitter twitter;
Serial myPort;
String sensorValue;
int sensorInt;

void setup()
{  
  String portName = Serial.list()[5]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, portName, 9600);
  sensorInt = 246;

  TwitterFactory tf = new TwitterFactory(cb.build());

  twitter = tf.getInstance();
}  
void draw()
{
  sensorValue = trim(myPort.readStringUntil('\n'));
  sensorInt = int(sensorValue);
  println(sensorValue);
  if (sensorInt < 230)
  {
    tweet();
  }
  delay(500);
}```
1 Like

Two things jump out at me as being wrong immediately.

First, you’re getting a String for sensorValue, and then assuming that what you got was a String that looks like an int. This might not be the case. You should check for this situation to avoid the NPE you are getting:

  sensorValue = trim(myPort.readStringUntil('\n'));
  if( sensorValue ) { // is not a null value
    sensorInt = int(sensorValue);
    // ..whatever else you do when you get a new value.
  }

The second mistake is the call to delay(500). You do not want this in your code AT ALL - especially not in your main draw loop!

… I feel like I haven’t stressed how wrong this is. Here is some insane gibberish ranting to drive the point home:

NO NO NO A MILLION TIMES NO DELAY IS NOT WHAT YOU WANT NO NO REMOVE IT NOT DELAY NO PLEASE LORD NOT DELAY DONT USE DELAY THAT IS NOT THE FUNCTION YOU WANT TO CAUSE A DELAY DONT USE DELAY NOT DELAY THAT IS WRONG AND BAD AND NO DONT USE DELAY

ahem

Instead, consider using millis():

int time;

// In setup(), time = millis();

void draw(){
  if( time + 500 > millis() ){
    time = millis();
    // Any other actions you want to happen ever half a second,
    // Perhaps things like reading a new value from your port.
  } // End if
} // End draw
3 Likes

Hi! Thank you so much for the reply, it means a ton! I am a little bit confused on what you put in the parenthesis on this line:

It’s just giving me “Type mismatch, “java.lang.String” does not match with “boolean”” because the variable sensorValue is a string. I was also confused by the statement you said at the very beginning.

The sensorValue variable is the constant string of numbers I’m receiving from my Arduino device and I want to change that string into an int so that way I can use it to see if that value is less than 230.

Oh wait, haha I’m just tired. I figured out what you meant.

void draw() {
  if ( time + 500 > millis() ) {
    time = millis();

    if (sensorValue != null && !sensorValue.isEmpty()) {
      sensorInt = int(sensorValue);
      println(sensorValue);
      tweet();
    }
  }
}

Looking better? I don’t get the null error anymore! :+1: :smile:

2 Likes

Just a comment on the delay() thing.

Agreed! And I’d like to add that making a home-brewed waiting loop “instead of delay()” is also a big NOPE! Something like for(int i=0; i<9000000; i++) {}, or similar.

This. Btw, turn the condition around: if( millis() > time + 500 ){

But this way still have problems just before millis() rollover. Ok so it won’t happen for about 24 days and 8.5 hours (minus the interval time). So may (probably) not be needed. But if it is, then it will fire the condition constantly during the last interval period (just before millis() rollover).

Instead of comparing time points, compare time durations to avoid this:

if( (millis() - time) > interval ) {

Also works for unsigned integers (like the millis() function in Arduino, nicely explained here)

Test:

/** millis rollover test
*/

int lastTime;
int currentTime;
int rolloverSoonTest = 2147483647 - 4000;

final int interval = 1000;
boolean onState = false;

void setup() {
  size(400,400);
  
  lastTime = millis() + rolloverSoonTest;
}


void draw(){
  background(128);
  stroke(255);
  fill(255);
  currentTime = millis() + rolloverSoonTest;
  
  text("millis: " + currentTime, 50, 50);
  
  //if( currentTime > (lastTime + interval) ) { // using time points
  if( (currentTime - lastTime) > interval ) {  // using time durations
    lastTime = currentTime;
    onState = !onState;
  }

  if (onState) fill(255,0,0); else fill(0);
  circle(200,200,50);

}

1 Like

Processing’s already got frameRate() to control its draw() looping’s FPS: :nerd_face:
Processing.org/reference/frameRate_.html

Use delay() to temporarily pause other threads, not the main “Animation Thread”. :face_with_monocle:

1 Like

Okay now I have a new problem arising. I’ve fixed the setup and draw loop to:

void setup()
{  
  String portName = Serial.list()[6]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, portName, 9600);

  ConfigurationBuilder cb = new ConfigurationBuilder();
  cb.setOAuthConsumerKey("---");
  cb.setOAuthConsumerSecret("---");
  cb.setOAuthAccessToken("---");
  cb.setOAuthAccessTokenSecret("---");

  TwitterFactory tf = new TwitterFactory(cb.build());

  twitter = tf.getInstance();
}  
void draw() {
  sensorValue = trim(myPort.readStringUntil('\n'));
  if (sensorValue != null && !sensorValue.isEmpty()) {
    int sensorInt = int(sensorValue);  
    if (sensorInt < 240) {
      tweet();
    }
  }
}

But I keep on receiving null values for the sensorValue when before I was receiving the actual data from Arduino. I checked the serial monitor on Arduino to see if the sensor was still working and outputting values, and it was, Processing is just now not giving me those values. I tried all of the ports and used println(Arduino.list()); to check everything, but still no luck. Any possible guesses on how I could fix this issue? Thanks! :slight_smile:

Were you able to resolve this issue?

If you revert to an earlier version of the sketch, does that still work? When you print Serial.list(), what does it say? Before you were using 5. Also, always important to unplug / plug when the code is unchanged but communication has stopped.

1 Like

Hi! Yes I did. I had switched computers, which is why the port number had changed. :slight_smile: Thank you though! :grin:

1 Like