Skip to content

NPE in Serial Monitor with 1.5.6 Beta (Serial.serialEvent) #1885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jperedadnr opened this issue Feb 20, 2014 · 5 comments
Closed

NPE in Serial Monitor with 1.5.6 Beta (Serial.serialEvent) #1885

jperedadnr opened this issue Feb 20, 2014 · 5 comments
Labels

Comments

@jperedadnr
Copy link

Installed last nightly build available for Windows (ARDUINO 1.5.6 BETA 2014.02.19), which include the replacement of RXTX library by JSSC.

With a simple sketch on my Arduino Uno that just writes to serial port every second, when I open the Serial Monitor, after the first string appears, I've got this null pointer exception:

Exception in thread "EventThread COM6" java.lang.NullPointerException
        at processing.app.Serial.serialEvent(Serial.java:176)
        at jssc.SerialPort$EventThread.run(SerialPort.java:1112)

As the exception indicates, the problem is in the Serial.serialEvent method, when reading the serial port.

Looking at the source code:

public synchronized void serialEvent(SerialPortEvent serialEvent) {
    if (serialEvent.isRXCHAR()) {
      try {
        byte[] buf = port.readBytes();
        if (buf.length > 0){
          ...
          if (monitor) {
            System.out.print(new String(buf));
          }
          ...
        }
      } catch (SerialPortException e) {
        errorMessage("serialEvent", e);
      }
    }
  }

the null pointer exception happens when port.readBytes() returns null.

Testing this outside Arduino IDE, with a simple Java program listening to the serial port with the JSSC library, 2.8.0, I had the same exception appearing at the same point.

Just by checking that the input buffer contains some bytes with

event.getEventValue()>0

the problem will be avoided, as it seems readBytes() returns null instead of an empty array of bytes when the buffer is empty. So:

public synchronized void serialEvent(SerialPortEvent serialEvent) {
    if (serialEvent.isRXCHAR() && event.getEventValue()>0) {
      try {
          byte[] buf = port.readBytes();
          ...
          if (monitor) {
            System.out.print(new String(buf));
          }
          ...
      } catch (SerialPortException e) {
        errorMessage("serialEvent", e);
      }
    }
  }

Hope it helps,
Jose

@matthijskooijman
Copy link
Collaborator

Thanks for the report analysis! I'm wondering though, if the even is an RXCHAR event, why aren't there any bytes available? Is it perhaps that the event is triggered for every character but if the events take a while to run, the first event will read up a couple of bytes, leaving the subsequent events with nothing to read? If that was the case, I'd expect the event value (whatever that means exactly) to not indicate this. Did you have a link to the documentation for SerialPortEvent handy, perhaps?

One note wrt code blocks: It seems that github applies code block formatting to blocks, but does not preserve whitespace. Instead, indenting the source code block with at least 4 (IIRC) spaces, should give better output.

@jperedadnr
Copy link
Author

Thanks for the advise, seems that just wrapping the code with "```" works!

Regarding the RXCHAR event, as you say: if there's an event it should be bytes...

I've just made a few tests with the library, but you can find the source code here, and old documentation here and samples here.

In all the samples they check before the number of bytes in the input buffer.

I've just tested another valid solution:

public synchronized void serialEvent(SerialPortEvent serialEvent) {
    if (serialEvent.isRXCHAR()) {
      try {
          byte[] buf = port.readBytes(event.getEventValue());
          ...
          if (monitor) {
            System.out.print(new String(buf));
          }
          ...
      } catch (SerialPortException e) {
        errorMessage("serialEvent", e);
      }
    }
  }

Jose

@matthijskooijman
Copy link
Collaborator

Hmm, looking around at the source, it seems they actually use a (seemingly) inefficient and slightly weird way to handle events (it seems like they're effectively polling), causing the RXCHAR event to simply be called on every poll, instead of only when there is actually something waiting (at least while using the generic event loop, it seems the linux-specific event loop is slightly smarter).

In any case, the proposed fix looks good to me.

@ffissore
Copy link
Contributor

We are packing fixes on PR #1886
We have also built the related nightly: download it from http://arduino.cc/en/Main/Software#toc4

@jperedadnr
Copy link
Author

Just tested the new build, and now it's working, no more NPE in the Serial Monitor.

Thank you for the celerity solving this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants