Connecting a Pico using LoRaWAN#

Requirements

  1. A Pico

  2. A LoRaWan adapator (we are using a Dragino LA66)

../../_images/Dragino.jpg

These shields are in fact intended to slot ontop of a different type of microcontroller board called an Arduino (hence all the pins and unusual shape). However, with some quick wiring you can easily get all the same functionality with your Raspberry Pi Pico.

Pinout#

The Pico can communicate with the LA66 module via UART. This means we only need the following four connections.

Pico Pin

Dragino Pin

GP0 (TX)

D11 (TX)

GP1 (RX)

D10 (RX)

3.3V (Power Out)

3.3V (Power In)

Ground (GND)

See below

To ground the LA66 module, connect to the pin on the board, highlighted below.

../../_images/Draginognd.jpg

Sending Commands#

Understanding how the LA66 generates LoRa radio signals is very complicated and far beyond the scope of this course. Thankfully, the module has various built-in commands that allow us to send data and get key device information. To issue these commands, we can send strings encoded into digital signals to the LA66 module, via UART.

The code below shows how you can program your Pico to send these commands.

import board
import busio
import time
import microcontroller

uart = busio.UART(board.GP0, board.GP1, baudrate=9600, timeout=1)

def send_command(command):                        # Format a command to send to the LA66 module
    uart.write(bytes(command + '\r\n', 'ASCII'))  # Send command as ASCII
    time.sleep(0.5)                               # Wait for the module to process the command
    response = uart.read(64)                      # Read up to 64 bytes of the response
    if response:
        try:
            decoded_response = response.decode('ASCII').strip()
            return decoded_response
        except UnicodeError as e:
            print("UnicodeError:", e)
            return None
    else:
        return None

When you need to send commands to the Dragino later on, include this code and use send_command('command...').

See also

For a full list and descriptions of available AT commands see the DataSheet under the documents tab on the product website.

Sending and Storing data#

Now that you have registered your Dragino LoRaWAN shield onto The Things Network, you can send data via the radio antenna which will be picked up and stored in The Things Stack.

The code below shows how you can send CPU temperature data from the Pico to your device page in The Things Stack.

import board
import busio
import time
import microcontroller

uart = busio.UART(board.GP0, board.GP1, baudrate=9600, timeout=1)

def send_command(command):                       
    '''Takes a given AT command for the LA66 module

    Formats command to work over UART and sends it to module

    Args:
        command (str): string containing the AT command

    Returns:
        string: The response from the module, returns None upon any failures
    '''
    uart.write(bytes(command + '\r\n', 'ASCII')) # Send command as ASCII
    time.sleep(0.5)                              # Wait for the module to process the command
    response = uart.read(64)                     # Read up to 64 bytes of the response
    if response:
        try:
            decoded_response = response.decode('ASCII').strip()
            return decoded_response
        except UnicodeError as e:
            print("UnicodeError:", e)
            return None
    else:
        return None

def convert_data(data):                          # Convert data into hexidecimal values
    '''Converts data into hexbytes for transmission.
    Input data should be an integer as any decimals will be lost
    If decimals are required prescale the data

    Args:
        data (int): The value to convert into hex

    Returns:
        string: string representation of the data in hex format
    '''
    hexnum = f"{(data >> 8) & 0xFF:02X}{data & 0xFF:02X}"
    return hexnum


while True:
    temp = microcontroller.cpu.temperature
    print(f'Temperature: {temp}')
    data = convert_data(temp)
    datasize = int(len(data)/2)                 # Size of the data (AKA 'payload') in bytes
    response = send_command(f'AT+SENDB=0,2,{datasize},{data}')  # Command to send data
    print(response)
    time.sleep(30)

The key line here is the AT+SENDB=... command, which is used to send data in hexidecimal form. We thus convert numerical (decimal) data into hexidecimal and multiply by 1000 to preserve some decimal spaces, e.g. convert_data(23.452) = 5B 9C

Caution

As an open-access and free server, The Things Stack operates with a fair-use policy that says you can’t send data more frequently than every 30 seconds.