commit
7af22472fc
9 changed files with 488 additions and 0 deletions
BIN
pi_radio/font5x8.bin
Executable file
BIN
pi_radio/font5x8.bin
Executable file
Binary file not shown.
117
pi_radio/radio_lorawan.py
Executable file
117
pi_radio/radio_lorawan.py
Executable file
|
|
@ -0,0 +1,117 @@
|
|||
"""
|
||||
Example for using the RFM9x Radio with Raspberry Pi and LoRaWAN
|
||||
|
||||
Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi
|
||||
Author: Brent Rubell for Adafruit Industries
|
||||
"""
|
||||
import threading
|
||||
import time
|
||||
import subprocess
|
||||
import busio
|
||||
from digitalio import DigitalInOut, Direction, Pull
|
||||
import board
|
||||
# Import thte SSD1306 module.
|
||||
import adafruit_ssd1306
|
||||
# Import Adafruit TinyLoRa
|
||||
from adafruit_tinylora.adafruit_tinylora import TTN, TinyLoRa
|
||||
|
||||
# Button A
|
||||
btnA = DigitalInOut(board.D5)
|
||||
btnA.direction = Direction.INPUT
|
||||
btnA.pull = Pull.UP
|
||||
|
||||
# Button B
|
||||
btnB = DigitalInOut(board.D6)
|
||||
btnB.direction = Direction.INPUT
|
||||
btnB.pull = Pull.UP
|
||||
|
||||
# Button C
|
||||
btnC = DigitalInOut(board.D12)
|
||||
btnC.direction = Direction.INPUT
|
||||
btnC.pull = Pull.UP
|
||||
|
||||
# Create the I2C interface.
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
|
||||
# 128x32 OLED Display
|
||||
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c)
|
||||
# Clear the display.
|
||||
display.fill(0)
|
||||
display.show()
|
||||
width = display.width
|
||||
height = display.height
|
||||
|
||||
# TinyLoRa Configuration
|
||||
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
|
||||
cs = DigitalInOut(board.D18)
|
||||
irq = DigitalInOut(board.D25)
|
||||
# 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])
|
||||
# Initialize ThingsNetwork configuration
|
||||
ttn_config = TTN(devaddr, nwkey, app, country='US')
|
||||
# Initialize lora object
|
||||
lora = TinyLoRa(spi, cs, irq, ttn_config)
|
||||
# 2b array to store sensor data
|
||||
data_pkt = bytearray(2)
|
||||
# time to delay periodic packet sends (in seconds)
|
||||
data_pkt_delay = 5.0
|
||||
|
||||
|
||||
def send_pi_data_periodic():
|
||||
threading.Timer(data_pkt_delay, send_pi_data_periodic).start()
|
||||
print("Sending periodic data...")
|
||||
send_pi_data(CPU)
|
||||
print('CPU:', CPU)
|
||||
|
||||
def send_pi_data(data):
|
||||
# Encode float as int
|
||||
data = int(data * 100)
|
||||
# Encode payload as bytes
|
||||
data_pkt[0] = (data >> 8) & 0xff
|
||||
data_pkt[1] = data & 0xff
|
||||
# Send data packet
|
||||
lora.send_data(data_pkt, len(data_pkt), lora.frame_counter)
|
||||
lora.frame_counter += 1
|
||||
display.fill(0)
|
||||
display.text('Sent Data to TTN!', 15, 15, 1)
|
||||
print('Data sent!')
|
||||
display.show()
|
||||
time.sleep(0.5)
|
||||
|
||||
while True:
|
||||
packet = None
|
||||
# draw a box to clear the image
|
||||
display.fill(0)
|
||||
display.text('RasPi LoRaWAN', 35, 0, 1)
|
||||
|
||||
# read the raspberry pi cpu load
|
||||
cmd = "top -bn1 | grep load | awk '{printf \"%.1f\", $(NF-2)}'"
|
||||
CPU = subprocess.check_output(cmd, shell = True )
|
||||
CPU = float(CPU)
|
||||
|
||||
if not btnA.value:
|
||||
# Send Packet
|
||||
send_pi_data(CPU)
|
||||
if not btnB.value:
|
||||
# Display CPU Load
|
||||
display.fill(0)
|
||||
display.text('CPU Load %', 45, 0, 1)
|
||||
display.text(str(CPU), 60, 15, 1)
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
if not btnC.value:
|
||||
display.fill(0)
|
||||
display.text('* Periodic Mode *', 15, 0, 1)
|
||||
display.show()
|
||||
time.sleep(0.5)
|
||||
send_pi_data_periodic()
|
||||
|
||||
|
||||
display.show()
|
||||
time.sleep(.1)
|
||||
94
pi_radio/radio_rfm69.py
Normal file
94
pi_radio/radio_rfm69.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
"""
|
||||
Demo of using the RFM69HCW Radio with Raspberry Pi.
|
||||
|
||||
Author: Brent Rubell for Adafruit Industries
|
||||
"""
|
||||
import time
|
||||
import busio
|
||||
from digitalio import DigitalInOut, Direction, Pull
|
||||
import board
|
||||
# Import the RFM69 radio module.
|
||||
import adafruit_rfm69
|
||||
# Import the SSD1306 module.
|
||||
import adafruit_ssd1306
|
||||
|
||||
# Button A
|
||||
btnA = DigitalInOut(board.D5)
|
||||
btnA.direction = Direction.INPUT
|
||||
btnA.pull = Pull.UP
|
||||
|
||||
# Button B
|
||||
btnB = DigitalInOut(board.D6)
|
||||
btnB.direction = Direction.INPUT
|
||||
btnB.pull = Pull.UP
|
||||
|
||||
# Create the I2C interface.
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
|
||||
# 128x32 OLED Display
|
||||
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c)
|
||||
# Clear the display.
|
||||
display.fill(0)
|
||||
display.show()
|
||||
width = display.width
|
||||
height = display.height
|
||||
|
||||
# Configure Packet Radio
|
||||
CS = DigitalInOut(board.D18)
|
||||
RESET = DigitalInOut(board.D25)
|
||||
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
|
||||
rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, 915.0)
|
||||
|
||||
# Optionally set an encryption key (16 byte AES key). MUST match both
|
||||
# on the transmitter and receiver (or be set to None to disable/the default).
|
||||
rfm69.encryption_key = b'\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08'
|
||||
# Data to send
|
||||
packet_data = bytes('Hello Feather!\r\n',"utf-8")
|
||||
prev_packet = None
|
||||
|
||||
while True:
|
||||
packet = None
|
||||
# draw a box to clear the image
|
||||
display.fill(0)
|
||||
display.text('RasPi Radio', 35, 0, 1)
|
||||
|
||||
# check for packet rx
|
||||
packet = rfm69.receive()
|
||||
print(packet)
|
||||
if packet is None:
|
||||
display.show()
|
||||
display.text('- Waiting for PKT -', 0, 20, 1)
|
||||
else:
|
||||
# Display the packet text and rssi
|
||||
display.fill(0)
|
||||
prev_packet = packet
|
||||
packet_text = str(prev_packet, 'ascii')
|
||||
display.text('RX: ', 0, 0, 1)
|
||||
display.text(packet_text, 25, 0, 1)
|
||||
display.text('RSSI: ', 0, 20, 1)
|
||||
display.text(str(rfm69.rssi), 35, 20, 1)
|
||||
time.sleep(2)
|
||||
|
||||
if not btnA.value:
|
||||
# Send Packet
|
||||
rfm69.send(packet_data)
|
||||
display.fill(0)
|
||||
display.text('Sent Packet', 0, 25, 1)
|
||||
display.show()
|
||||
time.sleep(0.2)
|
||||
elif not btnB.value:
|
||||
# Display the previous packet text and rssi
|
||||
display.fill(0)
|
||||
if prev_packet is not None:
|
||||
packet_text = str(prev_packet, 'ascii')
|
||||
display.text('RX: ', 0, 0, 1)
|
||||
display.text(packet_text, 25, 0, 1)
|
||||
display.text('RSSI: ', 0, 20, 1)
|
||||
display.text(str(rfm69.rssi), 35, 20, 1)
|
||||
else:
|
||||
display.text('No Pkt RCVd', 0, 16, 1)
|
||||
display.show()
|
||||
time.sleep(2)
|
||||
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
110
pi_radio/radio_rfm9x.py
Executable file
110
pi_radio/radio_rfm9x.py
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
"""
|
||||
Example for using the RFM9x Radio with Raspberry Pi.
|
||||
|
||||
Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi
|
||||
Author: Brent Rubell for Adafruit Industries
|
||||
"""
|
||||
import time
|
||||
import threading
|
||||
import busio
|
||||
from digitalio import DigitalInOut, Direction, Pull
|
||||
import board
|
||||
# Import thte SSD1306 module.
|
||||
import adafruit_ssd1306
|
||||
# Import the RFM9x
|
||||
import adafruit_rfm9x
|
||||
|
||||
# Button A
|
||||
btnA = DigitalInOut(board.D5)
|
||||
btnA.direction = Direction.INPUT
|
||||
btnA.pull = Pull.UP
|
||||
|
||||
# Button B
|
||||
btnB = DigitalInOut(board.D6)
|
||||
btnB.direction = Direction.INPUT
|
||||
btnB.pull = Pull.UP
|
||||
|
||||
# Button C
|
||||
btnC = DigitalInOut(board.D12)
|
||||
btnC.direction = Direction.INPUT
|
||||
btnC.pull = Pull.UP
|
||||
|
||||
# Create the I2C interface.
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
|
||||
# 128x32 OLED Display
|
||||
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c)
|
||||
# Clear the display.
|
||||
display.fill(0)
|
||||
display.show()
|
||||
width = display.width
|
||||
height = display.height
|
||||
|
||||
# Configure LoRa Radio
|
||||
CS = DigitalInOut(board.D18)
|
||||
RESET = DigitalInOut(board.D25)
|
||||
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
|
||||
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0)
|
||||
rfm9x.tx_power = 23
|
||||
data_to_send = bytes("Hello LoRa!\r\n","utf-8")
|
||||
prev_packet = None
|
||||
# time to delay periodic packet sends (in seconds)
|
||||
data_pkt_delay = 30.0
|
||||
|
||||
def send_pi_data_periodic():
|
||||
threading.Timer(data_pkt_delay, send_pi_data_periodic).start()
|
||||
print("Sending periodic data...")
|
||||
send_pi_data()
|
||||
|
||||
def send_pi_data():
|
||||
rfm9x.send(data_to_send)
|
||||
display.fill(0)
|
||||
display.text('Sent Packet', 35, 15, 1)
|
||||
print('Sent Packet!')
|
||||
display.show()
|
||||
time.sleep(0.5)
|
||||
|
||||
while True:
|
||||
packet = None
|
||||
# draw a box to clear the image
|
||||
display.fill(0)
|
||||
display.text('RasPi LoRa', 35, 0, 1)
|
||||
|
||||
# check for packet rx
|
||||
packet = rfm9x.receive()
|
||||
if packet is None:
|
||||
display.show()
|
||||
display.text('- Waiting for PKT -', 0, 20, 1)
|
||||
else:
|
||||
# Display the packet text and rssi
|
||||
display.fill(0)
|
||||
prev_packet = packet
|
||||
packet_text = str(prev_packet, 'ascii')
|
||||
display.text('RX: ', 0, 0, 1)
|
||||
display.text(packet_text, 25, 0, 1)
|
||||
time.sleep(1)
|
||||
|
||||
if not btnA.value:
|
||||
# Send Packet
|
||||
send_pi_data()
|
||||
elif not btnB.value:
|
||||
# Display the previous packet text and rssi
|
||||
display.fill(0)
|
||||
if prev_packet is not None:
|
||||
packet_text = str(prev_packet, 'ascii')
|
||||
display.text('RX: ', 0, 0, 1)
|
||||
display.text(packet_text, 25, 0, 1)
|
||||
else:
|
||||
display.text('No Pkt RCVd', 0, 16, 1)
|
||||
display.show()
|
||||
time.sleep(1)
|
||||
elif not btnC.value:
|
||||
display.fill(0)
|
||||
display.text('* Periodic Mode *', 15, 0, 1)
|
||||
display.show()
|
||||
time.sleep(0.2)
|
||||
send_pi_data_periodic()
|
||||
|
||||
|
||||
display.show()
|
||||
time.sleep(.1)
|
||||
BIN
pi_radio/rfm69.fzz
Normal file
BIN
pi_radio/rfm69.fzz
Normal file
Binary file not shown.
78
pi_radio/rfm69_check.py
Normal file
78
pi_radio/rfm69_check.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
"""
|
||||
Wiring Check, Pi Radio w/RFM69
|
||||
|
||||
Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi
|
||||
Author: Brent Rubell for Adafruit Industries
|
||||
"""
|
||||
import time
|
||||
import busio
|
||||
from digitalio import DigitalInOut, Direction, Pull
|
||||
import board
|
||||
# Import the SSD1306 module.
|
||||
import adafruit_ssd1306
|
||||
# Import the RFM69 radio module.
|
||||
import adafruit_rfm69
|
||||
|
||||
# Button A
|
||||
btnA = DigitalInOut(board.D26)
|
||||
btnA.direction = Direction.INPUT
|
||||
btnA.pull = Pull.UP
|
||||
|
||||
# Button B
|
||||
btnB = DigitalInOut(board.D19)
|
||||
btnB.direction = Direction.INPUT
|
||||
btnB.pull = Pull.UP
|
||||
|
||||
# Button C
|
||||
btnC = DigitalInOut(board.D13)
|
||||
btnC.direction = Direction.INPUT
|
||||
btnC.pull = Pull.UP
|
||||
|
||||
# Create the I2C interface.
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
|
||||
# 128x32 OLED Display
|
||||
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c)
|
||||
# Clear the display.
|
||||
display.fill(0)
|
||||
display.show()
|
||||
width = display.width
|
||||
height = display.height
|
||||
|
||||
|
||||
# RFM69 Configuration
|
||||
CS = DigitalInOut(board.D18)
|
||||
RESET = DigitalInOut(board.D25)
|
||||
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
|
||||
|
||||
while True:
|
||||
# Draw a black filled box to clear the image.
|
||||
display.fill(0)
|
||||
|
||||
# Attempt to set up the RFM69 Module
|
||||
try:
|
||||
rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, 915.0)
|
||||
display.text('RFM69: Detected', 0, 0, 1)
|
||||
except RuntimeError:
|
||||
# Thrown on version mismatch
|
||||
display.text('RFM69: ERROR', 0, 0, 1)
|
||||
|
||||
# Check buttons
|
||||
if not btnA.value:
|
||||
# Button A Pressed
|
||||
display.text('Ada', width-85, height-7, 1)
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
if not btnB.value:
|
||||
# Button B Pressed
|
||||
display.text('Fruit', width-75, height-7, 1)
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
if not btnC.value:
|
||||
# Button C Pressed
|
||||
display.text('Radio', width-65, height-7, 1)
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
BIN
pi_radio/rfm9x.fzz
Normal file
BIN
pi_radio/rfm9x.fzz
Normal file
Binary file not shown.
77
pi_radio/rfm9x_check.py
Normal file
77
pi_radio/rfm9x_check.py
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
"""
|
||||
Wiring Check, Pi Radio w/RFM9x
|
||||
|
||||
Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi
|
||||
Author: Brent Rubell for Adafruit Industries
|
||||
"""
|
||||
import time
|
||||
import busio
|
||||
from digitalio import DigitalInOut, Direction, Pull
|
||||
import board
|
||||
# Import the SSD1306 module.
|
||||
import adafruit_ssd1306
|
||||
# Import the RFM9x radio module.
|
||||
import adafruit_rfm9x
|
||||
|
||||
# Button A
|
||||
btnA = DigitalInOut(board.D26)
|
||||
btnA.direction = Direction.INPUT
|
||||
btnA.pull = Pull.UP
|
||||
|
||||
# Button B
|
||||
btnB = DigitalInOut(board.D19)
|
||||
btnB.direction = Direction.INPUT
|
||||
btnB.pull = Pull.UP
|
||||
|
||||
# Button C
|
||||
btnC = DigitalInOut(board.D13)
|
||||
btnC.direction = Direction.INPUT
|
||||
btnC.pull = Pull.UP
|
||||
|
||||
# Create the I2C interface.
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
|
||||
# 128x32 OLED Display
|
||||
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c)
|
||||
# Clear the display.
|
||||
display.fill(0)
|
||||
display.show()
|
||||
width = display.width
|
||||
height = display.height
|
||||
|
||||
# Configure RFM9x LoRa Radio
|
||||
CS = DigitalInOut(board.D18)
|
||||
RESET = DigitalInOut(board.D25)
|
||||
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
|
||||
|
||||
while True:
|
||||
# Clear the image
|
||||
display.fill(0)
|
||||
|
||||
# Attempt to set up the RFM9x Module
|
||||
try:
|
||||
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0)
|
||||
display.text('RFM9x: Detected', 0, 0, 1)
|
||||
except RuntimeError:
|
||||
# Thrown on version mismatch
|
||||
display.text('RFM9x: ERROR', 0, 0, 1)
|
||||
|
||||
# Check buttons
|
||||
if not btnA.value:
|
||||
# Button A Pressed
|
||||
display.text('Ada', width-85, height-7, 1)
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
if not btnB.value:
|
||||
# Button B Pressed
|
||||
display.text('Fruit', width-75, height-7, 1)
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
if not btnC.value:
|
||||
# Button C Pressed
|
||||
display.text('Radio', width-65, height-7, 1)
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
|
||||
display.show()
|
||||
time.sleep(0.1)
|
||||
12
pi_radio/ttn_decoder_lorawan.js
Normal file
12
pi_radio/ttn_decoder_lorawan.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// TinyLoRa - Raspberry Pi CPU Load Decoder
|
||||
function Decoder(bytes, port) {
|
||||
var decoded = {};
|
||||
|
||||
// Decode bytes to int
|
||||
var CPU_Load = (bytes[0] << 8) | bytes[1];
|
||||
|
||||
// Decode int to float
|
||||
decoded.CPU_Load = CPU_Load / 100;
|
||||
|
||||
return decoded;
|
||||
}
|
||||
Loading…
Reference in a new issue