null pointer exception processing error

edited November 2016 in Arduino

Hello i am currently working my thesis (creation of BCI with emotiv, arduino,servo and processing). My goal is to send r and l keystrokes to move the servo right or left with emotiv. For start i have create a code in processing (actually i try to combine things that i found here in the forum) and to arduino. I get a null pointer exception error on valtowrite when i try to hit r or l keystrokes. The goal is to identify automatically the port .Please advise.

Here is the processing code:

import processing.serial.*;

Serial ser_port;                // for serial port
PFont fnt;                      // for font
int num_ports;
boolean device_detected = false;
String[] port_list;
String detected_port = "";

void setup() {
    size(400, 200);                         // size of application window
    background(0);                          // black background
    fnt = createFont("Arial", 16, true);    // font displayed in window

    println(Serial.list());

    // get the number of detected serial ports
    num_ports = Serial.list().length;
    // save the current list of serial ports
    port_list = new String[num_ports];
    for (int i = 0; i < num_ports; i++) {
        port_list[i] = Serial.list()[i];
    }
}

void draw()
{
    background(0);
    // display instructions to user
    textFont(fnt, 14);
    text("1. Arduino or serial device must be unplugged.", 20, 30);
    text("   (unplug device and restart this application if not)", 20, 50);
    text("2. Plug the Arduino or serial device into a USB port.", 20, 80);

    // see if Arduino or serial device was plugged in
    if ((Serial.list().length > num_ports) && !device_detected) {
        device_detected = true;
        // determine which port the device was plugge into
        boolean str_match = false;
        if (num_ports == 0) {
            detected_port = Serial.list()[0];
        }
        else {
            // go through the current port list
            for (int i = 0; i < Serial.list().length; i++) {
                // go through the saved port list
                for (int j = 0; j < num_ports; j++) {
                    if (Serial.list()[i].equals(port_list[j])) {
                        break;
                    }
                    if (j == (num_ports - 1)) {
                        str_match = true;
                        detected_port = Serial.list()[i];
                    }
                }
            }
        }
    }
    // calculate and display serial port name
    if (device_detected) {
        text("Device detected:", 20, 110);
        textFont(fnt, 18);
        text(detected_port, 20, 150); 
        textFont(fnt, 14);
        text("3.  Now think Right or Left in this Window",20,190);

    }
}

char valToWrite = 'r' & 'l'; //a value to send as a single byte

void keyPressed(){
  valToWrite = key;
  ser_port.write(valToWrite);
}

void keyReleased(){
  valToWrite = 'r' & 'l';
  ser_port.write(valToWrite);
}

AND here is the arduino code:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

#define SERVO_PIN 9


int pos = 0;    // variable to store the servo position
int lastMotionMillis = 0;

void setup() {
  Serial.begin(9600);
  myservo.attach(SERVO_PIN);  // attaches the servo on pin 9 to the servo object
  delay(300);
  myservo.write(90);
}

void loop() {
   if (Serial.available() ) {
     char c = Serial.read();
     if (c=='r') {
       pos = pos +25; 
       myservo.write(pos);
       lastMotionMillis = millis();
     }
     if (c=='l') {
       pos = pos -25; 
       myservo.write(pos);
       lastMotionMillis = millis();
     }

     }
   }
Tagged:

Answers

  • edit post, highlight code, press ctrl-o

    then tell us which line the null pointer is on

  • edited November 2016
    if (num_ports == 0) {
        detected_port = Serial.list()[0];
    }
    

    if there are no ports then the 1st entry (ie [0]) won't exist.

    i'd also call Serial.list() once and store the results (it returns a String[]) instead of calling it inside loops and all - it's probably way more expensive the way you are using it.

  • thank you so much for your reply. The the null pointer is on line 74. So i have to call Serial.list()?

  • @james_ange where have you initialized ser_port ?

  • in the line 3 i think

  • you think wrong.

    line 3 defines ser_point, doesn't set it to anything, doesn't initialise it.

    add a line before line 74 println("ser_point:" + ser_point);...

  • Precisely, defining a variable is different from initialising it.
    When you defined it in line 3, Java set its value to null(don't worry about why). However, you can't call a function on null, it will throw a null pointer exception.
    Hence, the NullPointerException on line 74.
    Also remember that Processing IDE will not always warn you about possible NullPointerExceptions so it is your work to verify that every variable you define is initialised.

  • Some other optimisations --

    • You don't need to do what you did from line 17 to 23. All you do is port_list = Serial.list() .
    • How are you sure that the Arduino is not already connected to your PC/laptop/whatever when the program starts up?
    • Why don't you try learning Firmata? It is a lot better if all you're trying to do is turn a Servo.
  • thank you all for your reply. So i correct the code, i initialised ser_port and the program works fine. Now the error is tha COM1 is busy. is there a way to exclude it from the loop, i ask because i don't know the port name. Sorry for my mistakes i am a rookie in programing (and sorry for my english, is not my native language) here is the new code:

    import processing.serial.*;
    
    Serial ser_port;                // for serial port
    PFont fnt;                      // for font
    int num_ports;
    boolean device_detected = false;
    String[] port_list;
    String detected_port = "";
    
    void setup() {
        size(400, 200);                         // size of application window
        background(0);                          // black background
        fnt = createFont("Arial", 16, true);    // font displayed in window
    
        println(Serial.list());
    
        // get the number of detected serial ports
        num_ports = Serial.list().length;
        // save the current list of serial ports
        port_list = new String[num_ports];
        for (int i = 0; i < num_ports; i++)  {
            port_list[i] = Serial.list()[i];
        }
    }
    
    void draw()
    {
        background(0);
        // display instructions to user
        textFont(fnt, 14);
        text("1. Arduino or serial device must be unplugged.", 20, 30);
        text("   (unplug device and restart this application if not)", 20, 50);
        text("2. Plug the Arduino or serial device into a USB port.", 20, 80);
    
        // see if Arduino or serial device was plugged in
        if ((Serial.list().length > num_ports) && !device_detected) {
            device_detected = true;
            // determine which port the device was plugge into
            boolean str_match = false;
            if (num_ports == 0) {
                detected_port = Serial.list()[0];
            }
            else {
                // go through the current port list
                for (int i = 0; i < Serial.list().length; i++) {
                    // go through the saved port list
                    for (int j = 0; j < num_ports; j++) {
                        if (Serial.list()[i].equals(port_list[j])) {
                            break;
                        }
                        if (j == (num_ports - 1)) {
                            str_match = true;
                            detected_port = Serial.list()[i];
                        }
                    }
                }
            }
        }
        // calculate and display serial port name
        if (device_detected) {
            text("Device detected:", 20, 110);
            textFont(fnt, 18);
            text(detected_port, 20, 150); 
            textFont(fnt, 14);
            text("3.  Now think Right or Left in this Window",20,190);
    
        }
    }
    
    char valToWrite = 'r' & 'l'; //a value to send as a single byte
    
    void keyPressed(){
    
      ser_port = new Serial(this, 9600);
      ser_port.bufferUntil('\n');
    
      valToWrite = key;
      ser_port.write(valToWrite);
    }
    
    void keyReleased(){
    
    
      valToWrite = 'r' & 'l';
      ser_port.write(valToWrite);
    }
    
  • edited November 2016 Answer ✓

    Since you are using Arduino, you can open up the Arduino IDE and check to see what port is being used by the Arduino device. Did you look into Firmata?

  • yes i looked into firmata library but it was a little difficult. I know what port the arduino using (in my pc for example is com9) but i want to check all the ports(its a task from my professor) as it is know. He said to me yesterday that the COM1 problem is general and i have to exclude it from the loop. But i dont know what port is. If its port[0],or port[1]. I know tha port[3] is COM9. I hope that this make sense.

  • edited November 2016

    Oh, I see the problem now, it is in line 74.
    When you initialize ser_port you use new Serial(this, 9600) which initializes it to port COM1. However, you should use new Serial(this, portname, 9600) , where portname is the name of the Arduino connected port, which in this case is port[3](as you said).

  • When i used this constructor: new Serial(this, portname, 9600)i had a problem to use another port. The point is that i can use every usb port, so eventually to use this app on every PC without to have to recompile or change the code manually .So i 've changed it to new Serial(this, 9600). Maybe if before the for loop (line 20) i could somehow exclude COM1 with an if statement? how this could be done?

  • So what you need is that the code checks which port has an Arduino, then connect to that port?

  • edited November 2016

    yes that is correct :)

  • edited November 2016

    It will take some time to figure out, but here is a start(ignoring all the code you already have, sorry):

    1. In setup(), check if any Arduino has been connected. If no, continue. If yes, skip to step 3.
    2. In draw(), check every frame if a new port has been connected to. If yes, check if it is an Arduino. If it is, continue to step 3. Otherwise, tell the user to connect an Arduino (through that existing text message in your code already).
    3. Once you find an Arduino, connect to it.

    Done, you have successfully connected to an Arduino.

  • ok thank you very much i will try it

  • Your welcome. If you have any more problems, ask here. Please mention me(with @Lord_of_the_Galaxy).

  • @Lord_of_the_Galaxy hello again i have made some progress with firmata i think is easier not to have to write a sketch to arduino a just work with processing. But one more question in the old code because i overcome the COM1 busy problem, i initialized ser_port as ser_port = new Serial(this,detected_port,9600); and the new error is that the COM9 (or COMx port is busy). Is there a way after i find the correct port to clear it so i can write the data i have to send, i think this will correct the problem but i dont know how. Is just a hopeless try not to start all over again because i run out of time :( if you have any suggestion i ll be more than happy. Here is the code again with the line i added (under void keyPressed). Thank you in advance:

    import processing.serial.*;
    
    Serial ser_port;                // for serial port
    PFont fnt;                      // for font
    int num_ports;
    boolean device_detected = false;
    String[] port_list;
    String detected_port = "";
    
    void setup() {
        size(400, 200);                         // size of application window
        background(0);                          // black background
        fnt = createFont("Arial", 16, true);    // font displayed in window
    
        println(Serial.list());
    
        // get the number of detected serial ports
        num_ports = Serial.list().length;
        // save the current list of serial ports
        port_list = new String[num_ports];
        for (int i = 0; i < num_ports; i++)  {
            port_list[i] = Serial.list()[i];
        }
    }
    
    void draw()
    {
        background(0);
        // display instructions to user
        textFont(fnt, 14);
        text("1. Arduino or serial device must be unplugged.", 20, 30);
        text("   (unplug device and restart this application if not)", 20, 50);
        text("2. Plug the Arduino or serial device into a USB port.", 20, 80);
    
        // see if Arduino or serial device was plugged in
        if ((Serial.list().length > num_ports) && !device_detected) {
            device_detected = true;
            // determine which port the device was plugge into
            boolean str_match = false;
            if (num_ports == 0) {
                detected_port = Serial.list()[0];
            }
            else {
                // go through the current port list
                for (int i = 0; i < Serial.list().length; i++) {
                    // go through the saved port list
                    for (int j = 0; j < num_ports; j++) {
                        if (Serial.list()[i].equals(port_list[j])) {
                            break;
                        }
                        if (j == (num_ports - 1)) {
                            str_match = true;
                            detected_port = Serial.list()[i];
    
                        }
                    }
                }
            }
        }
        // calculate and display serial port name
        if (device_detected) {
            text("Device detected:", 20, 110);
            textFont(fnt, 18);
            text(detected_port, 20, 150); 
            textFont(fnt, 14);
            text("3.  Now think Right or Left in this Window",20,190);
    
        }
    }
    
    char valToWrite = 'r' & 'l'; //a value to send as a single byte
    
    void keyPressed(){
    
        ser_port = new Serial(this,detected_port,9600);
    
        valToWrite = key;
        ser_port.write(valToWrite);
    }
    
    void keyReleased(){
    
    
      valToWrite = 'r' & 'l';
      ser_port.write(valToWrite);
    }
    
  • Is Arduino IDE or any other program that might use Arduino open in the background? if so, you cannot connect to the Arduino.

  • no nothing is open. I think that the port is busy because is in the loop (starts in line 36). After i find it is there a way to clear it so i can write over the data? i ve used ser_port.clear() and ser_port.stop() and and pops up the null pointer exception error again. sigh

  • No, that doesn't make sense. The port is busy as it is used by some other program and because of that you cannot connect to it. Are you certain that the Arduino is on COM9?

Sign In or Register to comment.