# Map function worked in Processing 2 and early 3.. But broke in 3.5.3. Need guidance

**URL:** <https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371>\
**Category:** Electronics (Arduino, etc.)\
**Created:** [May 18, 2019, 10:16pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371 "2019-05-18T22:16:38Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ItchyBrain](https://avatars.discourse-cdn.com/v4/letter/i/bbe5ce/32.png) [@ItchyBrain](https://discourse.processing.org/u/ItchyBrain)\
**Post date:** [May 18, 2019, 10:16pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/1 "2019-05-18T22:16:38Z")

</div>

Hi. This exact code worked in Processing versions 2 and and earlier version of 3. I upgraded to 3.5.3 . Since upgrading my HP laptop to Processing 3.5.3 I now get the error:  
(note: I have another laptop still running Processing 2.0 and this exact code works fine on it. Just tried 3.4 with same problem)

“map(NaN, 0, 1023, 100, 1080) called, which returns NaN (not a number)  
Error, disabling serialEvent() for COM16  
null”

Code reads serial data. Aurdino is sending a value between 1 and 999, typically 200 - 400…

It looks like the variable inByte is not recognized as an intiger in ver 3.5.3. See code:

```auto
/ ******************************************************************************
/ ******************************************************************************
Heart_Rate_Display.ino
Demo Program for AD8232 Heart Rate sensor.
Casey Kuhns @ SparkFun Electronics
6/27/2014
https://github.com/sparkfun/AD8232_Heart_Rate_Monitor

The AD8232 Heart Rate sensor is a low cost EKG/ECG sensor. This example shows
how to create an ECG with real time display. The display is using Processing.
This sketch is based heavily on the Graphing Tutorial provided in the Arduino
IDE. http://www.arduino.cc/en/Tutorial/Graph

Resources:
This program requires a Processing sketch to view the data in real time.

Development environment specifics:
  IDE: Arduino 1.0.5
  Hardware Platform: Arduino Pro 3.3V/8MHz
  AD8232 Heart Monitor Version: 1.0

This code is beerware. If you see me (or any other SparkFun employee) at the
local pub, and you've found our code helpful, please buy us a round!

Distributed as-is; no warranty is given.
****************************************************************************** /

import processing.serial.*;

Serial myPort; // The serial port
int xPos = 1; // horizontal position of the graph
float height_old = 0;
float height_new = 0;
float inByte = 0;

void setup () {
  // set the window size:
  size(1900, 400);        

  // List all the available serial ports
  println(Serial.list());
  // Open whatever port is the one you're using.
  myPort = new Serial(this,Serial.list()[0], 9600);
  // don't generate a serialEvent() unless you get a newline character:
  myPort.bufferUntil('\n');
  // set inital background:
  background(0xff);
}

void draw () {
  // everything happens in the serialEvent()
}

void serialEvent (Serial myPort) {
  // get the ASCII string:
  String inString = myPort.readStringUntil('\n');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);

    // If leads off detection is true notify with blue line
    if (inString.equals("!")) { 
      stroke(0, 0, 0xff); //Set stroke to blue ( R, G, B)
      inByte = 512; // middle of the ADC range (Flat Line)
    }
    // If the data is good let it through
    else {
      stroke(0xff, 0, 0); //Set stroke to red ( R, G, B)
      inByte = float(inString); 
     }
     
     //Map and draw the line for new data point
     inByte = map(inByte, 0, 1023, 100, height);
     height_new = height - inByte; 
     line(xPos - 1, height_old, xPos, height_new);
     height_old = height_new;
    
      // at the edge of the screen, go back to the beginning:
      if (xPos >= width) {
        xPos = 0;
        background(0xff);
      } 
      else {
        // increment the horizontal position:
        xPos++;
      }
    
  }
}

//import processing.serial.*;

```

---

<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 18, 2019, 10:54pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/2 "2019-05-18T22:54:51Z")

</div>

- Mutating the sketch’s main canvas outside the “Animation Thread” crashes the program! 💥
- Callback **serialEvent()** is run by the Serial’s Thread btW. ⚠
- So even calling something like **background()** can be fatal! 😨
- Actually, due to a bad design, any Processing function which depends on **color()** will get wrong results when they’re multithreading invoked! 🐛
- So any canvas mutating operations should be moved to **draw()** or called by it. 🧐
- Here’s a post link for a bare minimum Serial data receiver demo: 👼

- [Forum.Processing.org/two/discussion/14534/myport-available-always-0#Item\_1](http://Forum.Processing.org/two/discussion/14534/myport-available-always-0#Item_1)

```auto
/**
 * Efficient Serial Reading (v1.02)
 * GoToLoop (2016-Jan-19)
 *
 * Forum.Processing.org/two/discussion/14534/
 * myport-available-always-0#Item_1
 *
 * Forum.Processing.org/two/discussion/16618/
 * processing-with-arduino-void-serialevent#Item_5
 *
 * Discourse.Processing.org/t/
 * map-function-worked-in-processing-2-and-early-3-
 * but-broke-in-3-5-3-need-guidance/11371/2
 */
 
import processing.serial.Serial;
 
static final int PORT_INDEX = 0, BAUDS = 9600;
String myString = "";
 
void setup() {
  noLoop();
  final String[] ports = Serial.list();
  printArray(ports);
  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
}
 
void draw() {
  println(myString);
}
 
void serialEvent(final Serial s) {
  myString = s.readString().trim();
  redraw = true;
}

```

---

<div class="post-metadata">

**Author:** ![ItchyBrain](https://avatars.discourse-cdn.com/v4/letter/i/bbe5ce/32.png) [@ItchyBrain](https://discourse.processing.org/u/ItchyBrain)\
**Post date:** [May 18, 2019, 11:29pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/3 "2019-05-18T23:29:04Z")

</div>

Hi GoToLoop - That certainly is more efficient! Thanks. But it doesn’t solve the invalid map issue. I’m at a loss to get my ECG monitor working again. It’s kind of important to me :). I can goback to very 2.0, but that isn’t “really” a longterm solution because I need recent versions to learn. I hope to port this to android so I can run it via bluetooth on my phone.  
Thanks!

EDIT! I just saw the other important notes you added in the bullet points. I will attempt to put code in the correct places… I didn’t write it, and am a novice… But will give it the old college try.

---

<div class="post-metadata">

**Author:** ![ItchyBrain](https://avatars.discourse-cdn.com/v4/letter/i/bbe5ce/32.png) [@ItchyBrain](https://discourse.processing.org/u/ItchyBrain)\
**Post date:** [May 19, 2019, 3:06pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/4 "2019-05-19T15:06:48Z")

</div>

Ho GoToLoop:  
2019-05-19T04:00:00Z  
Thank you for your guidance. I’ve rearranged the code so that (I think?) everything is where it is supposed to be. It WORKS! Also managed to up the speed from 9600bps to 38400 bps which improved the resolution. I appreciate that you gave direction, but not the actual revised/working code. This was a great learning experience for me.  
Be well and good things to you!

BEGIN new revision that works:

```auto
import processing.serial.*;

Serial s; // The serial port
int xPos = 1; // horizontal position of the graph
float height_old = 0;
float height_new = 0;
float inByte = 0;
static final int PORT_INDEX = 0, BAUDS = 38400;
String hrNumber = "";

void setup () {

  noLoop();
  final String[] ports = Serial.list();
  printArray(ports);
  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
  size(1900, 400);
}

  void serialEvent(final Serial s) {
    hrNumber = s.readString().trim();
    redraw = true;

    if (hrNumber != null) {
      // trim off any whitespace:
      hrNumber = trim(hrNumber);
      println(hrNumber);
    }
  }

void draw () 
{
// background(0xff);
  if (hrNumber.equals("!")) { 
    stroke(0, 0, 0xff); //Set stroke to blue ( R, G, B)
    inByte = 200; // middle of the ADC range (Flat Line)
  }
  // If the data is good let it through
  else {
    stroke(0xff, 0, 0); //Set stroke to red ( R, G, B)
    inByte = float(hrNumber);
  }

  //Map and draw the line for new data point
  inByte = map(inByte, 0, 1023, 0, height);
  height_new = height - inByte; 
  line(xPos - 1, height_old, xPos, height_new);
  height_old = height_new;

  // at the edge of the screen, go back to the beginning:
  if (xPos >= width) {
    xPos = 0;
    background(0xdd);
  } else {
    // increment the horizontal position:
    xPos = xPos += 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 19, 2019, 3:28pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/5 "2019-05-19T15:28:59Z")

</div>

> [@ItchyBrain](#):
>
> ```auto
> void serialEvent(final Serial s) {
> hrNumber = s.readString().trim();
> redraw = true;
> 
> if (hrNumber != null) {
> // trim off any whitespace:
> hrNumber = trim(hrNumber);
> println(hrNumber);
> }
> 
> ```

You’re using **trim()** 2x: 😳

1. `hrNumber = s.readString().trim();`
2. `hrNumber = trim(hrNumber);`

You can delete the 2nd **trim()** statement safely. 😉

And I’ve also spotted you’re checking for `null` at `if (hrNumber != null) {`. 🙈

If it were even possible for Serial::**readString()** to return `null` inside callback **serialEvent()**, calling **trim()** after `s.readString()` would had already crashed the program, before reaching your `if (hrNumber != null) {`. 😬

The reason why Serial::**readString()** can’t return `null` is b/c, by default, **serialEvent()** is only called back after a `byte` had arrived. 🛬

Specifically in your case, when an ENTER (`\n`) character is received: `.bufferUntil(ENTER);`. 🤓

Therefore, Serial::**readString()** would always return a String w/ 1 character at the very least. 🤑

---

<div class="post-metadata">

**Author:** ![ItchyBrain](https://avatars.discourse-cdn.com/v4/letter/i/bbe5ce/32.png) [@ItchyBrain](https://discourse.processing.org/u/ItchyBrain)\
**Post date:** [May 19, 2019, 3:46pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/6 "2019-05-19T15:46:46Z")

</div>

GoToLoop,  
You’re exactly correct! I removed the entire IF statement and placed the println in the body of void serialEvent right under redraw = true.

Thank you so much for helping me learn this.  
Here is what I believe to be the final code:

```auto
import processing.serial.*;

Serial s; // The serial port
int xPos = 1; // horizontal position of the graph
float height_old = 0;
float height_new = 0;
float inByte = 0;
static final int PORT_INDEX = 0, BAUDS = 38400;
String hrNumber = "";

void setup () {

  noLoop();
  final String[] ports = Serial.list();
  printArray(ports);
  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
  size(1900, 400);
}

  void serialEvent(final Serial s) {
    hrNumber = s.readString().trim();
    redraw = true;
    println(hrNumber);

  }

void draw () 
{
// background(0xff);
  if (hrNumber.equals("!")) { 
    stroke(0, 0, 0xff); //Set stroke to blue ( R, G, B)
    inByte = 200; // middle of the ADC range (Flat Line)
  }
  // If the data is good let it through
  else {
    stroke(0xff, 0, 0); //Set stroke to red ( R, G, B)
    inByte = float(hrNumber);
  }

  //Map and draw the line for new data point
  inByte = map(inByte, 0, 1023, 0, height);
  height_new = height - inByte; 
  line(xPos - 1, height_old, xPos, height_new);
  height_old = height_new;

  // at the edge of the screen, go back to the beginning:
  if (xPos >= width) {
    xPos = 0;
    background(0xdd);
  } else {
    // increment the horizontal position:
    xPos = xPos += 2;
  }
}

```

I can’t see how to mark a topic as resolved…

---

<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 19, 2019, 3:56pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/7 "2019-05-19T15:56:27Z")

</div>

> [@ItchyBrain](#):
>
> I can’t see how to mark a topic as resolved…

I don’t think this forum got such feature. 🥴

BtW, you should edit your posts and fix your code format, so others can study it. ⚠

Select your posted code and hit SHIFT + CTRL + C. Or even easier, click at the `</>` icon. 🤠

---

<div class="post-metadata">

**Author:** ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)\
**Post date:** [May 20, 2019, 5:05am UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/8 "2019-05-20T05:05:50Z")

</div>

@ItchyBrain you can click in the pen symbol on the post you want to edit. Then you can follow the instructions provided by Goto above to format your code. If something is not clear about formatting your code, let me know as I can help.

Kf

---

<div class="post-metadata">

**Author:** ![ItchyBrain](https://avatars.discourse-cdn.com/v4/letter/i/bbe5ce/32.png) [@ItchyBrain](https://discourse.processing.org/u/ItchyBrain)\
**Post date:** [May 20, 2019, 4:22pm UTC](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/9 "2019-05-20T16:22:27Z")

</div>

GoTo and Frajer:

I edited all my posts to place code in the code boxes and added the final code to the last post.  
Thank you for your patience and not booting me for bad forum behavior…

Best Regards,
