Controlp5 - got error that I can't understand

Hi there,

I got this error

Can anyone help me on this please?

Thank you

lug 19, 2020 5:34:52 PM controlP5.ControlBroadcaster printMethodError
GRAVE: An error occured while forwarding a Controller event, please check your code at automatico
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at controlP5.ControlBroadcaster.invokeMethod(Unknown Source)
at controlP5.ControlBroadcaster.callTarget(Unknown Source)
at controlP5.ControlBroadcaster.broadcast(Unknown Source)
at controlP5.Controller.broadcast(Unknown Source)
at controlP5.Button.setValue(Unknown Source)
at controlP5.Button.activate(Unknown Source)
at controlP5.Button.mouseReleased(Unknown Source)
at controlP5.Controller.setMousePressed(Unknown Source)
at controlP5.ControllerGroup.setMousePressed(Unknown Source)
at controlP5.ControlWindow.mouseReleasedEvent(Unknown Source)
at controlP5.ControlWindow.mouseEvent(Unknown Source)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1436)
at processing.core.PApplet.handleMethods(PApplet.java:1638)
at processing.core.PApplet.handleMouseEvent(PApplet.java:2749)
at processing.core.PApplet.dequeueEvents(PApplet.java:2652)
at processing.core.PApplet.handleDraw(PApplet.java:2493)
at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1547)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)
Caused by: java.lang.NullPointerException
at progetto5b.automatico(progetto5b.java:125)
… 25 more

the code i’m working on is

import controlP5.*;
import processing.serial.*;
import java.awt.event.KeyEvent; // imports library for reading the data from the serial port
import java.io.IOException;


ControlP5 cp5;
ControlP5 cp52;
Serial myPort;


boolean on;


int val, iAngle, iDistance, index1=0, index2=0; 
String dist, angle, distance, data;


void setup ()  {
myPort = new Serial(this,"COM5",9600);
//myPort.bufferUntil('.');    // reads the data from the serial port up to the character '.' before calling serialEvent
//println(myPort);


  size(700,700);
  //noStroke();
  
  
 
  
  
  cp5 = new ControlP5(this); 
  
    cp5.addIcon("icon",10)
     .setPosition(100,10)
     .setSize(70,50)
     .setRoundedCorners(20)
     .setFont(createFont("fontawesome-webfont.ttf", 40))
     .setFontIcons(#00f205,#00f204)
     //.setScale(0.9,1)
     .setSwitch(true)
     .setColorBackground(color(255,100))
     .hideBackground()
     ;  
   
    cp5.addButton("automatico")
     .setValue(0)
     .setPosition(100,100)
     .setSize(200,35);
     
    cp5.addButton("manuale")
     .setValue(0)
     .setPosition(100,150)
     .setSize(200,35);
   cp52 = new ControlP5(this);
   cp52.addSlider("slider")
     .setPosition(100,450)
     .setSize(200,20)
     .setRange(0,180)
     .setValue(0)
     ;
   Textlabel myTextlabelA;
   myTextlabelA = cp5.addTextlabel("label1")
                    //.setText("Angolo manuale:"+slider)
                    .setPosition(100,250)
                    .setColorValue(0xffffff00)
                    .setFont(createFont("Georgia",20))
                    ;
  Textlabel myTextlabelB;
  myTextlabelB = cp5.addTextlabel("label2")
                    .setText("Distanza manuale:"+dist)
                    .setPosition(100,300)
                    .setColorValue(0xffffff00)
                    .setFont(createFont("Georgia",20))                 
                    ;
   Textlabel myTextlabelC;
   myTextlabelC = cp5.addTextlabel("label3")
                    .setText("Angolo automatico:"+iAngle)
                    .setPosition(100,350)
                    .setColorValue(0xffffff00)
                    .setFont(createFont("Georgia",20))                 
                    ;
   Textlabel myTextlabelD;
   myTextlabelD = cp5.addTextlabel("label4")
                    .setText("Distanza automatico:"+iDistance)
                    .setPosition(100,400)
                    .setColorValue(0xffffff00)
                    .setFont(createFont("Georgia",20))                 
                    ;                   
                    
   cp52.hide();
   }
     
void draw () { 
 
 background(155);}


void icon(boolean theValue) {
  if(theValue==true){on=true;}
  else{on=false;}
} 


void automatico() {
  if(on==true){
      cp52.hide();
      myPort.write('A');
delay(500);
data = myPort.readStringUntil('.');
data = data.substring(0,data.length()-1);
  
index1 = data.indexOf(","); // find the character ',' and puts it into the variable "index1"
angle= data.substring(0, index1); // read the data from position "0" to position of the variable index1 or thats the value of the angle the Arduino Board sent into the Serial Port
distance= data.substring(index1+1, data.length()); // read the data from position "index1" to the end of the data pr thats the value of the distance
  
  // converts the String variables into Integer
iAngle = int(angle);
iDistance = int(distance);}} 


void manuale() {
if(on==true){
      cp52.show();
      //myPort.write(val);
      //myPort.readString();
}}


void slider (int slider) {
  val=slider;   
  byte sliderB=byte(val); 
  myPort.write('P');
  myPort.write(sliderB);    
  }  


I forgot to say that I got the error when I click on the button “automatico”

A few thoughts:
Check that your serial port was opened successfully before calling the write method.

Verify “COM5” matches your hardware and that the port is not already in use (by Arduino IDE, for example).

The function readStringUntil() will return null if it did not find your specified character. Make sure the device is terminating each message.

Your listing shows “Caused by: java.lang.NullPointerException” so the following may only cause a problem if a bad message comes in: indexOf() will return -1 if the input string is not found in the target causing substring() to throw an IndexOutOfBoundsException.

1 Like

Yes, as @noahbuddy said, this error only appears when port is not recognized.

I check my port and it’s not the problem because it works elsewhere in the code. Now I changed my code but I get the same error when I click on the button “automatico”.

My new code is:

import controlP5.*;
import processing.serial.*;

 

ControlP5 cp5;
ControlP5 cp52;
Serial myPort;

 

boolean on;

 

String  iAngle, iDistance, sl, slid, dist;

 

void setup ()  {
myPort = new Serial(this,"COM5",9600);

 

size(700,700);
  
  
cp5 = new ControlP5(this); 
  
    cp5.addIcon("icon",10)
     .setPosition(100,10)
     .setSize(70,50)
     .setRoundedCorners(20)
     .setFont(createFont("fontawesome-webfont.ttf", 40))
     .setFontIcons(#00f205,#00f204)
     //.setScale(0.9,1)
     .setSwitch(true)
     .setColorBackground(color(255,100))
     .hideBackground()
     ;  
   
    cp5.addButton("automatico")
     .setValue(0)
     .setPosition(100,100)
     .setSize(200,35);
     
    cp5.addButton("manuale")
     .setValue(0)
     .setPosition(100,150)
     .setSize(200,35);

 

cp52 = new ControlP5(this);
  
   cp52.addSlider("slider")
     .setPosition(100,400)
     .setSize(200,20)
     .setRange(0,180)
     .setValue(0)
     ;
   
   cp52.hide();
   }
     
void draw () { 
 
 background(155);
textSize(18); fill(0); text("Angolo automatico = " + iAngle + "°",100,225);
textSize(18); fill(0); text("Distanza automatico = " + iDistance + " cm",100,275);
textSize(18); fill(0); text("Angolo manuale = " + slid + "°",100,325);
textSize(18); fill(0); text("Disranza manuale = " + dist + " cm",100,375);
}

 

void icon(boolean theValue) {
  if(theValue==true){on=true;}
  else{on=false;}
} 

 

void automatico() {
  if(on==true){
      cp52.hide();
      myPort.write('A');

 

delay(500);

 

  byte[] angle = new byte[1];
  angle = myPort.readBytes();
  myPort.readBytes(angle);
  iAngle = new String(angle);

 

  byte[] distance = new byte[1];
  distance = myPort.readBytes();
  myPort.readBytes(distance);
  iDistance = new String(distance);}} 

 

void manuale() {
if(on==true){
      cp52.show();
}}

 

void slider (int slider) {
  slid=str(int(slider));
  sl=str(int(map(slider,0,180,0,255)));
  myPort.write('P');
  myPort.write(sl);
  delay(2000);
  dist = myPort.readString();
 } 

My Arduino paired code is:

#include <Servo.h> // servo motor library
Servo myServo; // create servo object to control a servo
int angle; char Param, d;
const int echoPin=11, trigPin=10, servoPin=9;   // pin che riceve l’eco, pin che invia il trigger al sensore, pin connesso al servomotore 
int dist, reflectime, dutyc;                    // variabili che memorizzano: la distanza misurata dal sensore, la durata dell'eco, il duty cycle del PWM

 

void setup()      {
  myServo.attach(servoPin);   // attach the servo on pin 9 to the servo object
  Serial.begin(9600);
  pinMode(echoPin, INPUT);    // imposta il pin echo come input
  pinMode(trigPin, OUTPUT);
                  } 
// Funzione per calcolare la distanza misurata dal sensore ad ultrasuoni
void CalculateDistance() { 
    digitalWrite(trigPin, HIGH);            // impulso di trigger che comanda l’invio di ultrasuoni
    delayMicroseconds(10);                  // durata dell’impulso (microsecondi) di innesco
    digitalWrite(trigPin, LOW);             // fine dell’impulso
    reflectime = pulseIn(echoPin, HIGH);    // misura la durata (miscrosecondi) dell’echo pari al tempo di andata/ritorno
    dist = reflectime/58;                   // formula per ottenere la distanza (cm) = velocitĂ  suono x tempo / 2        
                         }
                  
void loop()       {
  while (Serial.available()<1); // check for available data from the apps
  Param = Serial.read();        // when data is present, read 1 byte (1 character)
  switch (Param)  {             // check the value of the received character
    case 'P':                         // GUI wants to rotate the servo motor with PWM
    while (Serial.available()<1);     // check for available data from the apps
    dutyc = Serial.parseInt();        // Looks for the next valid integer (data type: long) in the incoming serial (data type: char)
    angle = map(dutyc,0,255,0,180);   // mapping dutyc to rotation angles (absolute not relative)
    myServo.write(angle);             // to operate smooth rotations, rotate 1 step in a for cycle with delay
    delay(500);
    CalculateDistance();              // formula per ottenere la distanza (cm)
    Serial.print(dist); break;
        case 'A':     // automatic rotation of the servo motor from 0 to 180 degrees
        for(int i=10;i<=170;i++) {  
        myServo.write(i);
        delay(70);
        CalculateDistance();
        if ((dist<15)&&(dist>0))      {           //se rileva ostacolo a meno di 15 cm si ferma 5 secondi e invia alla seriale l'angolo e la distanza
            Serial.write(i);
            delay(300);
            Serial.write(dist);
            delay (5000); }       
                                }
        for(int i=170;i>10;i--)  {  
        myServo.write(i);
        delay(70);        
        CalculateDistance();
        if ((dist<15)&&(dist>0))      {
            Serial.write(i);
            delay(300);
            Serial.write(dist);
            delay (5000); }
                                }
                }
                }

Remember to use port.available() before trying to read data.
I think your program may get stuck on parts like this:

  angle = myPort.readBytes();
  myPort.readBytes(angle);

Use one of those, not both, as readBytes() with no parameters will read all bytes in the buffer.

1 Like

Hi,

I also think you should test for byte array being == null, because your initial error was caused by a java.lang.NullPointerException.

Also, you are receiving a byte array, but not converting to an int, float or char array. So if you print a byte array, you will not convert to a string properly.

byte []Hi = {1,2,3,4,5,6};

String a = new String(Hi);
println(a);

Do some println() just for debugging so you understand the flow of your sketch.

Best regards