Search code examples
micropythonraspberry-pi-picolora

How to change byte literal to str variable with LoRa module's send()?


For 2 Raspberry Pi Pico's with SX126X LoRa modules attached I use this library and have the ping pong example working. I want to send a JSON string from one to the other. sx.send(b'Ping') sends b'Ping' to the remote device (if I remove the b it fails).

I want to save a JSON string to a variable and send it with sx.send(). The b is somehow required and I can't figure out how to swap literal 'Ping' with a variable.

From main.py:

while True:
    sx.send(b'Ping')
    time.sleep(10)

SX1262.py:

def send(self, data):
    if not self.blocking:
        return self._startTransmit(data)
    else:
        return self._transmit(data)


def _startTransmit(self, data):
    if isinstance(data, bytes) or isinstance(data, bytearray):
        pass
    else:
        return 0, ERR_INVALID_PACKET_TYPE

Solution

  • the b in sx.send(b'Ping') means that you are sending literal bytes, as opposed to a string. This notation is internal to Python. What is actually sent is Ping. And when the other device receives it, it is stored as bytes, and when displayed:

    >>>> packet = b'Ping'
    >>>> packet
    b'Ping'
    >>>> len(packet)
    4
    

    As you can see there are only 4 bytes in packet.

    To send a JSON string you can do something like this:

    >>>> import json
    >>>> p = '{"name": "Bob", "languages": ["Python", "Java"]}'
    >>>> j = json.loads(p)
    >>>> sx.send(bytes(json.dumps(j).encode()))
    

    json.dumps(j) takes a JSON object j and transforms it into a string with dumps(), after making sure it has an encoding (encode()), and turns that string into bytes. Which you can send.

    On the other side, on device 2, you can just json.loads() the bytes to make it a JSON object.

    Getting the values back to variables is easy:

    >>>> j['name']
    'Bob'
    >>>> j['languages']
    ['Python', 'Java']