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);
}