creating a biaxial testing apparatus

Hi everyone,

I’m working on a school project that involves making a biaxial testing machine controlled by an Arduino. This is my first actual Arduino project, previously I only played around with it.

I’m trying to use four nema17 stepper motors to perform tensile or compression testing on a sample (apply load in x and y axis), measure the load using a load cell, and output the load into a separate file for analysis. I also need the motors to stop running when the load reading changes more than a certain amount (indicating material failure). I have the motors running, and I have the code for reading the load cell.

The problem I’m running into:
I created a GUI using Processing with some buttons (start, stop, and move “arms”). The GUI opens up just fine but when I try to make the buttons send commands to the Arduino to “start”, “stop”, and “move arms” I get a NullPointerException error.

I’ve spent the last two weeks trying to fix this and applying solutions I read on other forums and youtube videos, but I can’t seem to get it working.

If anyone can take the time to look at my code and point me in the right direction, I’d appreciate very much.

Here’s my Arduino and Processing code for running the motors when the “start” button is pressed:

Arduino

// toggle switch pins
int toggleForward = 13;
int toggleBackward = 12;

// stepper motor pins
const int stepPin = 11; 
int dirPin = 10; 
const int enPin = 9;

void toggleSwitch() {
// toggle switch pin setup
  pinMode(toggleForward, INPUT);
  pinMode(toggleBackward, INPUT);

// motor pin setup
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,HIGH);

}

void loop() {

// mave arms towards center
if(digitalRead(toggleForward) == HIGH && digitalRead(toggleBackward) == LOW){
   digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for(int x = 0; x < 800; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(50); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(5); 
  }
  delay(1); // 1ms delay
  
}


// move arms outwards from center
if(digitalRead(toggleBackward) == HIGH){
  digitalWrite(dirPin, HIGH); //Changes the rotations direction
  // Makes 400 pulses for making two full cycle rotation
  for(int x = 0; x < 800; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(50);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(5);
  }
  delay(1);
}

else{
  digitalWrite(dirPin, LOW);
}

}

Processing

import controlP5.*;
ControlP5 cp5;

PFont font;

Chart myChart;
String loadSet;

import processing.serial.*;
Serial mySerial;

String myString = null;
int nl = 10;
float val;

public void settings() {
  size(600, 500);
}

void setup() {  
  //printArray(Serial.list());
  String myPort = Serial.list()[3]; //find correct serial port
  mySerial = new Serial(this, myPort, 9600);
  
  cp5 = new ControlP5(this);
  font = createFont("arial", 13);
  
  
  cp5.addTextfield("a").setPosition(50, 120).setSize(100, 30).setAutoClear(false).setFont(font);
  cp5.addBang("submit").setPosition(155, 120).setSize(30, 30);
  
  //create a button (text on button), position x & y coordinates of upper left corner of button
  cp5.addButton("start").setPosition(210, 120).setSize(50, 30).setFont(font);
  cp5.addButton("stop").setPosition(50, 215).setSize(50, 30).setFont(font);
  cp5.addButton("reset").setPosition(120, 215).setSize(50, 30).setFont(font); 
  cp5.addButton("A & B  backward").setPosition(50, 315).setSize(150, 50).setFont(font);
  cp5.addButton("A & B  foreward").setPosition(205, 315).setSize(150, 50).setFont(font);
  cp5.addButton("C & D  backward").setPosition(50, 370).setSize(150, 50).setFont(font);
  cp5.addButton("C & D  foreward").setPosition(205, 370).setSize(150, 50).setFont(font);
}


void draw() {
  background(250, 250, 250);
  fill(0, 0, 0);
  textFont(font);
  while (mySerial.available() > 0){
    myString = mySerial.readStringUntil(nl);
    
    
    if (myString != null){
      val = float(myString); //takes data from serial and turns into number
      println(val);
    }
  }
  text("Welcome to the Biaxial Testing Apparatus Control Center", 50, 50);
  text("Enter load (kg), click submit, and click start to begin test:", 50, 100);
  text("Stop testing, reset to initial position:", 50, 200);
  text("Use these buttons to move the device's arms (A & B for X-axis, C & D for Y-axis):", 50, 300);
}

void submit(){
  println();
  print("load set to: ");
  loadSet = cp5.get(Textfield.class, "a").getText();
  print(loadSet);
  print(" kg");
}

void start(){
  mySerial.write('s');
}

Your Processing code does not have a controlEvent function to process the button-clicking events.

Doesn't Processing give you more information than "Null pointer exception"? Doesn't it tell you the line number at which the error occurred? That would go far toward determining which pointer is null and why.

MorganS:
Your Processing code does not have a controlEvent function to process the button-clicking events.

Ok I'll try that. Thanks.