Micro:bit multiple "serial on data recieved" don't work properly (only the last one works)

Unless I’m doing something wrong here - when I use multiple serial.onDataReceived only the last one actually works. The serial.readString() I was using clearly shows that both the # and $ sign get sent over serial and get properly received, but only the LAST serial.onDataReceived with a . actually works.

https://youtu.be/2iKxum5Tk4A (I press each key at least 3 times)

Here’s the code ifrom the video:

serial.onDataReceived(serial.delimiters(Delimiters.Dollar), function () {
    basic.showLeds(`
        . . . . .
        . # . . .
        # # # # #
        . # . . .
        . . . . .
        `)
    basic.pause(1000)
    basic.clearScreen()
})
input.onButtonPressed(Button.AB, function () {
    serial.writeLine("A")
})
serial.onDataReceived(serial.delimiters(Delimiters.Hash), function () {
    basic.showLeds(`
        . . # # #
        . . # # #
        . . # # #
        . . . . .
        . . . . .
        `)
    basic.pause(1000)
    basic.clearScreen()
})
serial.onDataReceived(serial.delimiters(Delimiters.Fullstop), function () {
    basic.showIcon(IconNames.Sword)
    basic.pause(1000)
    basic.clearScreen()
})
basic.forever(function () {
    basic.showString(serial.readString())
})

Yes, I think you’re right. Looking at the code, each handler block overwrites the same delimiter string, and the same pointer to the event’s handler.

It’s the same for Bluetooth UART: https://forum.makecode.com/t/bluetooth-uart-command-to-move-servo-only-work-in-one-direction/29202

https://github.com/microbit-foundation/codal-core/blob/master/source/driver-models/Serial.cpp#L932

So is this fixable in any way?

What do you want the project to do?

I think this behaves the same as the original intended.

If you don’t want inputs to queue up (as they would with data received events too), how to decide which inputs to use?

The last?

Or the first?

I wanted to control a computer by sending and receiving serial commands from the micro:bit to and from the computer. I ended up working around the issue by just ending everything with a dot, still pretty annoying since it’s a bit of a rigid system

I think one separator is probably a good idea. If it was possible to have 3 independent event handlers, it could get tricky to ensure they read their bit from the serial buffer - e.g. by calling them in the right order.

Similarly, when writing to serial from multiple loops/handlers, only one can write at a time. If a call has to wait for the serial to send, other loop/handlers will run, and serial writes from them will just return, and the output will be lost. I think micro:bit V1 always waits for the output to send, and V2 waits when the send buffer is full.