Merge remote-tracking branch 'adafruit/master'
This commit is contained in:
commit
30649574d2
18 changed files with 840 additions and 1 deletions
145
Disc_Step_Sequencer/Disc_Step_Sequencer.py
Normal file
145
Disc_Step_Sequencer/Disc_Step_Sequencer.py
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
"""
|
||||
Opto Mechanical Disc Step Sequencer from John Park's Workshop
|
||||
Crickit Feather M4 Express, Crickit FeatherWing, continuous servo,
|
||||
four reflection sensors, speaker
|
||||
|
||||
Adafruit invests time and resources providing this open source code.
|
||||
Please support Adafruit and open source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Dave Astels for Adafruit Industries
|
||||
Copyright (c) 2018 Adafruit Industries
|
||||
Licensed under the MIT license.
|
||||
|
||||
All text above must be included in any redistribution.
|
||||
"""
|
||||
|
||||
import audioio
|
||||
import board
|
||||
from digitalio import DigitalInOut, Direction
|
||||
from adafruit_crickit import crickit
|
||||
from debouncer import Debouncer
|
||||
|
||||
# You get 4 samples, they must all have the same sample rate and must
|
||||
# all be mono or stereo (no mix-n-match!)
|
||||
# mixer info https://circuitpython.readthedocs.io/en/latest/shared-bindings/audioio/Mixer.html
|
||||
|
||||
VOICES = ["bd_tek.wav", "elec_hi_snare.wav", "ch_01.wav", "clap_01.wav"]
|
||||
# Parse the first file to figure out what format its in
|
||||
with open(VOICES[0], "rb") as f:
|
||||
wav = audioio.WaveFile(f)
|
||||
print("%d channels, %d bits per sample, %d Hz sample rate " %
|
||||
(wav.channel_count, wav.bits_per_sample, wav.sample_rate))
|
||||
|
||||
# Audio playback object - we'll go with either mono or stereo depending on
|
||||
# what we see in the first file
|
||||
if wav.channel_count == 1:
|
||||
audio = audioio.AudioOut(board.A0)
|
||||
elif wav.channel_count == 2:
|
||||
# audio = audioio.AudioOut(board.A0, right_channel=board.A0)
|
||||
audio = audioio.AudioOut(board.A0)
|
||||
else:
|
||||
raise RuntimeError("Must be mono or stereo waves!")
|
||||
mixer = audioio.Mixer(voice_count=4,
|
||||
sample_rate=wav.sample_rate,
|
||||
channel_count=wav.channel_count,
|
||||
bits_per_sample=wav.bits_per_sample,
|
||||
samples_signed=True)
|
||||
audio.play(mixer)
|
||||
|
||||
samples = []
|
||||
# Read the 4 wave files, convert to stereo samples, and store
|
||||
# (show load status on neopixels and play audio once loaded too!)
|
||||
for v in VOICES:
|
||||
wave_file = open(v, "rb")
|
||||
print(v)
|
||||
# OK we managed to open the wave OK
|
||||
sample = audioio.WaveFile(wave_file)
|
||||
# debug play back on load!
|
||||
mixer.play(sample, voice=0)
|
||||
while mixer.playing:
|
||||
pass
|
||||
samples.append(sample)
|
||||
|
||||
|
||||
led = DigitalInOut(board.D13)
|
||||
led.direction = Direction.OUTPUT
|
||||
|
||||
# For signal control, we'll chat directly with seesaw, use 'ss' to shorten typing!
|
||||
ss = crickit.seesaw
|
||||
|
||||
# define and set up inputs to use the debouncer
|
||||
def make_criket_signal_debouncer(pin): # create pin signal objects
|
||||
ss.pin_mode(pin, ss.INPUT_PULLUP)
|
||||
return Debouncer(lambda : ss.digital_read(pin))
|
||||
|
||||
# The IR sensors on are pullups, connect to ground to activate
|
||||
clock_pin = make_criket_signal_debouncer(crickit.SIGNAL1)
|
||||
voice_1_pin = make_criket_signal_debouncer(crickit.SIGNAL2)
|
||||
voice_2_pin = make_criket_signal_debouncer(crickit.SIGNAL3)
|
||||
voice_3_pin = make_criket_signal_debouncer(crickit.SIGNAL4)
|
||||
voice_4_pin = make_criket_signal_debouncer(crickit.SIGNAL5)
|
||||
# Crickit capacitive touch pads
|
||||
touch_1_pad = Debouncer(lambda: crickit.touch_1.value)
|
||||
touch_4_pad = Debouncer(lambda: crickit.touch_4.value)
|
||||
touch_2_3_pad = Debouncer(lambda: crickit.touch_2.value and crickit.touch_3.value)
|
||||
|
||||
crickit.continuous_servo_1.set_pulse_width_range(min_pulse=500, max_pulse=2500)
|
||||
speed = -0.04 #this is clockwise/forward at a moderate tempo
|
||||
|
||||
|
||||
def play_voice(vo):
|
||||
mixer.stop_voice(vo)
|
||||
mixer.play(samples[vo], voice=vo, loop=False)
|
||||
|
||||
while True:
|
||||
clock_pin.update() #debouncer at work
|
||||
voice_1_pin.update()
|
||||
voice_2_pin.update()
|
||||
voice_3_pin.update()
|
||||
voice_4_pin.update()
|
||||
touch_1_pad.update()
|
||||
touch_4_pad.update()
|
||||
touch_2_3_pad.update()
|
||||
|
||||
crickit.continuous_servo_1.throttle = speed # spin the disc at speed defined by touch pads
|
||||
|
||||
if clock_pin.fell: # sensor noticed change from white (reflection) to black (no reflection)
|
||||
# this means a clock tick has begun, time to check if any steps will play
|
||||
led.value = 0
|
||||
|
||||
if voice_1_pin.value: # a black step (no reflection) mark during clock tick, play a sound!
|
||||
led.value = 1 # light up LED when step is read
|
||||
# print('| .kick. | | | |')
|
||||
play_voice(0)
|
||||
|
||||
if voice_2_pin.value:
|
||||
led.value = 1
|
||||
# print('| | .snare. | | |')
|
||||
play_voice(1)
|
||||
|
||||
if voice_3_pin.value:
|
||||
led.value = 1
|
||||
# print('| | | .closed hat. | |')
|
||||
play_voice(2)
|
||||
|
||||
if voice_4_pin.value:
|
||||
led.value = 1
|
||||
# print('| | | | .clap. |')
|
||||
play_voice(3)
|
||||
|
||||
if touch_4_pad.rose: # speed it up
|
||||
speed -= 0.001
|
||||
# print("speed: %s" % speed)
|
||||
|
||||
if touch_1_pad.rose: # slow it down
|
||||
speed += 0.001
|
||||
# you can comment out the next two lines if you want to go backwards
|
||||
# however, the clock ticks may not register with the default template spacing
|
||||
if speed >= 0: # to prevent backwards
|
||||
speed = 0
|
||||
# print("speed: %s" % speed)
|
||||
|
||||
if touch_2_3_pad.rose: # stop the disc
|
||||
speed = 0
|
||||
# print("speed: %s" % speed)
|
||||
BIN
Disc_Step_Sequencer/ch_01.wav
Normal file
BIN
Disc_Step_Sequencer/ch_01.wav
Normal file
Binary file not shown.
BIN
Disc_Step_Sequencer/clap_01.wav
Normal file
BIN
Disc_Step_Sequencer/clap_01.wav
Normal file
Binary file not shown.
96
Disc_Step_Sequencer/debouncer.py
Normal file
96
Disc_Step_Sequencer/debouncer.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
"""
|
||||
GPIO Pin Debouncer
|
||||
|
||||
Adafruit invests time and resources providing this open source code.
|
||||
Please support Adafruit and open source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Dave Astels for Adafruit Industries
|
||||
Copyright (c) 2018 Adafruit Industries
|
||||
Licensed under the MIT license.
|
||||
|
||||
All text above must be included in any redistribution.
|
||||
"""
|
||||
|
||||
import time
|
||||
import digitalio
|
||||
|
||||
class Debouncer(object):
|
||||
"""Debounce an input pin"""
|
||||
|
||||
DEBOUNCED_STATE = 0x01
|
||||
UNSTABLE_STATE = 0x02
|
||||
CHANGED_STATE = 0x04
|
||||
|
||||
|
||||
def __init__(self, pin_or_predicate, mode=digitalio.Pull.UP, interval=0.010):
|
||||
"""Make am instance.
|
||||
:param int/function pin_or_predicate: the pin (from board) to debounce
|
||||
:param int mode: digitalio.Pull.UP or .DOWN (default is no pull up/down)
|
||||
:param int interval: bounce threshold in seconds (default is 0.010, i.e. 10 milliseconds)
|
||||
"""
|
||||
self.state = 0x00
|
||||
if isinstance(pin_or_predicate, int):
|
||||
p = digitalio.DigitalInOut(pin_or_predicate)
|
||||
p.direction = digitalio.Direction.INPUT
|
||||
p.pull = mode
|
||||
self.f = lambda : p.value
|
||||
else:
|
||||
self.f = pin_or_predicate
|
||||
if self.f():
|
||||
self.__set_state(Debouncer.DEBOUNCED_STATE | Debouncer.UNSTABLE_STATE)
|
||||
self.previous_time = 0
|
||||
if interval is None:
|
||||
self.interval = 0.010
|
||||
else:
|
||||
self.interval = interval
|
||||
|
||||
|
||||
def __set_state(self, bits):
|
||||
self.state |= bits
|
||||
|
||||
|
||||
def __unset_state(self, bits):
|
||||
self.state &= ~bits
|
||||
|
||||
|
||||
def __toggle_state(self, bits):
|
||||
self.state ^= bits
|
||||
|
||||
|
||||
def __get_state(self, bits):
|
||||
return (self.state & bits) != 0
|
||||
|
||||
|
||||
def update(self):
|
||||
"""Update the debouncer state. Must be called before using any of the properties below"""
|
||||
now = time.monotonic()
|
||||
self.__unset_state(Debouncer.CHANGED_STATE)
|
||||
current_state = self.f()
|
||||
if current_state != self.__get_state(Debouncer.UNSTABLE_STATE):
|
||||
self.previous_time = now
|
||||
self.__toggle_state(Debouncer.UNSTABLE_STATE)
|
||||
else:
|
||||
if now - self.previous_time >= self.interval:
|
||||
if current_state != self.__get_state(Debouncer.DEBOUNCED_STATE):
|
||||
self.previous_time = now
|
||||
self.__toggle_state(Debouncer.DEBOUNCED_STATE)
|
||||
self.__set_state(Debouncer.CHANGED_STATE)
|
||||
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
"""Return the current debounced value of the input."""
|
||||
return self.__get_state(Debouncer.DEBOUNCED_STATE)
|
||||
|
||||
|
||||
@property
|
||||
def rose(self):
|
||||
"""Return whether the debounced input went from low to high at the most recent update."""
|
||||
return self.__get_state(self.DEBOUNCED_STATE) and self.__get_state(self.CHANGED_STATE)
|
||||
|
||||
|
||||
@property
|
||||
def fell(self):
|
||||
"""Return whether the debounced input went from high to low at the most recent update."""
|
||||
return (not self.__get_state(self.DEBOUNCED_STATE)) and self.__get_state(self.CHANGED_STATE)
|
||||
BIN
Disc_Step_Sequencer/fB_bd_tek.wav
Normal file
BIN
Disc_Step_Sequencer/fB_bd_tek.wav
Normal file
Binary file not shown.
BIN
Disc_Step_Sequencer/fB_elec_hi_snare.wav
Normal file
BIN
Disc_Step_Sequencer/fB_elec_hi_snare.wav
Normal file
Binary file not shown.
65
Gemma_Nano_Ring/NanoRing.ino
Normal file
65
Gemma_Nano_Ring/NanoRing.ino
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#include <Adafruit_NeoPixel.h>
|
||||
#define PIN 1
|
||||
#define NUM_LEDS 3
|
||||
|
||||
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
// R G B
|
||||
uint8_t myColors[][5] = {
|
||||
{30, 144, 255}, // dodger blue
|
||||
{232, 100, 255}, // purple
|
||||
{204, 0, 204}, //
|
||||
{200, 200, 20}, // yellow
|
||||
{30, 200, 200}, // blue
|
||||
};
|
||||
|
||||
// don't edit the line below
|
||||
#define FAVCOLORS sizeof(myColors) / 5
|
||||
|
||||
void setup() {
|
||||
strip.begin();
|
||||
strip.setBrightness(20);
|
||||
strip.show(); // Initialize all pixels to 'off'
|
||||
}
|
||||
|
||||
void loop() {
|
||||
flashRandom(10, 1); // first number is 'wait' delay, shorter num == shorter twinkle
|
||||
flashRandom(10, 3); // second number is how many neopixels to simultaneously light up
|
||||
flashRandom(10, 2);
|
||||
}
|
||||
|
||||
void flashRandom(int wait, uint8_t howmany) {
|
||||
|
||||
for(uint16_t i=0; i<howmany; i++) {
|
||||
// pick a random favorite color!
|
||||
int c = random(FAVCOLORS);
|
||||
int red = myColors[c][0];
|
||||
int green = myColors[c][1];
|
||||
int blue = myColors[c][2];
|
||||
|
||||
// get a random pixel from the list
|
||||
int j = random(strip.numPixels());
|
||||
|
||||
// now we will 'fade' it in 5 steps
|
||||
for (int x=0; x < 5; x++) {
|
||||
int r = red * (x+1); r /= 5;
|
||||
int g = green * (x+1); g /= 5;
|
||||
int b = blue * (x+1); b /= 5;
|
||||
|
||||
strip.setPixelColor(j, strip.Color(r, g, b));
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
// & fade out in 5 steps
|
||||
for (int x=5; x >= 0; x--) {
|
||||
int r = red * x; r /= 5;
|
||||
int g = green * x; g /= 5;
|
||||
int b = blue * x; b /= 5;
|
||||
|
||||
strip.setPixelColor(j, strip.Color(r, g, b));
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
// LEDs will be off when done (they are faded to 0)
|
||||
}
|
||||
45
Gemma_Nano_Ring/code.py
Normal file
45
Gemma_Nano_Ring/code.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import time
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
|
||||
try:
|
||||
import urandom as random
|
||||
except ImportError:
|
||||
import random
|
||||
|
||||
numpix = 3 # Number of NeoPixels
|
||||
pixpin = board.D1 # Pin where NeoPixels are connected
|
||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.1, auto_write=True)
|
||||
colors = [
|
||||
[30, 144, 255], # Dodger Blue
|
||||
[232, 100, 255], # Purple
|
||||
[204, 0, 204], # Pink
|
||||
[200, 200, 20], # Yellow
|
||||
[30, 200, 200], # Blue
|
||||
]
|
||||
|
||||
|
||||
def flash_random(wait, howmany):
|
||||
for _ in range(howmany):
|
||||
|
||||
c = random.randint(0, len(colors) - 1) # Choose random color index
|
||||
j = random.randint(0, numpix - 1) # Choose random pixel
|
||||
strip[j] = colors[c] # Set pixel to color
|
||||
|
||||
for i in range(1, 5):
|
||||
strip.brightness = i / 5.0 # Ramp up brightness
|
||||
time.sleep(wait)
|
||||
|
||||
for i in range(5, 0, -1):
|
||||
strip.brightness = i / 5.0 # Ramp down brightness
|
||||
strip[j] = [0, 0, 0] # Set pixel to 'off'
|
||||
time.sleep(wait)
|
||||
|
||||
|
||||
while True:
|
||||
# first number is 'wait' delay, shorter num == shorter twinkle
|
||||
flash_random(.01, 1)
|
||||
# second number is how many neopixels to simultaneously light up
|
||||
flash_random(.01, 3)
|
||||
flash_random(.01, 2)
|
||||
|
|
@ -23,7 +23,7 @@ def normalized_rms(values):
|
|||
mic = audiobusio.PDMIn(
|
||||
board.MICROPHONE_CLOCK,
|
||||
board.MICROPHONE_DATA,
|
||||
frequency=16000,
|
||||
sample_rate=16000,
|
||||
bit_depth=16
|
||||
)
|
||||
samples = array.array('H', [0] * 160)
|
||||
|
|
|
|||
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