Null Pointer Exception with Arduino Communication

So I am running into this issue with my Processing code where I am getting null pointer exceptions whenever it runs over the port.write() line. Just for some background, what I am trying to do is have the Processing code process the controller input from my Xbox One controller and make it into codes that start with a letter and position for servos/motors and send that through the serial port. Then, the Arduino has its own code as it utilizes a motor shield, but it will translate these codes that are sent through the serial port in order to move the motors and servos. My code below has a lot of commented-out lines of code, but I merely do that for testing.
Processing:

import processing.serial.*;
import net.java.games.input.*;
import org.gamecontrolplus.*;
import org.gamecontrolplus.gui.*;
import cc.arduino.*;
//import org.firmata.*;

Serial port;
ControlDevice cont;
ControlIO control;
Arduino arduino;
float swivel, screw, rail, selectcontrol;
boolean shoulderselect, elbowselect, clawarmselect, clawgrab, clawrelease;
String portmessage;

PImage splash;

void setup(){
  size(700, 400);
  control = ControlIO.getInstance(this);
  cont = control.getMatchedDevice("STAR_2021_Artificial_Astronauts_controls");
  
  if (cont == null) {
    println("No suitable device configured, exiting program"); // write better exit statements than me
    System.exit(-1);
  }
  
  splash = loadImage("Artificial Astronaut Control Scheme");
  println((Object[])Arduino.list());
  arduino = new Arduino(this, Arduino.list()[2], 9600);
  //arduino.pinMode(9, Arduino.SERVO); //claw
  //arduino.pinMode(10, Arduino.SERVO); //claw arm
  //arduino.pinMode(11, Arduino.SERVO); //drill arm
}

public void getUserInput() {
  screw = map(cont.getSlider("Screw").getValue(), -1, 1, 0, 180);
  swivel = map(cont.getSlider("SwivelJoint").getValue(), -1, 1, 0, 180);
  rail = map(cont.getSlider("Rail").getValue(), -1, 1, 0, 180);
  selectcontrol = map(cont.getSlider("SelectControl").getValue(), -1, 1, 0, 360);
  shoulderselect = cont.getButton("ShoulderSelect").pressed();
  elbowselect = cont.getButton("ElbowSelect").pressed();
  clawarmselect = cont.getButton("ClawArmSelect").pressed();
  clawgrab = cont.getButton("ClawGrab").pressed();
  clawrelease = cont.getButton("ClawRelease").pressed();
}


            
void draw() {
  getUserInput();
  background(selectcontrol,700,400);
  println("You are now in Control >:)");
  //send a list that consists of the joint's name and, position(and direction) to the serial for the arduino
  if(clawarmselect == true){ //control claw arm with right stick
    //arduino.servoWrite(11, (int)selectcontrol);
    println("Selecting the claw arm to control, use the right stick to control");
    portmessage = "A"+str((int)selectcontrol);
    port.write(portmessage);
  }
  
  if(elbowselect == true){ //control elbow with button and control right stick
    //arduino.servoWrite(11, (int)selectcontrol);
    println("Selecting the elbow to control, use the right stick to control");
    portmessage = "B"+str((int)selectcontrol);
    port.write(portmessage);
  }
  
  if(clawgrab == true){ //close claw
    //arduino.servoWrite(9, 90);
    println("Claw Closing");
    port.write("C90");
  }
  
  if(clawrelease == true){ //open claw
    //arduino.servoWrite(9, 180);
    println("Claw Opening");
    port.write("C180");
  }
  
}

Arduino:

#include <Wire.h>
#include <Servo.h>
#include <Adafruit_MotorShield.h>

//set up motorhsield
Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x60);

//assign motors
Adafruit_DCMotor *RailMotor = AFMS.getMotor(1);
Adafruit_DCMotor *Swivel = AFMS.getMotor(2);
Adafruit_DCMotor *Elbow = AFMS.getMotor(3);
Adafruit_DCMotor *Drill = AFMS.getMotor(4);

//call the servo library
Servo DrillArm;
Servo ClawArm;
Servo Claw;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  // create with the default frequency 1.6KHz
  AFMS.begin();

  // Attach a servo to pin #10 and pin #9
  DrillArm.attach(11);
  ClawArm.attach(10);
  Claw.attach(9);

  // turn on motor M1
  RailMotor->setSpeed(300);
  RailMotor->run(FORWARD);
  RailMotor->run(BACKWARD);
  RailMotor->run(RELEASE);

  // turn on M2
  Swivel->setSpeed(200);
  Swivel->run(FORWARD);
  Swivel->run(BACKWARD);
  Swivel->run(RELEASE);

  // turn on motor M3
  Elbow->setSpeed(200);
  Elbow->run(FORWARD);
  Elbow->run(BACKWARD);
  Elbow->run(RELEASE);

  // turn on M2
  Drill->setSpeed(200);
  Drill->run(FORWARD);
  Drill->run(BACKWARD);
  Drill->run(RELEASE);
}

//setting variables
int ClawClose = 90, ClawOpen = 180, mapping;
String MotorCode = "C90", str;

void loop() {
  Serial.println("ok so the loop started");
  // put your main code here, to run repeatedly:
  if (Serial.available()){
    MotorCode = String(Serial.read());
    Serial.println(MotorCode);
  }

  if (MotorCode.indexOf(0) == "C"){
    str = MotorCode.substring(1,-1);
    Serial.print(str);
    mapping = str.toInt();
    Claw.write(map(mapping, 0, 180, 0, 180));
  }
  RailMotor->run(FORWARD); //go up rails
  //delay(1000);
  RailMotor->run(BACKWARD);
  //delay(1000);
  RailMotor->run(RELEASE);
  
  //motion claw and claw arm to the position to grab rail
  //ClawArm.write(map(180, 0, 180, 0, 180));
  //delay(1000);
  //ClawArm.write(map(0, 0, 180, 0, 180));
  //Claw.write(map(ClawClose, 0, 180, 0, 180));
  //delay(1000);
  //Claw.write(map(ClawOpen, 0, 180, 0, 180));
  //DrillArm.write(map(180, 0, 180, 0, 180));
  //DrillArm.write(map(0, 0, 180, 0, 180));
  
  //rotate drill arm on the swivel point
  Swivel->run(FORWARD);
  //delay(1000);
  Swivel->run(BACKWARD);
  //delay(1000);
  Swivel->run(RELEASE);
  
  Elbow->run(FORWARD);
  //delay(1000);
  Elbow->run(BACKWARD);
  //delay(1000);
  Elbow->run(RELEASE);
  
  //test the drill forward & backward
  Drill->run(FORWARD);
  //delay(1000);
  Drill->run(BACKWARD);
  //delay(1000);
  Drill->run(RELEASE);
}

Try:

// arduino = new Arduino(this, Arduino.list()[2], 9600);
port = new Serial(this, Serial.list()[2], 9600);

References:
https://processing.org/reference/libraries/serial/index.html

:)

Ok after editing some of the initial stuff it stopped giving that error! The only thing is that I don’t think that the Arduino is receiving the serial data. I know that the ports aren’t two-way, but can the Arduino get the Serial messages being sent through from the processing code?

Hi @PapiAli. The port is 2 way! I have several projects with separate data-streams going Processing->Ard and Ard->Processing. There are many reasons why it might not appear to be working. Most Ard have leds TX and RX (Transmit and receive.) Simply seeing the RX light flashing proves that Processing is sending something. It doesn’t prove the Ard understands it in the way you want. I suggest you try each of the Serial examples (Processing, File, Examples, Libraries, Serial). While you are developing transmit only 2/Sec so you can see the lights flash and the prints of what you are transmitting.

sure it receive serial data if not how Arduino IDE upload sketch to Arduino

Ok, I am now able to get it responding to the software, but it only works well with single characters. Is it just how I am formatting the strings, or can the Arduino only receive one character at a time through the Serial? It only seems to work if I use single characters.
Arduino:

while (Serial.available()>0){
    String MotorCode = Serial.readString();

    if (MotorCode.substring(0) == "C"){
      Claw.write(map(MotorCode.substring(1,-1).toInt(), 0, 180, 0, 180));
      digitalWrite(LED_BUILTIN,HIGH);
    }
    else {
      digitalWrite(LED_BUILTIN,LOW);
    }

  }

Processing:

void draw() {
  getUserInput();
  background(selectcontrol,700,400);
  println("You are now in Control >:)");
  
  //send a list that consists of the joint's name and, position(and direction) to the serial for the arduino
  if(clawarmselect == true){ //control claw arm with right stick
    println("Selecting the claw arm to control, use the right stick to control");
    portmessage = "A"+str((int)selectcontrol);
    println(portmessage);
    port.write(portmessage);
  }
  
  if(elbowselect == true){ //control elbow with button and control right stick
    println("Selecting the elbow to control, use the right stick to control");
    portmessage = "B"+str((int)selectcontrol);
    println(portmessage);
    port.write(portmessage);
  }
  
  if(clawgrab == true){ //close claw
    println("Claw Closing");
    port.write("C90");
  }
  
  if(clawrelease == true){ //open claw
    println("Claw Opening");
    port.write("C180");
  }

I’m not sure what you mean, but as long as there isn’t another IDE trying to access the serial port then you can upload it.

they are two-way for sure

@PapiAli From your code I see that your command protocol to the Arduino is this: One character, e.g. ‘A’ or ‘C’ followed by a number, which might be 2 or 3 chars. As I see it the problem is your Ard code will start reading what’s come in as soon as e.g. ‘C’ arrives, but the value hasn’t arrived yet. So it will see just ‘C’ and the ‘90’ will be in the input buffer for next time. Think you should use a line-feed character on the end and instead of if (available) use ReadBytesUntil . Then your Ard will have the whole message to work on.

I see you are using a LED to indicate code flow. Just thinking about tools to help you. What type of Arduino is it? Do you have any displays LCD, OLED, or TTL-USB adaptor?

You don’t need all the ‘== true’. If (booleanvar) makes sense.

1 Like

I have an Arduino Uno R3, and unfortunately, I don’t have any displays. What do you mean by:

I am looking at the function, and it’s only saying how many bytes are passing through. I think instead what you mean is to use “readStringUntil()” since the context makes a bit more sense for this. I have made the line-feed character a lowercase “c” just for testing purposes.
Heres is what I have for the Arduino now(still not working):

void loop() {
  //Serial.println("ok so the loop started");
  // put your main code here, to run repeatedly:
  while (Serial.available()>0){
    String MotorCode = Serial.readStringUntil("c");

    if (MotorCode.substring(0) == "C"){
      Claw.write(map(MotorCode.substring(1,-1).toInt(), 0, 180, 0, 180));
      digitalWrite(LED_BUILTIN,HIGH);
    }
    else {
      digitalWrite(LED_BUILTIN,LOW);
    }

  }

I have a feeling it has something to do with how I am decomposing the string, as I don’t know much about decomposing strings in Arduino.

I’m playing with a test program, it;s not doing what I want. (Please wait.) I think the difference between readBytesUntil and readStringUntil is only the type of var that it writes to. I’m convinced by this that strings are evil, and they didn’t exist when I learned C. I meant that you don’t need to use Serial.available()>0 because you can call readBytesUntil repeatedly and detect success from it’s return value.

Hello @PapiAli,

Some resources here:

:)

I have to stop soon (22:15 UK) but have some pieces working. In your Processing code, in each section you need to set the boolean false to prevent it sending multiple times:


  if(clawgrab){
    print("Claw Closing ");
    port.write("C90");
    clawgrab = false;
  }

In the Arduino before setup

#define dW digitalWrite
#define buffsize 50
char buffer[buffsize];

in loop

    int res;
    if (Serial.available() > 0)
    {
      res = Serial.readBytesUntil('x', buffer, buffsize);
      Serial.print(res); Serial.print(" ");
      if (res > 0) {dW(led2, 1);}
      else         {dW(led2, 0);}
    }

This is correctly flashing the led each time it receives some chars terminating with x. I’ve included the .available() despite what I said before. Your application only sends occasionally, but I’m more used to things being sent regularly. We don’t want the readBytesUntil to timeout, and we don’t want to use a big timeout as that would prevent the Ard code doing other things.

I’m using Serial.print to see what the Ard is doing, and testing using Putty, just typing in chars. The Ard serial monitor is similar but I prefer the interaction with Putty. (Don’t leave Putty running and try to reload.)

Thank you! I put that into my program and it seems to be working correctly in getting the number of characters. The only thing is, I am not sure how I am going to apply this to my code with my servos and motors? The main thing I wanted to do with the Serial ports is to send a code that the Arduino would decode and apply to the motors and servos. Perhaps I could do this with bytes, but how feasible would this be?

I can’t look at it now, but here are 2 sscanf examples that get values from character arrays into integers.

sscanf(buffer, "%s %d %d %d", &z, &pc_count, &mouse_x, &mouse_y);
sscanf(&buff[star_ix + 4], "%d", &val);

hi

study this code if you understand it then you can code whatever you need via serial

//--------------------------------------------
//  Ardino code**
//---------------------------------------------

#include <SoftwareSerial.h>
#include <Wire.h>

SoftwareSerial mySerial(11, 12); // RX, TX

int red_led = 3;
int green_led = 6;
int blue_led = 5;
int int_1 = 0;
int int_2 = 0;
int int_3 = 0;
const byte number_of_chars = 32;
char receivedChars[number_of_chars];
boolean new_data = false;

void setup() {
  mySerial.begin(9600); // Set the baudrate equal to HC06 setting
  Serial.begin(9600);
  pinMode(red_led, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(blue_led, OUTPUT);
}

void loop() {
  receivePacket();
  if (new_data == true) {
    parseData();
    executeParsedData();
    new_data = false;
  }
}

void receivePacket() {
  static boolean receiving = false;
  static byte index = 0;
  char start_mark = '<';
  char end_mark = '>';
  char rc;
  while (mySerial.available() > 0 && new_data == false) {
    rc = mySerial.read();
    if (receiving == true) {
      if (rc != end_mark) {
        receivedChars[index] = rc;
        index++;
        if (index >= number_of_chars) {
          index = number_of_chars-1;
        }
      } else {
        receivedChars[index] = '\0';
        receiving = false;
        index = 0;
        new_data = true;
      }
    } else if (rc == start_mark) {
      receiving = true;
    }
  }
}

void parseData() {
  char * split;
  split = strtok(receivedChars, ",");
  int_1 = atoi(split);
  split = strtok(NULL, ",");
  int_2 = atoi(split);
  split = strtok(NULL, ",");
  int_3 = atoi(split);
}

void executeParsedData() {
  if (int_3 == 0) {
    analogWrite(red_led, 0);
    analogWrite(green_led, 0);
    analogWrite(blue_led, 0);
  } else if (int_3 == 1) {
    analogWrite(red_led, 255);
    analogWrite(green_led, 255);
    analogWrite(blue_led, 255);
  } else if (int_3 == 2) {
    if (int_2 == 0) analogWrite(red_led, int_1);
    if (int_2 == 1) analogWrite(green_led, int_1);
    if (int_2 == 2) analogWrite(blue_led, int_1);
  }
}


Android-java-code-utilities-widgets-for-Processing-for-Android

this other example using switch case

processing side


import controlP5.*;
import processing.serial.*;
 
ControlP5 cP5a;
ControlP5 cP5b;
 
Serial arduino;
 
void setup() {
  size(350,120);
 printArray(Serial.list());
 
  arduino = new Serial(this, Serial.list()[0], 9600);
 
  cP5a = new ControlP5(this);
  cP5a.addSlider("CYCLE_TIME", 999, 1999,999, 10, 10, 255, 35);
  cP5b = new ControlP5(this);
  cP5b.addSlider("PULSE", 55, 455, 55, 10, 55, 255, 35);
}
 
void draw()  {
  background(0);
 
  }
 
void controlEvent(ControlEvent theEvent) {
  if(theEvent.isController()) {
 
 print("control event from : "+theEvent.getController().getName());
 println(", value : "+theEvent.getController().getValue());
 
 if(theEvent.getController().getName()=="CYCLE_TIME") {
   int val1 = int(theEvent.getController().getValue());
   arduino.write("a" + val1+"\n");
 
 }
 
 if(theEvent.getController().getName()=="PULSE") {
   int val2 = int(theEvent.getController().getValue());
   arduino.write("b" + val2+"\n" );
   }
  }
}

Arduino side

void loop() {  
  
 
  
     if (Serial.available() >= 2)
 
  {
    int value2;
    char command = Serial.read();
    switch (command)
    {
    case 'a': value2 = Serial.parseInt();
      CYCLE_TIME = value2;
      break; 
     
 {

    case 'b': value2 = Serial.parseInt();
     TX_PULSE = value2;
       
   break;
        }

@PapiAli Try this program in your Ard.

#define buffsize 50
char buffer[buffsize];

void setup(){
  Serial.begin(9600);
  Serial.setTimeout(2000);}
  
void loop(){
  int res;
  int val;
  if (Serial.available() > 0){
    res = Serial.readBytesUntil('Z', buffer, buffsize);
    Serial.print(res); Serial.print(" ");
    buffer[res] = 0;  // terminate the 'string' after the number.
    Serial.print(buffer); Serial.print(" ");
    sscanf(&buffer[1], "%d", &val);
    Serial.print(val); Serial.print(" ");}}

Leave processing aside for the moment. Open Ard’s serial monitor, and enter C180Z (return). It should print "4 C180 180 ". 4 is the no. of chars, C180 is the chars received, 180 is the value converted to integer. It works with different length numbers.

(I don’t normally put the { on the same line, prefer the old way on next line. But the new way is shorter for copy+paste. Then I thought, why not put the trailing } on the line above? Now it looks like Python :slight_smile: )

Ok so I finally got them to communicate and decompose the string correctly! Instead of using the string class, I just made a “char” array of whatever I wanted, and utilized what jafal sent to me (its in another tab). I am now running into the problem of the motors not running now, but that could be a power issue at this point. Heres what I got.

Arduino:

#include <Wire.h>
#include <Servo.h>
#include <Adafruit_MotorShield.h>

//set up motorhsield
Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x60);

//assign motors
Adafruit_DCMotor *RailMotor = AFMS.getMotor(1);
Adafruit_DCMotor *Swivel = AFMS.getMotor(2);
Adafruit_DCMotor *Elbow = AFMS.getMotor(3);
Adafruit_DCMotor *Screw = AFMS.getMotor(4);

//call the servo library
Servo DrillArm;
Servo ClawArm;
Servo Claw;

const byte number_of_chars = 32;
char receivedChars[number_of_chars];
boolean new_data = false;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  // create with the default frequency 1.6KHz
  AFMS.begin();

  // Attach a servo to pin #10 and pin #9
  DrillArm.attach(11);
  ClawArm.attach(10);
  Claw.attach(9);

  // turn on motor M1
  RailMotor->setSpeed(300);
  RailMotor->run(FORWARD);
  RailMotor->run(BACKWARD);
  RailMotor->run(RELEASE);

  // turn on M2
  Swivel->setSpeed(200);
  Swivel->run(FORWARD);
  Swivel->run(BACKWARD);
  Swivel->run(RELEASE);

  // turn on motor M3
  Elbow->setSpeed(200);
  Elbow->run(FORWARD);
  Elbow->run(BACKWARD);
  Elbow->run(RELEASE);

  // turn on M4
  Screw->setSpeed(200);
  Screw->run(FORWARD);
  Screw->run(BACKWARD);
  Screw->run(RELEASE);
}

//setting variables

void loop() {
  // put your main code here, to run repeatedly:

  receivePacket();
  if (new_data == true) {
    parseData();
    executeParsedData();
    new_data = false;
    Serial.println(receivedChars);
    char buf[4] = {receivedChars[1], receivedChars[2], receivedChars[3], receivedChars[4]};
    int mapp = atoi(buf);
    Serial.println(mapp);

    if (receivedChars[0] == 'A'){ //claw arm control
      Serial.println(receivedChars);
      ClawArm.write(map(mapp, 0, 180, 0, 180));
    }

    if (receivedChars[0] == 'B'){ //elbow control
      Serial.println(receivedChars);
      Elbow->setSpeed(mapp);
      Elbow->run(FORWARD);
      delay(2000);
    }
    
    if (receivedChars[0] == 'C'){ //claw open/close
      Serial.println(receivedChars);
      Claw.write(map(mapp, 0, 180, 0, 180));
    }

    if (receivedChars[0] == 'D'){ //drill arm control
      Serial.println(receivedChars);
      DrillArm.write(map(mapp, 0, 180, 0, 180));
    }

    if (receivedChars[0] == 'E'){ //rail control
      Serial.println(receivedChars);
      RailMotor->setSpeed(mapp);
      RailMotor->run(FORWARD);
      delay(2000);
    }

    if (receivedChars[0] == 'F'){ //swivel control
      Serial.println(receivedChars);
      Swivel->setSpeed(mapp);
      Swivel->run(FORWARD);
      delay(2000);
    }
    
    if (receivedChars[0] == 'G'){ //screw control
      Serial.println(receivedChars);
      Screw->setSpeed(mapp);
      Screw->run(FORWARD);
      delay(2000);
    }
    
  }
  
}

Processing:

import processing.serial.*;
import net.java.games.input.*;
import org.gamecontrolplus.*;
import org.gamecontrolplus.gui.*;

Serial port;
ControlDevice cont;
ControlIO control;
Arduino arduino;
float swivel, screw, rail, selectcontrol;
boolean shoulderselect, elbowselect, clawarmselect, clawgrab, clawrelease;
String portmessage;

PImage splash;

void setup(){
  size(700, 400);
  control = ControlIO.getInstance(this);
  cont = control.getMatchedDevice("STAR_2021_Artificial_Astronauts_controls");
  
  if (cont == null) {
    println("No suitable device configured, exiting program"); 
    System.exit(-1);
  }
  
  splash = loadImage("Artificial Astronaut Control Scheme");
  println((Object[])Serial.list());
  port = new Serial(this, "COM8", 9600);
}

public void getUserInput() {
  screw = map(cont.getSlider("Screw").getValue(), -1, 1, 0, 180);
  swivel = map(cont.getSlider("SwivelJoint").getValue(), -1, 1, 0, 180);
  rail = map(cont.getSlider("Rail").getValue(), -1, 1, 0, 180);
  selectcontrol = map(cont.getSlider("SelectControl").getValue(), -1, 1, 0, 360);
  shoulderselect = cont.getButton("ShoulderSelect").pressed();
  elbowselect = cont.getButton("ElbowSelect").pressed();
  clawarmselect = cont.getButton("ClawArmSelect").pressed();
  clawgrab = cont.getButton("ClawGrab").pressed();
  clawrelease = cont.getButton("ClawRelease").pressed();
}


            
void draw() {
  getUserInput();
  background(selectcontrol,400,400);
  println("You are now in Control >:)");
  //send a list that consists of the joint's name and, position(and direction) to the serial for the arduino
  
  if(clawarmselect){ //control claw arm with right stick
    println("Selecting the claw arm to control, use the right stick to control");
    portmessage = "<A"+str((int)selectcontrol)+">";
    port.write(portmessage);
  }
  
  if(elbowselect){ //control elbow with button and control right stick
    println("Selecting the elbow to control, use the right stick to control");
    portmessage = "<B"+str((int)selectcontrol)+">";
    port.write(portmessage);
  }
  
  if(clawgrab){ //close claw
    println("Claw Closing");
    port.write("<"+"C90"+">");
  }
  
  if(clawrelease){ //open claw\
    println("Claw Opening");
    port.write("<"+"C180"+">");
  }
  
  if(shoulderselect){ //control elbow with button and control right stick
    println("Selecting the shoulder to control, use the right stick to control");
    portmessage = "<D"+str((int)selectcontrol)+">";
    port.write(portmessage);
  }
  
  if(rail > 0){ //control elbow with button and control right stick
    println("Selecting the rail to control, use the left stick to control");
    portmessage = "<E"+str((int)selectcontrol)+">";
    port.write(portmessage);
  }
  
  if(swivel > 0){ //control swivel with button and control right stick
    println("Selecting the swivel to control, use the left stick to control");
    portmessage = "<F"+str((int)selectcontrol)+">";
    port.write(portmessage);
  }
  
  if(screw > 0){ //control screw with trigger buttons
    println("Selecting the elbow to control, use the right stick to control");
    portmessage = "<G"+str((int)selectcontrol)+">";
    port.write(portmessage);
  }
}

This also would work, and probably less code. Check out my other post for the code I had, I implemented what jafal had sent.