diff --git a/pi_radio/font5x8.bin b/pi_radio/font5x8.bin new file mode 100755 index 00000000..9a0563ba Binary files /dev/null and b/pi_radio/font5x8.bin differ diff --git a/pi_radio/radio_lorawan.py b/pi_radio/radio_lorawan.py new file mode 100755 index 00000000..f96b7c7d --- /dev/null +++ b/pi_radio/radio_lorawan.py @@ -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) diff --git a/pi_radio/radio_rfm69.py b/pi_radio/radio_rfm69.py new file mode 100644 index 00000000..78d21a20 --- /dev/null +++ b/pi_radio/radio_rfm69.py @@ -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) diff --git a/pi_radio/radio_rfm9x.py b/pi_radio/radio_rfm9x.py new file mode 100755 index 00000000..7d4ff655 --- /dev/null +++ b/pi_radio/radio_rfm9x.py @@ -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) diff --git a/pi_radio/rfm69.fzz b/pi_radio/rfm69.fzz new file mode 100644 index 00000000..9aeb3f51 Binary files /dev/null and b/pi_radio/rfm69.fzz differ diff --git a/pi_radio/rfm69_check.py b/pi_radio/rfm69_check.py new file mode 100644 index 00000000..97307775 --- /dev/null +++ b/pi_radio/rfm69_check.py @@ -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) diff --git a/pi_radio/rfm9x.fzz b/pi_radio/rfm9x.fzz new file mode 100644 index 00000000..8054e3b8 Binary files /dev/null and b/pi_radio/rfm9x.fzz differ diff --git a/pi_radio/rfm9x_check.py b/pi_radio/rfm9x_check.py new file mode 100644 index 00000000..f1c05d42 --- /dev/null +++ b/pi_radio/rfm9x_check.py @@ -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) diff --git a/pi_radio/ttn_decoder_lorawan.js b/pi_radio/ttn_decoder_lorawan.js new file mode 100644 index 00000000..d02c806c --- /dev/null +++ b/pi_radio/ttn_decoder_lorawan.js @@ -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; +} \ No newline at end of file