Using two different readStringUntil "characters"

https://processing.org/reference/splitTokens_.html

This helps I guess…

I apologize for many reply and edit.

Alright, so far I have been having issues with this

On processing I have:


import processing.serial.*;
float[] val = {};
Serial port;

int len = 1200; // set length
int wid = 700;  // set width
float x, y;
float px = 600;
float py = 350;

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

void serialEvent(final Serial port) {
  val = float(splitTokens(port.readString()));
  redraw = true;
}
void draw(){
  gyroline();
}

void gyroline() {
  //...
  x = val[0];
  y = val[1];
  line(px, py, x + px, y + py);
  px = x;
  py = y;
  
  print(x); println(y); // for debugging
}

However this gives me “ArrayIndexOutOfBoundsException 0

And for reference’s sake, here’s my Arduino (but only the loop() part):

//...
void loop() {
  mpu.getMotion6(&rawaccx, &rawaccy, &rawaccz, &rawgyrx, &rawgyry, &rawgyrz);
  getaccel(rawaccx, rawaccy, rawaccz);

  Serial.print(realaccx); Serial.write("\t"); // TSV
  Serial.print(realaccy); Serial.write("\t"); // TSV
  Serial.println('\n'); // NEWLINE
  delay(10);
}

Please reply soon :frowning_face: Thank you
EDIT: I’ve been trying to work on a solution while reading the links you sent and I have this. Now i am getting NullPointerException



import processing.serial.*;
String index;
float[] val;
Serial port;

int len = 1200; // set length
int wid = 700;  // set width
float x, y;
float px = 600;
float py = 350;

void setup() {
  noLoop();
  final String[] port = Serial.list();
  // port = new Serial (this, "COM12", 115200);
  new Serial(this, "COM12", 115200).bufferUntil('\n');
  // port.bufferUntil('\n');
}

void serialEvent(final Serial port) {
  val = float(splitTokens(port.readString()));
  redraw = true;
}
void draw() {
  while (port.available() > 0) {
    String input = port.readString();
    val = float(splitTokens(input));
    gyroline();
  }
}

void gyroline() {
  //...
  x = val[0];
  y = val[1];
  line(px, py, x + px, y + py);
  px = x;
  py = y;

  print(x); 
  println(y);
}

That means the val[] array variable is of length = 0.

That means the val[] array variable is still null. That is, it has not been initialized yet.

So, why are those errors happening? Pay attention to this line of code below inside serialEvent():

Variable val[] is properly assigned w/ a float[] array only when serialEvent() is called back.

As you know, draw() is called back (much probably many times) much earlier before serialEvent() is called back for the 1st time!

However, you’re assuming that val[] is already an array of length = 2 at the lines below:

Given you expect to receive exactly 2 values from Serial::readString() each time it’s called back, you should pre-initialize val[] w/ an array of length = 2 (or more if you wish), so it doesn’t crash the sketch when draw() is called back for the 1st time:

float[] val = {};float[] val = new float[2];

P.S.: You don’t need redraw = true; when not using noLoop():

1 Like

The last line of code gives me an error.

float[] val = {}; ->  float[] val = float[2];

"Error on ‘.class’ "

How do you propose I read the serial values and store each one separated by tsv onto my array?

Should I put the splitTokens withing draw? It doesn’t necessarily have to be in serialEvent right?

Edit: I tried to do something with this and it’s a null error:

import processing.serial.*;
String index;
float[] val;

Serial port;

float x, y;
float px = 600;
float py = 350;

void setup() {
  size(200, 200);
  noLoop();
  new Serial(this, "COM12", 115200).bufferUntil('\n');
}

//void serialEvent(final Serial port) {
//  val = float(splitTokens(port.readString()));
//}

void draw() {
  while (port.available() > 0) {
    String input = port.readString(); //takes serial input from Arduino
    val = float(splitTokens(input));  //assuming that all values until \n are caputured, split into array
    x = val[0];
    y = val[1];
    line(px, py, x + px, y + py);     //draw line
    px = x;
    py = y;
  }
}

Oops! I knew I was forgetting something, the operator new: float[] val = new float[2];. :confounded:

Alright so nothing is working yet. I’m currently trying it on a simpler scale – using potentiometer and drawing lines. It’s similar anyway, so I thought I’d figure this thing out using potentiometer

I just have a question: Does the value for the array index reset to 0? From as far as I know (which is probably wrong :thinking:), the splitTokens() parses a string and puts it into array as

 val [strIndex0] 

where this is the first value from the serial.

Now, as the serial is being read, given that it has 2 values, does the index reset after \n?

On another note…I’m working on this and this is what I have

import processing.serial.*;

Serial port;
float[] coords = new float [2];

float x, y;
float px, py;

void setup(){
  background(1);
  port = new Serial (this, "COM12", 115200);
}

void serialEvent(final Serial port){
  coords = float(splitTokens(port.readStringUntil('\n')));
}

void draw(){
  if(port.available() > 0){
    index = 0;
    serialEvent(port);
    x = coords[0];
    y = coords[1];
    line(px, py, x, y);
    px = x;
    py = y;
  }
}

The Arduino:




void setup() {
  Serial.begin(115200);
}

void loop() {
  int x = analogRead(A1);
  int y = analogRead(A0);

  int x1 = map(x, 1023, 0, -10, 10);
  int y1 = map(y, 0, 1023, -10, 10);

  Serial.print(x1); Serial.write('\t');
  Serial.print(y1); Serial.write('\t');
  Serial.println('\n');

}

Is the arduino side correct? I wont want to be referring to tsv and newline and then it turns out I’m wrong :disappointed:

Dunno much about Arduino, but it seems correct to me. :flushed:
Although you can simplify it a lil’ more like this: :nerd_face:

Serial.print(x1);
Serial.write('\t');
Serial.println(y1);

I’m also noticing you’re sending 2 int values, not float 1s: :see_no_evil:

int x1 = map(x, 1023, 0, -10, 10);
int y1 = map(y, 0, 1023, -10, 10);

So it’ll be more efficient to replace all float to int in the Processing side as well. :bulb:

Also in your Processing code side, I’ve spotted some bugs which wouldn’t be there if you had followed my own sketch model more closely! :roll_eyes:

Where’s Serial::bufferUntil() after this statement: :grimacing:
port = new Serial(this, "COM12", 115200);

And do not use Serial::available() when using serialEvent()! :no_good_man:

1 Like

Thanks!

Oops I, too, knew I was missing something :laughing:

I’ll take the time to slowly read because often times I skim (idk it’s a natural thing I do). Proves to be ineffective with programming hehe

Will do :+1: but maybe I’ll just replace the Arduino code parts to float. If we’re going for code efficiency, I guess I’ll change it to int

At the time I wrote this reply this is what I have so far (implementing your recent suggestions…)

import processing.serial.*;

Serial port;
float[] coords = new float [2];

float x, y;
float px = 250;
float py = 250;

void setup(){
  size(500,500);
  final String[] str = Serial.list(); //not sure why i need this but copied it anyway
  printArray(str);                    //this one too
  port = new Serial (this, "COM12", 115200);
  port.bufferUntil('\n');
}

void draw(){
  background(1);
    //serialEvent(port);
    //coords = float(splitTokens(port.readString()));
    stroke(255);
    x = coords[0];
    y = coords[1];
    line(px, py, x + px, y + py);
    print(x);
    print(y);
    println(" ");
    px = x;
    py = y;
}

void serialEvent(final Serial port){
  coords = float(splitTokens(port.readString()));
  //redraw = true; //added just because it's on your model code
}

With a weird output

[code]
[0] “COM12”
0.00.0

0.00.0
0.00.0
ArrayIndexOutOfBoundsException: 0

[/code]:

TL:DR the end of the output has an error on it

It’s also not drawing anything

@GoToLoop I have tried and tried and even copied the code on the links you gave as though it was a template, but I have gotten nothing

I did, however, watch a video about multiple serial values and acting on it. After watching it I got this:

import processing.serial.*;

Serial port;

int index = 0;
int[] input_arr = new int[2];
int px, py;
int x, y;

void setup() {
  background(0);
  size(500, 500);

  port = new Serial(this, "COM12", 115200);
  stroke(255);
}

void draw() {
}

void serialEvent() {
  while (port.available() > 0) {
    String raw = port.readStringUntil('\n');
    input_arr[index] = int(raw);
    index++;

    if (index > 1) {
      x = px + input_arr[0];
      y = py + input_arr[1];
      port.clear();
      println(input_arr[0]); //debug; this doesnt print anything
      px = x;
      py = y;
    }
  }
  line(x, y, px, py);
  port.bufferUntil('\n');
}

I might start a new thread about this specific one…

Well, I don’t have any Arduino hardware and neither even seen 1 in front of me yet! :woozy_face:

So I can only do blind coding in the dark for you. :dark_sunglasses:

Theoretically, an Arduino C code like this 1: :thinking:

void setup() {
  Serial.begin(115200);
}

void loop() {
  const int x = map(analogRead(A1), 0, 1023, -10, 10);
  const int y = map(analogRead(A0), 0, 1023, -10, 10);

  Serial.print(x);    // "-5"
  Serial.write('\t'); // '\t'
  Serial.println(y);  // "10" + "\r\n"

  delay(2);
}

Should expect to send an output similar to this 1 on each of its loop(), right: :grey_question:

String tsv = "-5" + '\t' + "10" + "\r\n";
println(tsv); // -5      10

int[] vals = int(splitTokens(tsv));
println(vals); // [0] -5  [1] 10

exit();

So AFAIK, a Processing Java code like this 1 should hopefully work for your case: :pleading_face:

import processing.serial.Serial;

static final int VALS = 2;
int[] vals = new int[VALS];

void setup() {
  size(800, 600);
  noLoop();

  stroke(-1);
  clear();

  final String[] ports = Serial.list();
  printArray(ports);

  new Serial(this, "COM12", 115200).bufferUntil(ENTER);
}

void draw() {
  println(vals);
}

void serialEvent(final Serial s) {
  vals = int(splitTokens(s.readString()));
  redraw = true;
}

BtW, here are some Arduino API references: :wink:

  1. https://www.Arduino.cc/reference/en/
  2. https://www.Arduino.cc/reference/en/language/functions/communication/serial/

Yes it definitely works (i feel like I’m cheating here…). Thanks so much

Now, I’m wondering…what in the WORLD did I miss? I’ve been at this for 12 hours and it took you less than an hour

Problem solved, but I just want to know why after missing meals and sitting in front of a screen I still couldn’t get it myself. Reading documentations just became a drag after stressing, so it was pointless to do so :angry:

Thanks though, but I hate getting the answer without learning my mistake.

Now I am trying to add the draw line and SO FAR this is what I have…

import processing.serial.Serial;

static final int VALS = 2;
int[] vals = new int[VALS];

//
int px = 400, py = 300;

void setup() {
  size(800, 600);
  noLoop();

  stroke(-1);
  clear();

  final String[] ports = Serial.list();
  printArray(ports);

  new Serial(this, "COM12", 115200).bufferUntil(ENTER);
}

void draw() {
  println(vals);
  line(px, py, vals[0], vals[1]);
  px = vals[0];
  py = vals[1];
}

void serialEvent(final Serial s) {
  vals = int(splitTokens(s.readString()));
  redraw = true;
}

EDIT: I noticed that println(vals) works just fine but why not println(vals[0])
I think this has been causing my confusion and I’m glad I found it

Well, println(vals); logs the whole content of the array val[].
While println(vals[0]); logs only the value stored at index 0.

The [] is called the array access operator btW:

You can learn more about Java arrays here:
Docs.Oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

The sketch I’ve posted in this thread is about 90% the same from my posted link:

Basically, I’ve simply replaced:

static final int PORT_INDEX = 0, BAUDS = 9600;
int[] vals = {};

new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);

w/

static final int VALS = 2;
int[] vals = new int[VALS];

new Serial(this, "COM12", 115200).bufferUntil(ENTER);

BtW, the constant PORT_INDEX has to match an index value from the array returned by Serial.list() which corresponds to the port that’s gonna receive bytes from the Arduino:

In your computer, that seems “COM12” matches the 1 connected to your Arduino.

However, if you simply copy & paste it on some other computer, chances are “COM12” might fail!

Also, even if in the same computer, but w/ a diff. OS, like some Linux distro, “COM12” won’t work at all; b/c Linux uses a completely diff. string for ports!

Also, if you happen to send a TSV row w/ more data than just 2, int[] vals = new int[2]; isn’t enough, obviously!

Therefore, when dealing w/ any Arduino code, we should consider such code a template.

B/c each computer and OS will have its own port number!

Thus we have to slightly customize such code to the values used by own particular computer configuration rather than directly use an unmodified copy & paste serial program!

I guess what you’re actually attempting there is to move the line()'s current coordinates w/ the values received from Serial, right? :thinking:

I see that at the Arduino’s side, you use map() in order to constrain the sent values within the range of [-10 to 10]. :world_map:

My bet is that those values mean how much farther to draw the next line()'s coordinates in relation to the previous 1.:horse_racing:

So I’ve made some changes to my previous Serial posted sketch. :man_mechanic:

Now, instead of vals[], we’re gonna have a PVector mov variable:

Variable mov is gonna store the values received from Serial::readString() using its method PVector::set():

void serialEvent(final Serial s) {
  mov.set(float(splitTokens(s.readString())));
  redraw = true;
}

We’re also gonna need a 2nd PVector named vec, which’s gonna store canvas’ current coordinates:
final PVector vec = new PVector(), mov = new PVector();

And we’re gonna initialize it w/ the canvas’ center coordinates:
vec.set(width>>1, height>>1);

Now, every time a new coordinate pair is received within serialEvent(), we’re gonna use PVector::add() method in order to move vec’s current coordinates to a new 1, passing mov as its argument:

line(vec.x, vec.y, vec.add(mov).x, vec.y);

Here’s the complete sketch “Serial TSV-Reading Line-Drawing”. Have fun: :smile_cat:

/**
 * Serial TSV-Reading Line-Drawing (v1.0)
 * GoToLoop (2019/May/02)
 *
 * https://Discourse.Processing.org/t/
 * using-two-different-readstringuntil-characters/10769/21
 */

import processing.serial.Serial;

static final String PORT = "COM12";
static final int BAUDS = 115200, INDEX = 1;

final PVector vec = new PVector(), mov = new PVector();

void setup() {
  size(1300, 700);
  noLoop();

  stroke(-1);
  clear();

  vec.set(width>>1, height>>1);

  final String[] ports = Serial.list();
  printArray(ports);

  new Serial(this, PORT, BAUDS).bufferUntil(ENTER);
  //new Serial(this, ports[INDEX], BAUDS).bufferUntil(ENTER);
}

void draw() {
  line(vec.x, vec.y, vec.add(mov).x, vec.y);

  if (outtaBounds(vec)) {
    vec.set(width>>1, height>>1);
    System.err.println("Coords reset back to center of canvas!");
  }

  println(vec, mov);
}

boolean outtaBounds(final PVector v) {
  return v.x < 0 | v.x >= width | v.y < 0 | v.y >= height;
}

void serialEvent(final Serial s) {
  mov.set(float(splitTokens(s.readString())));
  redraw = true;
}

Hmm I was actually prepping for a reply on the other thread I asked. It involved having potentiometer input from Arduino and feeding it to processing to draw lines

I have been a bit confused because it’s not behaving like ContinuousLines demo, rather it’s just really weird lines…

Yes!
Yes! It’s 10 and -10 to interact with the “coordinates” on screen
YES!!

So I’ll look into this and thank you very much for all the support and help! Thanks for being patient too

  • Now that it seems all’s been sorted out, how about some optimization?
  • The range [-10 to 10] is so small (5-bit) that it comfortably fits in a byte (8-bit).
  • So, rather than send those 2 small values as TSV, w/ lotsa extra separator characters, we can simply send 2 bytes only using Serial.write():
    https://www.Arduino.cc/reference/en/language/functions/communication/serial/write/
  • We just need to create a char array of length = 2: signed char xy[2];
#define BAUDS 115200
#define DELAY 10
#define BYTES 2

#define MIN 0
#define MAX 1023
#define MIN_RANGE -10
#define MAX_RANGE 10

signed char xy[BYTES];

void setup() {
  Serial.begin(BAUDS);
}

void loop() {
  xy[0] = map(analogRead(A1), MIN, MAX, MIN_RANGE, MAX_RANGE);
  xy[1] = map(analogRead(A0), MIN, MAX, MIN_RANGE, MAX_RANGE);

  Serial.write(xy);
  delay(DELAY);
}
/**
 * Serial readBytes() Line-Drawing (v1.0)
 * GoToLoop (2019/May/02)
 *
 * https://Discourse.Processing.org/t/
 * using-two-different-readstringuntil-characters/10769/23
 */

import processing.serial.Serial;

static final String PORT = "COM12";
static final float FPS = 100;
static final int BAUDS = 115200, INDEX = 1, BYTES = 2;
static final color STROKE = -1;

final byte[] xy = new byte[BYTES];
final PVector vec = new PVector(), mov = new PVector();

void setup() {
  size(1300, 700);
  noLoop();
  frameRate(FPS);

  stroke(STROKE);
  clear();

  vec.set(width>>1, height>>1);

  final String[] ports = Serial.list();
  printArray(ports);

  new Serial(this, PORT, BAUDS).buffer(BYTES);
  //new Serial(this, ports[INDEX], BAUDS).buffer(BYTES);
}

void draw() {
  line(vec.x, vec.y, vec.add(mov).x, vec.y);

  if (outtaBounds(vec)) {
    vec.set(width>>1, height>>1);
    System.err.println("Coords reset back to center of canvas!");
  }

  println(vec, mov);
}

boolean outtaBounds(final PVector v) {
  return v.x < 0 | v.x >= width | v.y < 0 | v.y >= height;
}

void serialEvent(final Serial s) {
  s.readBytes(xy);
  mov.set(xy[0], xy[1]);
  redraw = true;
}
1 Like

@GoToLoop ,

Your Arduino code from previous post above has errors.

Working (simplified) version:

//unsigned char xy[2];  //ok
//byte xy[2];  //ok
uint8_t xy[2]; //ok

//signed char xy[2];  // Error!

void setup() 
  {
  Serial.begin(9600);
  }

void loop() 
  {
  xy[0] = 255;
  xy[1] = 128;

  Serial.write(xy, 2);
  delay(1000);
  }

Reference:

:)

Well, I’m far of being knowledgeable in C/C++ so I dunno the details. :woozy_face:

However I guess in my original C code from 3 years ago the range [-10…+10] (MIN_RANGE & MAX_RANGE) used by map() is comfortably within a signed char datatype, isn’t it? :thinking:

Hello @GoToLoop,

Your Arduino code compiles with errors:

Errors

Arduino: 1.8.15 (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560

D:\Users\GLV\Documents\Arduino\Serial_send_floats_1_0_0\Serial_send_floats_1_0_0.ino: In function ‘void loop()’:

Serial_send_floats_1_0_0:20:18: error: no matching function for call to ‘write(signed char [2])’

Serial.write(xy);

              ^

In file included from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Arduino.h:233:0,

             from sketch\Serial_send_floats_1_0_0.ino.cpp:1:

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:129:20: note: candidate: virtual size_t HardwareSerial::write(uint8_t)

 virtual size_t write(uint8_t);

                ^~~~~

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:129:20: note: conversion of argument 1 would be ill-formed:

D:\Users\GLV\Documents\Arduino\Serial_send_floats_1_0_0\Serial_send_floats_1_0_0.ino:20:18: warning: invalid conversion from ‘signed char*’ to ‘uint8_t {aka unsigned char}’ [-fpermissive]

Serial.write(xy);

              ^

In file included from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Arduino.h:233:0,

             from sketch\Serial_send_floats_1_0_0.ino.cpp:1:

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:130:19: note: candidate: size_t HardwareSerial::write(long unsigned int)

 inline size_t write(unsigned long n) { return write((uint8_t)n); }

               ^~~~~

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:130:19: note: conversion of argument 1 would be ill-formed:

D:\Users\GLV\Documents\Arduino\Serial_send_floats_1_0_0\Serial_send_floats_1_0_0.ino:20:18: warning: invalid conversion from ‘signed char*’ to ‘long unsigned int’ [-fpermissive]

Serial.write(xy);

              ^

In file included from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Arduino.h:233:0,

             from sketch\Serial_send_floats_1_0_0.ino.cpp:1:

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:131:19: note: candidate: size_t HardwareSerial::write(long int)

 inline size_t write(long n) { return write((uint8_t)n); }

               ^~~~~

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:131:19: note: conversion of argument 1 would be ill-formed:

D:\Users\GLV\Documents\Arduino\Serial_send_floats_1_0_0\Serial_send_floats_1_0_0.ino:20:18: warning: invalid conversion from ‘signed char*’ to ‘long int’ [-fpermissive]

Serial.write(xy);

              ^

In file included from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Arduino.h:233:0,

             from sketch\Serial_send_floats_1_0_0.ino.cpp:1:

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:132:19: note: candidate: size_t HardwareSerial::write(unsigned int)

 inline size_t write(unsigned int n) { return write((uint8_t)n); }

               ^~~~~

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:132:19: note: conversion of argument 1 would be ill-formed:

D:\Users\GLV\Documents\Arduino\Serial_send_floats_1_0_0\Serial_send_floats_1_0_0.ino:20:18: warning: invalid conversion from ‘signed char*’ to ‘unsigned int’ [-fpermissive]

Serial.write(xy);

              ^

In file included from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Arduino.h:233:0,

             from sketch\Serial_send_floats_1_0_0.ino.cpp:1:

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:133:19: note: candidate: size_t HardwareSerial::write(int)

 inline size_t write(int n) { return write((uint8_t)n); }

               ^~~~~

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:133:19: note: conversion of argument 1 would be ill-formed:

D:\Users\GLV\Documents\Arduino\Serial_send_floats_1_0_0\Serial_send_floats_1_0_0.ino:20:18: warning: invalid conversion from ‘signed char*’ to ‘int’ [-fpermissive]

Serial.write(xy);

              ^

In file included from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

             from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

             from D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Arduino.h:233,

             from sketch\Serial_send_floats_1_0_0.ino.cpp:1:

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Print.h:52:12: note: candidate: size_t Print::write(const char*)

 size_t write(const char *str) {

        ^~~~~

D:\Program Portable\arduino-1.8.15\hardware\arduino\avr\cores\arduino/Print.h:52:12: note: conversion of argument 1 would be ill-formed:

D:\Users\GLV\Documents\Arduino\Serial_send_floats_1_0_0\Serial_send_floats_1_0_0.ino:20:18: warning: invalid conversion from ‘signed char*’ to ‘const char*’ [-fpermissive]

Serial.write(xy);

              ^

exit status 1

no matching function for call to ‘write(signed char [2])’

This report would have more information with
“Show verbose output during compilation”
option enabled in File → Preferences.

It will compile error free with these changes:

//signed char xy[BYTES];
unsigned char xy[BYTES];

//Serial.write(xy);
Serial.write(xy, 2);

Serial.write(buf, len) works with buf as a:

  • unsigned char xy[2];
  • byte xy[2];
  • uint8_t xy[2];

:)

I’ve never had an Arduino and any blind code I post for it is just wishful thinking. :dark_sunglasses:

So I depend on Arduino users’ feedback to know if it’s actually working! :construction_worker_man:

After all these years you’ve given me that feedback, thx! :bowing_man:

However, based on the big log you’ve posted above, I still think that’s rather a warning than an actual error. :warning:

AFAIK, the C language is able to automatically fit in an unsigned char into a signed char b/c both are 8-bit datatypes. :eight:

The log also mentions [-fpermissive], which I believe is a command line flag parameter which would allow the C compiler to ignore all those related warnings when compiling my code. :smile_cat: