Issue with using array after splitTokens()

#1

Hello.

This can be considered an extension of my previous thread here Using two different readStringUntil "characters"

Now, I am working on a basic Arduino project, but for understand Processing, I am now using a potentiometer to extend a line across the screen. I wish to extend it to 2D because it has been 1D

Through Serial, I receive the values of the pot via Arduino. I know that separating a string using splitTokens() will give a pre-initialized array at some index that string.

However here is my code, and for some reason, it gives me an error about the array being null

For the sake of trying to figure this thing out I didn’t add the line movement yet. For now I want to know what in the world is happening

import processing.serial.*;

Serial port;
String[] input = {};
float val;

void setup(){
  stroke(250);
  size(1000, 700);
  port = new Serial (this, "COM12", 115200);
  port.bufferUntil('\n');

}

void serialEvent(Serial port){
 // input = float((port.readStringUntil('\n'));
 input = splitTokens(port.readString());

}

void draw(){

  background(1);

  println(input[0]);
  
  
}

The line println(input[0]); will give me the error, however removing the [] part gives me the raw values, just as I am reading them from Arduino serial. println(input); works

But I want to interact with the individual values.

Please help. I have a deadline to meet on the 10th and I’m still on the processing basics.

Thanks

#2

you should not try to make a command short / snappy
like nesting commands if you not know what is happening inside.

so stick to the example and get a string first.

  • that string might be null
  • if not null should trim it first

after that a split ( like for “,” ) gives a error if there is no “,”
so try a match first
if ok do the split to array.
when using the array you must check on the length of the array,
if you get 2 values, one “,” you get array length 2
but if you have com problems might get short lines,
so you check
if length >= 2 else println(“bad line”);
finally you can inside use a input[0] and input[1]

#3

Might you show me in processing code?
I tried and this is what I got

import processing.serial.*;

Serial port;
//String[] input = {};
float val;

String[] arr_input = new String[2];

int index = 0;

void setup(){
  stroke(250);
  size(1000, 700);
  port = new Serial (this, "COM12", 115200);
  port.bufferUntil('\n');

}

void serialEvent(Serial port){
 // input = float((port.readStringUntil('\n'));
 /*input = splitTokens(*/port.readStringUntil('\n');

}

void draw(){
  String[] input = splitTokens(port.readString());
  background(1);
  arr_input= split(input[index], ',');
  index++;
  println(input[0]);
  println(input[1]);
  
  index = 0;
  port.clear();
  
}

NullPointerException

#4

example for above wording:

import processing.serial.*;
Serial port;
String ports, inString;
String[] elements;
boolean diagp = true;
int baud = 115200; // 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 230400, 250000, 500000, 1000000, 2000000
boolean getrecord= false;
int many = 0, expect = 7, recs=0;
int[] values = new int[expect];
float zoom;

public void setup() {
  size(300, 300);
  if ( diagp ) printArray(Serial.list());
  ports = Serial.list()[1];
  port = new Serial(this, ports, baud);
  port.bufferUntil('\n');
  stroke(0);
  zoom = height/1023.0;
  background(200, 200, 0);
}

void draw() {
  if ( getrecord ) {
    getdata();
    stroke(200,200,0);
    line(recs, 0, recs, height);
    for (int i=0; i<expect; i++ ) { 
      float ypos = height - values[i]*zoom;
      if ( i > 4 ) ypos = height-40*(i-4) - 10*values[i]; // for the digital vals
      if ( diagp ) println(" values ["+i+"] "+values[i]+" xpos "+recs+" ypos "+ypos);
      stroke(0, i*40, 200-i*40);
      point( recs, ypos );
    }
    recs++;
    if ( recs > width ) recs = 0;
    stroke(255);
    line(recs, 0, recs, height);
    getrecord = false;
  }
}


void getdata() {
  if ( diagp ) println(inString);
  elements = splitTokens(inString, ",");  // split and set some globals...
  int many = elements.length;
  if ( many >= expect ) {
    for (int i=0; i<expect; i++ ) { 
      if ( diagp ) print(elements[i]+" , ");
      values[i] = int(elements[i]);
    }
    if ( diagp ) println();
  } else {
    println("com error, found short line:"+inString);
  }
}

void serialEvent(Serial thisport) {                     // read the serial buffer:
  inString = thisport.readString();
  if ( inString  != null ) {
    inString = trim(inString);                          // clean
    getrecord = true;
  }
}


/*
// arduino code tested Arduino Leonardo Arduino IDE 1.8.9 hourly 
 
 String aline; // readable char line
 
 void make_aline() {
 aline = "";
 aline += analogRead(0);
 aline += ',';
 aline += analogRead(1);
 aline += ',';
 aline += analogRead(2);
 aline += ',';
 aline += analogRead(3);
 aline += ',';
 aline += analogRead(4);
 aline += ',';
 aline += digitalRead(2);
 aline += ',';
 aline += digitalRead(3);
 // ++ CR LF
 }
 
 int wait = 500;
 long baud = 115200; // 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 230400, 250000, 500000, 1000000, 2000000
 
 void setup() {
 Serial.begin(baud);
 while (!Serial) {
 ;  // wait for serial port to connect. Needed for native USB port only ( arduino leonardo )
 }
 }
 
 void loop() {
 make_aline();
 Serial.println(aline);
 delay(wait);
 }
 
 */

Is possible use different layer for the axes on chart?
Simple arduino to processing serial not outputting anything
Trouble with the Serial port read
#5

At the moment I am working on basically copying the code line by line but implementing it for a different purpose. This is how I’ve learned code and I guess it’s working

But question…there are some variable names/objects (not like Java objects) that I want to know…

What does the following mean:

  • recs
  • diagp
  • ["+i+"] especially this, I think it adds the index?

Why specifically these variable names? Just wanted to know.

Also in the draw() function, I am a bit lost in terms of the language. You execute the function anyway whether getrecord is true or false?!?!

if(getrecord). // statements`
//somewhere later, with statements
getrecord = true;`
//later again...
getrecord = false;

Thanks

#6

-a- getrecord
yes i moved the data string processing from the serial event to draw,
that only works when the serial event sets
getrecord = true;

the draw executes that part and set it to false.

if for that structure is a time limit i not know,
more arduino lines per second as you have FPS could skip lines or even fail,
the advantage is the errors from that processing ( and the messages )
are more easy as when it happens inside serial event.
( but you can move it back )

-b- diagp
is a boolean switch “diagnostic printing”
what you can disable when all works fine.

-c- recs
each time a new line comes from arduino i make a new
vertical line on the canvas ( oscilloscope style )
first yellow ( background ) then
the colored points for each measurement
at the current cursor x position
add i make a white line at x+1 to show that cursor