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
if (n == 0) return mkString("", 0);
return PSTR(uBit.serial.read(n, MicroBitSerialMode::ASYNC));
}
/**
* Register an event to be fired when one of the delimiter is matched.
* @param delimiters the characters to match received characters against.
*/
//% help=serial/on-data-received
//% weight=18 blockId=serial_on_data_received block="serial|on data received %delimiters=serial_delimiter_conv"
void onDataReceived(String delimiters, Action body) {
uBit.serial.eventOn(MSTR(delimiters));
registerWithDal(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_DELIM_MATCH, body);
// lazy initialization of serial buffers
uBit.serial.read(MicroBitSerialMode::ASYNC);
}
/**
* Send a piece of text through the serial connection.
*/
//% help=serial/write-string
https://github.com/microbit-foundation/codal-core/blob/master/source/driver-models/Serial.cpp#L932
return p;
}
}
return 0;
}
HandlerBinding *findBinding(int source, int value) {
return nextBinding(handlerBindings, source, value);
}
void setBinding(int source, int value, Action act) {
HandlerBinding *curr = NULL;
for (auto p = handlerBindings; p; p = p->next) {
if ((p->source == source) && (p->value == value)) {
curr = p;
break;
}
}
if (curr) {
curr->action = act;
return;
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