# Using two different readStringUntil "characters"

**URL:** <https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769>\
**Category:** Electronics (Arduino, etc.)\
**Tags:** homework\
**Created:** [April 29, 2019, 11:10pm UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769 "2019-04-29T23:10:54Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 3, 2019, 12:44pm UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/21 "2019-05-03T12:44:08Z")

</div>

> [@eezJerome](#):
>
> Now I am trying to add the draw line and SO FAR this is what I have…

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

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]. 🗺

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

So I’ve made some changes to my previous Serial posted sketch. 👨‍🔧

Now, instead of _vals[]_, we’re gonna have a PVector _mov_ variable:

> **[PVector / Reference](https://processing.org/reference/PVector.html)**
>
> A class to describe a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction. The datatype, however, st…

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

> **[set() / Reference](https://processing.org/reference/PVector_set_.html)**
>
> Sets the x, y, and z component of the vector using two or three separate variables, the data from a PVector, or the values from a float array.

```java
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:

> **[add() / Reference](https://processing.org/reference/PVector_add_.html)**
>
> Adds x, y, and z components to a vector, adds one vector to another, or adds two independent vectors together. The version of the method that adds two vectors together is a static method and returns a…

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

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

```auto
/**
 * 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;
}

```

---

<div class="post-metadata">

**Author:** ![eezJerome](https://avatars.discourse-cdn.com/v4/letter/e/e0b2c6/32.png) [@eezJerome](https://discourse.processing.org/u/eezJerome)\
**Post date:** [May 3, 2019, 12:50pm UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/22 "2019-05-03T12:50:32Z")

</div>

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…

> [@GoToLoop](#):
>
> I guess what you’re actually attempting there is to move the **line()**'s current coordinates w/ the values received from Serial, right? 🤔
> 
> 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]. 🗺
> 
> My bet is that those values mean how much farther to draw the next **line()**'s coordinates in relation to the previous 1.🏇

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

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 3, 2019, 5:29pm UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/23 "2019-05-03T17:29:56Z")

</div>

- 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/](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];`

```auto
#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);
}

```

- For the Processing Java side, we also create a `byte[]` array of _length_ = 2:  
`final byte[] xy = new byte[2];`
- And replace Serial::**bufferUntil()** w/ Serial::**buffer()**:  
[Processing.org/reference/libraries/serial/Serial\_buffer\_.html](http://Processing.org/reference/libraries/serial/Serial_buffer_.html)  
`new Serial(this, "COM12", 115200).buffer(2);`
- and inside **serialEvent()**, we replace Serial::**readString()** w/ Serial::**readBytes()**:  
[Processing.org/reference/libraries/serial/Serial\_readBytes\_.html](http://Processing.org/reference/libraries/serial/Serial_readBytes_.html)  
`s.readBytes(xy); mov.set(xy[0], xy[1]);`

```auto
/**
 * 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;
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [December 11, 2021, 11:33pm UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/24 "2021-12-11T23:33:51Z")

</div>

@GoToLoop ,

Your Arduino code from previous [post](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/23) above has errors.

Working (simplified) version:

```auto
//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:

- [Serial.write() - Arduino Reference](https://www.arduino.cc/reference/en/language/functions/communication/serial/write/)
- [Arduino: Difference in "Byte" VS "uint8\_t" VS "unsigned char" - Oscar Liang](https://oscarliang.com/arduino-difference-byte-uint8-t-unsigned-cha/)

`:)`

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 12, 2021, 12:09am UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/25 "2021-12-12T00:09:41Z")

</div>

> [@glv](#):
>
> Your Arduino code from post above has errors:

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

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? 🤔

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [December 12, 2021, 11:19am UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/26 "2021-12-12T11:19:50Z")

</div>

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:

```auto
//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];

`:)`

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [December 12, 2021, 11:46am UTC](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769/27 "2021-12-12T11:46:56Z")

</div>

> [@glv](#):
>
> It will compile error free with these changes:

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

So I depend on Arduino users’ feedback to know if it’s actually working! 👷‍♂️

After all these years you’ve given me that feedback, thx! 🙇‍♂️

> [@glv](#):
>
> note: conversion of argument 1 would be ill-formed:

> [@glv](#):
>
> warning: invalid conversion from ‘signed char\*’ to ‘uint8\_t {aka unsigned char}’ [-fpermissive]

> [@glv](#):
>
> no matching function for call to ‘write(signed char [2])’

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

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

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. 😸

[Previous page](https://discourse.processing.org/t/using-two-different-readstringuntil-characters/10769.md?page=1)
