# Why can I not draw in the serialEvent() function?

**URL:** <https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032>\
**Category:** Electronics (Arduino, etc.)\
**Created:** [February 22, 2020, 11:59pm UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032 "2020-02-22T23:59:35Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tophee](https://avatars.discourse-cdn.com/v4/letter/t/2bfe46/32.png) [@tophee](https://discourse.processing.org/u/tophee)\
**Post date:** [February 22, 2020, 11:59pm UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032/1 "2020-02-22T23:59:36Z")

</div>

When I put the `text("Bla", 30,30)` in the loop, it works, i.e. it prints “Bla” on my Canvas.

```auto
void Draw() {
 text("Bla", 30,30); 
}

```

But when I but the same code into the `serialEvent()` function and trigger it by receiving serial data, it doesn’t work, i.e. it draws nothing on my canvas.

```auto
void serialEvent(Serial mySerial) { 
  value = mySerial.readStringUntil('\n');
         if ( value != null ) {
              textSize(20);
              fill(120);
              text("Bla", 30,30); 
              println("Bla");            
         }
} 

```

To make sure that the if clause is properly triggered, I added `println("Bla");` and, indeed, I get a “Bla” in the console for every data package I receive. But nothing on the canvas.

How is this possible? 😩

And, no, my background is not set to the same colour as the text.

---

<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:** [February 23, 2020, 6:45am UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032/2 "2020-02-23T06:45:01Z")

</div>

- **serialEvent()** is called back by the Serial’s internal Thread.
- However we can’t mutate anything on the canvas outside Processing’s own “Animation” Thread.
- Instead just have some global `boolean` “flag” variable to indicate it’s time to **draw()**.

---

<div class="post-metadata">

**Author:** ![tophee](https://avatars.discourse-cdn.com/v4/letter/t/2bfe46/32.png) [@tophee](https://discourse.processing.org/u/tophee)\
**Post date:** [February 23, 2020, 9:41am UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032/3 "2020-02-23T09:41:58Z")

</div>

> [@GoToLoop](#):
>
> However we can’t mutate anything on the canvas outside Processing’s own “Animation” Thread.

Why does it work in these examples shown in the video below? Note that the `Draw()` loop in both examples are completely empty.

[![](https://img.youtube.com/vi/C_gyGXWIgHY/maxresdefault.jpg "Processing 3 - graphing data from Arduino sensor") ](https://www.youtube.com/watch?v=C_gyGXWIgHY)

> [@GoToLoop](#):
>
> Instead just have some global `boolean` “flag” variable to indicate it’s time to **draw()**

Could you explain what you mean by that? Or how to implement it?

---

<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:** [February 23, 2020, 11:19am UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032/4 "2020-02-23T11:19:28Z")

</div>

> [@tophee](#):
>
> Why does it work in these examples shown in the video below?

B/c older versions were less restricted. At least when using the default JAVA2D renderer.

Even back then, drawing outside the “Animation” Thread could display some glitches.

> [@tophee](#):
>
> Or how to implement it?

```auto
// ...

boolean flag;

// ...

void draw() {
  // ...

  if (flag) {
    flag = false;

    // ...
  }

  // ...
}

// ...

void serialEvent(final Serial s) {
    // ...

    flag = true;
}

// ...

```

---

<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:** [February 23, 2020, 2:25pm UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032/5 "2020-02-23T14:25:32Z")

</div>

Alternatively, if you just need to refresh the canvas when new data arrives, you can use the **noLoop()** / **redraw()** technique: 💡

> [@Map function worked in Processing 2 and early 3.. But broke in 3.5.3. Need guidance](https://discourse.processing.org/t/map-function-worked-in-processing-2-and-early-3-but-broke-in-3-5-3-need-guidance/11371/2):
>
> Mutating the sketch’s main canvas outside the “Animation Thread” crashes the program! boomCallback serialEvent() is run by the Serial’s Thread btW. warningSo even calling something like background() can be fatal! fearfulActually, due to a bad design, any Processing function which depends on color() will get wrong results when they’re multithreading invoked! bugSo any canvas mutating operations should be moved to draw() or called by it. face_with_monocleHere’s a post link for…

---

<div class="post-metadata">

**Author:** ![tophee](https://avatars.discourse-cdn.com/v4/letter/t/2bfe46/32.png) [@tophee](https://discourse.processing.org/u/tophee)\
**Post date:** [February 23, 2020, 2:57pm UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032/6 "2020-02-23T14:57:37Z")

</div>

> [@GoToLoop](#):
>
> older versions were less restricted

A quick note to the people maintaining the processing reference pages (in particular [this one](https://processing.org/reference/libraries/serial/serialEvent_.html)): it would be really great if it could be mentioned that no drawing can be done in `serialEvent()`. (This would have saved me hours of dispair, struggling to get the impossible to work.)

Thanks for the cide example. Now I understand the idea. I’ll try it out as soon as I’m back at the computer.

But I’d like to understand this way of working a bit better and any help with that is greatly appreciated.

So what exactly happens when a serial event triggers the flag? For better understanding, let’s assume the loop (i.e. `void draw() { }`) is not empty but, in the contrary is quite full of other drawing business. So as long as there is no serial event, it relentlessly cycles through those drawing exercises.

Now, let’s say we receive data via the serial port which triggers the flag. This flag, just to be clear:

> [@GoToLoop](#):
>
> flag = true;

No, wait, before the flag (which is at the end of the function) is triggered, other code will be executed (probably processing the received data).

Here is my first question: while this processing occurs, is the loop interrupted or does the drawing continue? (On Arduino, my understanding is that only one thread can be processed at a time so the main loop would have to be interrupted, but I’m not sure whether this applies in processing running on a fully fledged operating system.)

So, let’s continue with what happens next: after the data is processed, the flag is triggered and the function exits and we’re either back in the main thread (if it was interrupted by the serial event) or we are left with the main thread (if it was happily drawing while we were processing serial data). In any case, what has changed now is that the flag is true so that once we reach the if clause, this one:

> [@GoToLoop](#):
>
> if (flag) {

we will draw something based on our serial data, right?

Second question: Assuming, as we have, that there is lots of stuff in the main thread, doesn’t this flag method mean that there can be a significant delay between the serial event happening and the drawing occurring? More specifically, the delay can be up to the duration of one cycle through the main loop, right? If so, is there any way to avoid such a delay?

**Edit:** We were replying at the same time, so I didn’t see your second reply about `redraw()`. At first I thought this might indeed be the cleaner solution, but the I saw the following on the [reference page](https://processing.org/reference/redraw_.html):

> **redraw()** does not run **draw()** immediately (it only sets a flag that indicates an update is needed).

I guess this means that it does exactly what you proposed above, with the flag, right. And, interestingly, the reference don’t mention either when exactly the redraw will occur, only that it will not be immediately, exactly as I suspected above…

---

<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:** [February 24, 2020, 10:09am UTC](https://discourse.processing.org/t/why-can-i-not-draw-in-the-serialevent-function/18032/7 "2020-02-24T10:09:55Z")

</div>

> [@tophee](#):
>
> Here is my first question: while this processing occurs, is the loop interrupted or does the drawing continue?

- Each Thread follows its own code path in a multitask, concurrent way.
- Processing’s “Animation” Thread is responsible to run the code within callback **draw()**.
- While Serial’s is the 1 responsible for callback **serialEvent()**.
- So code in **draw()** isn’t interrupted at all while the other code is at the same time being run in **serialEvent()**, and vice-versa.

> [@tophee](#):
>
> Second question: Assuming, as we have, that there is lots of stuff in the main thread, doesn’t this flag method mean that there can be a significant delay between the serial event happening and the drawing occurring?

- Notice that _flag_ in my example isn’t a method but just a field.
- When a Thread reassigns another value to a field, it takes some time before other Threads can notice that.
- That’s why concurrent programming is such a complex endeavor, which needs to ensure that data mutation happens in a synchronized, atomic way across Threads.
- However, in this particular case, where your Arduino code video has a **delay()** of 50 milliseconds, you shouldn’t worry about data loss.
- By default Processing’s “Animation” Thread calls back **draw()** at 60 FPS (about 16.7 milliseconds): [frameRate() / Reference / Processing.org](http://Processing.org/reference/frameRate_.html)
- Even an Arduino **delay()** as low as 20 milliseconds would be OK I believe.
