logo

Receiving radio data from PXT within Python

PROBLEM

I want to send a text string from PXT to Python.

Why do I get ‘junk’ at the start of a radio message sent by PXT?

Python not receiving radio message correctly.

CAUSE

The PXT radio blocks add some additional binary information at the start of the radio message. When received by Python, this binary data can cause your program to crash.

SOLUTION

You need to step over the first 12 bytes of any radio message transmitted by PXT, in order to get at the data inside the message.

Byte 3 is the payload type as follows:

C++
// payload: number (9 ... 12)
#define PACKET_TYPE_NUMBER 0

// payload: number (9 ... 12), name length (13), name (14 ... 26)
#define PACKET_TYPE_VALUE 1

// payload: string length (9), string (10 ... 28)
#define PACKET_TYPE_STRING 2

EXAMPLE

The below PXT code transmits the message ‘DALEK’ every second, and can be used to test the below Python code with.

Js
basic.forever(() => {
    radio.sendString("DALEK")
    basic.showLeds(`
        . # . . .
        # # # # #
        # # . . .
        # # # # .
        # # # . .
        `)
    basic.pause(500)
    basic.clearScreen()
    basic.pause(500)
})
radio.setGroup(132)


The following code, written in MicroPython, will receive any string message that the above PXT program transmits on radio group 132 and then scroll the text message on the screen.

from microbit import *
import radio

radio.config(group=132)
radio.on()

def get_message():
    while True:
        try:
            msg = radio.receive_bytes()
            if msg is not None:
                if len(msg) >= 13 and msg[3] == 2:
                    lstr = msg[12] # length byte
                    text = str(msg[13:13+lstr], 'ascii')
                    return text

        except Exception as e: # reset radio on error
            print("reset %s" % str(e))
            radio.off()
            radio.on()

while True:
    print("waiting...")
    display.show('?')

    m = get_message()
    print('got message:', m)
    display.scroll(m)

FURTHER INFORMATION

The radio payload sent from PXT has the following format:

01 00 01 | 02 | 1E 01 01 00 | 00 00 00 00 | 05 44 41 4C 45 4B

--- DAL HEADER
01                      raw payload
00                      group 0?
01                      version 1

-- PXT HEADER
02                      type=string
1E 01 01 00             timestamp
00 00 00 00             serial number (disabled)

-- PXT DATA
05                      length of string
44 41 4C 45 4B          DALEK

SIMPLIFIED VERSION

If you are not too worried about errors, you can use this simplified version

from microbit import *
import radio
radio.config(group=132)
radio.on()

while True:
    display.show('?')
    text = None 
    while text is None:
        try:
            msg = radio.receive_bytes()
            if msg is not None:
                text = str(msg[13:], 'ascii')
        except: 
            display.scroll("ERROR")

    display.scroll(text)
1 found this helpful
All for Joomla All for Webmasters