We've sent data from our sensor devices to Adafruit IO over LoRa, but what about sending data over a different protocol - LoRaWAN?
The Adafruit_TinyLoRa library allows the RFM9x to be used as a LoRaWAN device capable of communicating its data over longer distance with less power utilization.
The code below will use the adafruit_tinylora
library which provides high-level access to your radio transceiver features.
The code for sending data using a BME280 sensor, along with a unique feather identifier, to a Things Network Gateway is shown below:
# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries # # SPDX-License-Identifier: MIT import time import board import busio from digitalio import DigitalInOut import adafruit_bme280 from adafruit_tinylora.adafruit_tinylora import TTN, TinyLoRa # Unique feather identifier FEATHER_ID = 1 i2c = busio.I2C(board.SCL, board.SDA) bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c) # TinyLoRa/RFM9x Setup spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) # pylint: disable=c-extension-no-member cs = DigitalInOut(board.RFM9X_CS) irq = DigitalInOut(board.RFM9X_D0) rst = DigitalInOut(board.RFM9X_RST) # TTN Device Address, 4 Bytes, MSB devaddr = bytearray([0x00, 0x00, 0x00, 0x00]) # TTN Network Key, 16 Bytes, MSB nwkey = bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) # TTN Application Key, 16 Bytess, MSB app = bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) ttn_config = TTN(devaddr, nwkey, app, country='US') lora = TinyLoRa(spi, cs, irq, rst, ttn_config, channel = 6) # bme data packet bme_d = bytearray(7) while True: # Grab sensor data temp_val = int(bme280.temperature * 100) humid_val = int(bme280.humidity * 100) bme_d[0] = FEATHER_ID # Temperature data bme_d[1] = (temp_val >> 8) & 0xff bme_d[2] = temp_val & 0xff # Humidity data bme_d[3] = (humid_val >> 8) & 0xff bme_d[4] = humid_val & 0xff print('Sending packet...') lora.send_data(bme_d, len(bme_d), lora.frame_counter) print('Packet sent!') lora.frame_counter += 1 time.sleep(1 * 60)
While we can send data to The Things Network, and our gateway might notice it, it isn't registered to a device yet.
- To register your feather(s) with The Things Network, follow these steps and come back when you're done.
Running the Code using Mu Editor
Upon saving (ctrl/cmd +s) your code, the board will refresh.
But where is the output? The serial monitor is hidden by default in Mu Editor.
In the Mu Editor, click the Serial button on the top icon-bar to bring up the Serial REPL.
The REPL should output the following:
code.py output: Sending packet... Packet sent!
We still need to check that the Raspberry Pi Gateway receives the packet from the Feather. Let's set that up next.
Run the Python program by entering the following into the terminal:
python3 lorawan_gateway.py
Press the first button to display statistics about the Pi, such as its IP, CPU load, and available memory.
Press the third button to display the name of the gateway along with the frequency, spreading factor, and The Things Network router.
Press the second button to launch the gateway. It'll display the current status (if a packet is received or not) and update the timestamp every minute.
When a LoRa Packet is received by the gateway, the terminal will display that a packet has been received, and it'll print out useful data coming from the packet :
incoming pkt... {"rxpk":[{"tmst":4067850409,"freq":905.1,"chan":0,"rfch":0,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","rssi":-35,"lsnr":10.0,"size":24,"data":"QLERAiYAKAABE0NCX+3lkSnK09WVlk8N"}]}
The display will also refresh to display that a packet has been received.
We can't read the incoming data since it's encrypted. After all, device data shouldn't be readable by a gateway operator. We'll need to check our device on The Things Network Console to read the decrypted data.
We want to make sure the data has been received on the other end. To do this, we'll navigate to the The Things Network Console and select the application. From the menu on the right hand side of the page, Click Data.
If everything worked correctly, you'll see the payload from your device streaming into the page, in real time.
Neat, right? But while we received a payload, we still don't understand what it means. It's been sent to The Things Network and decoded on the client (Gateway) side, so it's not an AES-encrypted payload anymore. It's just not readable by humans.
If you're sending packets in strange formats or encodings (like we are!), The Things Network Console has a programmable data decoder to decode the packets, and assign useful labels to the data.
Copy and paste the decoder script below into the decoder's integrated text editor and click save.
// TinyLoRa - BME280 and Feather ID Decoder function Decoder(bytes, port) { var decoded = {}; // Decode bytes to int var celciusInt = (bytes[1] << 8) | bytes[2]; var humidInt = (bytes[3] << 8) | bytes[4]; // Decode Feather ID decoded.featherID = bytes[0] // Decode int to float decoded.celcius = celciusInt / 100; decoded.humid = humidInt / 100; return decoded; }
Then, click the data tab. Next to the raw payload data, you should see the decoded data for humidity and temperature, along with the unique ID of the feather.
Page last edited January 21, 2025
Text editor powered by tinymce.