Merge pull request #451 from brentru/pi-radio

Pi Radio LearnGuide
This commit is contained in:
Limor "Ladyada" Fried 2019-01-02 08:57:51 -08:00 committed by GitHub
commit 7af22472fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 488 additions and 0 deletions

BIN
pi_radio/font5x8.bin Executable file

Binary file not shown.

117
pi_radio/radio_lorawan.py Executable file
View 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
View 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
View 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

Binary file not shown.

78
pi_radio/rfm69_check.py Normal file
View 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

Binary file not shown.

77
pi_radio/rfm9x_check.py Normal file
View 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)

View 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;
}