javascriptlorabbc-microbit

Microbit truncates messages received from LoRa Reyax RYLR890/896 module


I have set up a MicroBit as a LoRa receiver using a LoRa module from Reyax RYLR890/896. These LoRa modules receive/transmit information with AT commands over the serial port.

On the transmitter, I have an ESP32 that I have programmed in C in the Arduino framework. It is wired to a Reyax RYLR890 module and transmits a message every few seconds with an 'AT+SEND' command. I have verified that it transmits correctly with another Reyax RYLR890 module set up as receiver in the following ways:

  1. Hooked up to my Macbook's USB port via FTDI adapter to convert between UART and USB serial protocols. I use the CoolTerm serial monitor to see the received messages.
  2. Wired to another ESP32 connected my Macbook's USB port. I can see the received messages in the serial monitor in PlatformIO.

The transmissions are correctly sent and received in both cases.

Now I set up reception on a Microbit using two pins (14, 15) for serial redirect. I am able to receive transmissions but they are truncated for some reason. Instead of "Hello World", I only see "Hello W". Here is my code:

let preamble = ""
let comma_first = 0
let generic_message = ""
let comma_second = 0
let sizeTx = 0
let payload = ""
let messageRx = ""

input.onButtonPressed(Button.A, function () {
    serial.redirect(
    SerialPin.P15,
    SerialPin.P14,
    BaudRate.BaudRate9600
    )
    basic.showIcon(IconNames.Yes)
})

function parseRx (message: string) {
    // message: "+RCV=120,11,HELLO WORLD,-99,40\n"
    preamble = message.substr(1, 3)
    if (preamble == "RCV") { // Check
        // Play tone
        music.playTone(262, music.beat(BeatFraction.Whole))
        // Find 1st comma
        comma_first = message.indexOf(",")
        // Get "11,HELLO WORLD,-99,40\n"
        generic_message = message.substr(comma_first + 1, message.length - comma_first)
        // Find next comma
        comma_second = generic_message.indexOf(",")
        // Extract size of payload and use it to get payload
        sizeTx = parseFloat(generic_message.substr(0, comma_second)) // 11
        payload = generic_message.substr(comma_second + 1, sizeTx) // HELLO WORLD
        // Display 
        basic.showString("" + (payload.length))
        if (payload.includes("WOR")) { // FAILS!! HELLO W
            basic.showIcon(IconNames.SmallHeart)
        }
    }
}

serial.onDataReceived(serial.delimiters(Delimiters.NewLine), function () {
    messageRx = serial.readUntil(serial.delimiters(Delimiters.NewLine))
    parseRx(messageRx)
    basic.clearScreen()
    basic.showIcon(IconNames.Happy)
    basic.clearScreen()
})

I appreciate any help figuring this out.


Solution

  • It turns out that the size of the serial buffer was the issue that was the root cause of incoming radio transmissions being truncated. The default size is 20 Bytes (here) and triggers an event when 20 Bytes are rec'd (here).

    The fix turned out to be to increase the buffer size. This additional line of code serial.setRxBufferSize(128) did the job. Ref. docs.

    let preamble = ""
    let comma_first = 0
    let generic_message = ""
    let comma_second = 0
    let sizeTx = 0
    let payload = ""
    let messageRx = ""
    input.onButtonPressed(Button.A, function () {
        serial.redirect(
        SerialPin.P15,
        SerialPin.P14,
        BaudRate.BaudRate9600
        )
        serial.setRxBufferSize(128)
        basic.showIcon(IconNames.Yes)
    })
    function parseRx (message: string) {
        preamble = message.substr(1, 3)
        if (preamble == "RCV") {
            music.playTone(988, music.beat(BeatFraction.Whole))
            comma_first = message.indexOf(",")
            generic_message = message.substr(comma_first + 1, message.length - comma_first)
            comma_second = generic_message.indexOf(",")
            sizeTx = parseFloat(generic_message.substr(0, comma_second))
            payload = generic_message.substr(comma_second + 1, sizeTx)
            basic.showString("" + (payload.length))
            if (payload.includes("WOR")) {
                basic.showIcon(IconNames.SmallHeart)
            }
        }
    }
    serial.onDataReceived(serial.delimiters(Delimiters.NewLine), function () {
        messageRx = serial.readUntil(serial.delimiters(Delimiters.NewLine))
        parseRx(messageRx)
        basic.clearScreen()
        basic.showIcon(IconNames.Happy)
        basic.clearScreen()
    })
    

    enter image description here