diff --git a/Disc_Step_Sequencer/Disc_Step_Sequencer.py b/Disc_Step_Sequencer/Disc_Step_Sequencer.py new file mode 100644 index 000000000..51229f6f3 --- /dev/null +++ b/Disc_Step_Sequencer/Disc_Step_Sequencer.py @@ -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) diff --git a/Disc_Step_Sequencer/ch_01.wav b/Disc_Step_Sequencer/ch_01.wav new file mode 100644 index 000000000..dc16722ff Binary files /dev/null and b/Disc_Step_Sequencer/ch_01.wav differ diff --git a/Disc_Step_Sequencer/clap_01.wav b/Disc_Step_Sequencer/clap_01.wav new file mode 100644 index 000000000..59ae55fbb Binary files /dev/null and b/Disc_Step_Sequencer/clap_01.wav differ diff --git a/Disc_Step_Sequencer/debouncer.py b/Disc_Step_Sequencer/debouncer.py new file mode 100644 index 000000000..b65083df4 --- /dev/null +++ b/Disc_Step_Sequencer/debouncer.py @@ -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) diff --git a/Disc_Step_Sequencer/fB_bd_tek.wav b/Disc_Step_Sequencer/fB_bd_tek.wav new file mode 100644 index 000000000..89cea991d Binary files /dev/null and b/Disc_Step_Sequencer/fB_bd_tek.wav differ diff --git a/Disc_Step_Sequencer/fB_elec_hi_snare.wav b/Disc_Step_Sequencer/fB_elec_hi_snare.wav new file mode 100644 index 000000000..9dcb7450e Binary files /dev/null and b/Disc_Step_Sequencer/fB_elec_hi_snare.wav differ diff --git a/Gemma_Nano_Ring/NanoRing.ino b/Gemma_Nano_Ring/NanoRing.ino new file mode 100644 index 000000000..f3dd6c947 --- /dev/null +++ b/Gemma_Nano_Ring/NanoRing.ino @@ -0,0 +1,65 @@ +#include +#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= 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) +} diff --git a/Gemma_Nano_Ring/code.py b/Gemma_Nano_Ring/code.py new file mode 100644 index 000000000..64b07d22b --- /dev/null +++ b/Gemma_Nano_Ring/code.py @@ -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) diff --git a/Sensor_Plotting_With_Mu_CircuitPython/audio.py b/Sensor_Plotting_With_Mu_CircuitPython/audio.py index b9c7f4830..b7f957d9a 100644 --- a/Sensor_Plotting_With_Mu_CircuitPython/audio.py +++ b/Sensor_Plotting_With_Mu_CircuitPython/audio.py @@ -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) diff --git a/pi_radio/font5x8.bin b/pi_radio/font5x8.bin new file mode 100755 index 000000000..9a0563ba2 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 000000000..f96b7c7db --- /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 000000000..78d21a203 --- /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 000000000..7d4ff6554 --- /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 000000000..9aeb3f515 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 000000000..973077753 --- /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 000000000..8054e3b8b 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 000000000..f1c05d424 --- /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 000000000..d02c806c6 --- /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