From 718d4e4668ab38b8775af581531bd30a17be8235 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 27 Dec 2018 17:58:26 -0500 Subject: [PATCH 01/27] Wiring checks for RFM69 and RFM9x Radio Modules --- pi_radio/rfm69_check.py | 90 +++++++++++++++++++++++++++++++++++++++++ pi_radio/rfm9x_check.py | 90 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 pi_radio/rfm69_check.py create mode 100644 pi_radio/rfm9x_check.py diff --git a/pi_radio/rfm69_check.py b/pi_radio/rfm69_check.py new file mode 100644 index 000000000..b0bb84bf0 --- /dev/null +++ b/pi_radio/rfm69_check.py @@ -0,0 +1,90 @@ +""" +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 +from PIL import Image +from PIL import ImageDraw +from PIL import ImageFont +import busio +from digitalio import DigitalInOut, Direction, Pull +import board +import Adafruit_GPIO.SPI as SPI +import Adafruit_SSD1306 +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 + +# 128x32 OLED Display +disp = Adafruit_SSD1306.SSD1306_128_32(rst=None) +# Initialize library. +disp.begin() +# Clear display. +disp.clear() +disp.display() +width = disp.width +height = disp.height +image = Image.new('1', (width, height)) +draw = ImageDraw.Draw(image) +draw.rectangle((0,0,width,height), outline=0, fill=0) +padding = -2 +top = padding +bottom = height-padding +x = 0 +font = ImageFont.load_default() + +# 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. + packet = None + draw.rectangle((0,0,width,height), outline=0, fill=0) + + # Attempt to set up the RFM69 Module + try: + # Setup the RFM69 + rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, 915.0) + draw.text((x+20, top+8), "RFM69: Detected", font=font, fill=255) + except RuntimeError: + # Thrown on version mismatch + draw.text((x+20, top), "RFM69: ERROR", font=font, fill=255) + + # Check buttons + if not btnA.value: + # Button A Pressed + draw.text((x, top+16),'Radio', font=font, fill=255) + disp.image(image) + disp.display() + time.sleep(0.1) + if not btnB.value: + # Button B Pressed + draw.text((x, top+16),'LoRa', font=font, fill=255) + disp.image(image) + disp.display() + if not btnC.value: + # Button C Pressed + draw.text((x, top+16),'LoRaWAN', font=font, fill=255) + disp.image(image) + disp.display() + + disp.image(image) + disp.display() + time.sleep(0.1) diff --git a/pi_radio/rfm9x_check.py b/pi_radio/rfm9x_check.py new file mode 100644 index 000000000..c5bf11a82 --- /dev/null +++ b/pi_radio/rfm9x_check.py @@ -0,0 +1,90 @@ +""" +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 +from PIL import Image +from PIL import ImageDraw +from PIL import ImageFont +import busio +from digitalio import DigitalInOut, Direction, Pull +import board +import Adafruit_GPIO.SPI as SPI +import Adafruit_SSD1306 +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 + +# 128x32 OLED Display +disp = Adafruit_SSD1306.SSD1306_128_32(rst=None) +# Initialize library. +disp.begin() +# Clear display. +disp.clear() +disp.display() +width = disp.width +height = disp.height +image = Image.new('1', (width, height)) +draw = ImageDraw.Draw(image) +draw.rectangle((0,0,width,height), outline=0, fill=0) +padding = -2 +top = padding +bottom = height-padding +x = 0 +font = ImageFont.load_default() + +# 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: + # Draw a black filled box to clear the image. + packet = None + draw.rectangle((0,0,width,height), outline=0, fill=0) + + # Attempt to set up the RFM69 Module + try: + # Setup the RFM69 + rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0) + draw.text((x+20, top+8), "RFM69: Detected", font=font, fill=255) + except RuntimeError: + # Thrown on version mismatch + draw.text((x+20, top), "RFM69: ERROR", font=font, fill=255) + + # Check buttons + if not btnA.value: + # Button A Pressed + draw.text((x, top+16),'Radio', font=font, fill=255) + disp.image(image) + disp.display() + time.sleep(0.1) + if not btnB.value: + # Button B Pressed + draw.text((x, top+16),'LoRa', font=font, fill=255) + disp.image(image) + disp.display() + if not btnC.value: + # Button C Pressed + draw.text((x, top+16),'LoRaWAN', font=font, fill=255) + disp.image(image) + disp.display() + + disp.image(image) + disp.display() + time.sleep(0.1) From 4c91773f87cd93479daadaa8da0ebd2db7c759bc Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 27 Dec 2018 17:59:13 -0500 Subject: [PATCH 02/27] removing unused import --- pi_radio/rfm69_check.py | 1 - pi_radio/rfm9x_check.py | 1 - 2 files changed, 2 deletions(-) diff --git a/pi_radio/rfm69_check.py b/pi_radio/rfm69_check.py index b0bb84bf0..4f08d9771 100644 --- a/pi_radio/rfm69_check.py +++ b/pi_radio/rfm69_check.py @@ -11,7 +11,6 @@ from PIL import ImageFont import busio from digitalio import DigitalInOut, Direction, Pull import board -import Adafruit_GPIO.SPI as SPI import Adafruit_SSD1306 import adafruit_rfm69 diff --git a/pi_radio/rfm9x_check.py b/pi_radio/rfm9x_check.py index c5bf11a82..35ed7e7a1 100644 --- a/pi_radio/rfm9x_check.py +++ b/pi_radio/rfm9x_check.py @@ -11,7 +11,6 @@ from PIL import ImageFont import busio from digitalio import DigitalInOut, Direction, Pull import board -import Adafruit_GPIO.SPI as SPI import Adafruit_SSD1306 import adafruit_rfm9x From 8af49f776a36c0535773751e260f18de834c8357 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 12:03:17 -0500 Subject: [PATCH 03/27] tested wiring checks for RFM69/RFM9x on Pi --- pi_radio/rfm69_check.py | 4 +--- pi_radio/rfm9x_check.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pi_radio/rfm69_check.py b/pi_radio/rfm69_check.py index 4f08d9771..8b48cdb59 100644 --- a/pi_radio/rfm69_check.py +++ b/pi_radio/rfm69_check.py @@ -54,16 +54,14 @@ spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) while True: # Draw a black filled box to clear the image. - packet = None draw.rectangle((0,0,width,height), outline=0, fill=0) # Attempt to set up the RFM69 Module try: - # Setup the RFM69 rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, 915.0) draw.text((x+20, top+8), "RFM69: Detected", font=font, fill=255) except RuntimeError: - # Thrown on version mismatch + # Thrown on version mismatch draw.text((x+20, top), "RFM69: ERROR", font=font, fill=255) # Check buttons diff --git a/pi_radio/rfm9x_check.py b/pi_radio/rfm9x_check.py index 35ed7e7a1..7564fdffd 100644 --- a/pi_radio/rfm9x_check.py +++ b/pi_radio/rfm9x_check.py @@ -1,5 +1,5 @@ """ -Wiring Check, Pi Radio w/RFM69 +Wiring Check, Pi Radio w/RFM9x Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi Author: Brent Rubell for Adafruit Industries @@ -54,35 +54,35 @@ spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) while True: # Draw a black filled box to clear the image. - packet = None draw.rectangle((0,0,width,height), outline=0, fill=0) - # Attempt to set up the RFM69 Module + # Attempt to set up the RFM9x Module try: - # Setup the RFM69 rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0) - draw.text((x+20, top+8), "RFM69: Detected", font=font, fill=255) + draw.text((x+20, top+8), "RFM9x: Detected", font=font, fill=255) except RuntimeError: - # Thrown on version mismatch - draw.text((x+20, top), "RFM69: ERROR", font=font, fill=255) + # Thrown on version mismatch + draw.text((x+20, top), "RFM9x: ERROR", font=font, fill=255) # Check buttons if not btnA.value: # Button A Pressed - draw.text((x, top+16),'Radio', font=font, fill=255) + draw.text((x, top+16),'Ada', font=font, fill=255) disp.image(image) disp.display() time.sleep(0.1) if not btnB.value: # Button B Pressed - draw.text((x, top+16),'LoRa', font=font, fill=255) + draw.text((x, top+16),'Fruit', font=font, fill=255) disp.image(image) disp.display() + time.sleep(0.1) if not btnC.value: # Button C Pressed - draw.text((x, top+16),'LoRaWAN', font=font, fill=255) + draw.text((x, top+16),'Radio', font=font, fill=255) disp.image(image) disp.display() + time.sleep(0.1) disp.image(image) disp.display() From 4771530456cba244680770c8c0136424f73a7822 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 13:23:16 -0500 Subject: [PATCH 04/27] move from PIL to framebuf --- pi_radio/font5x8.bin | Bin 0 -> 1282 bytes pi_radio/rfm69_check.py | 63 +++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 36 deletions(-) create mode 100755 pi_radio/font5x8.bin diff --git a/pi_radio/font5x8.bin b/pi_radio/font5x8.bin new file mode 100755 index 0000000000000000000000000000000000000000..9a0563ba2dae1dc1d0b1b7ecb2e54e5113f3f540 GIT binary patch literal 1282 zcmXw3F>l*e5I$10{Ai>OqY^L;uo9&xs-z5NTtlD*ih5KiLlo?$F36^GP|Jyf4E0jD zLuHrZ%h+xn(jh<#Btfzi{RKsb0$utax^(lZ!Ki^k0DC8(cjWQCyLaDxJf5_~fW&+B z;F0H@JUH=8FY!#nObZw6zn4 zjUs@K#rYN*rdNEO1Pkd*mPTsc^S>BBnV1y6d{|k5ZDVrxgKR8=zjT7sOycL8lr6GBq8Oxc(z-zxK-+Mhj)*4rXS~& ziIRIf3is{<)s(5DfD56>lB^Iqhuks)D~cvu)Pulrf*`1)sS78HA_G{e%EsHbKTZTw zlnDe=j{JBBgjNr*o!F)XYfKV~Qm!*Ms#SyTIr-QCQL2j44XQ5ZR$?MQ)8#gIgE}JY zUR+!x!P96r0M^3K1K;57w-^vT*{$8Kxy9G79~at~dya(SQ8|v!{0h?Tm1E>=Me!NG zQT+6@upP(oXdA1Iw&N)J9H5{0Aor&|kopOq;s=<{>UZk1B#Qg=zDbmK zdviD#*lpi0pSOG5n!r!5UQIi_Ua!-^E_K{$R;>=w@cy&A8}p63ncDcr`u)39%^}no zG7qM{Js1o(9nLG~aK5r~I(={b-n7R#eXjlxWKa*xLD)u7-ocauKs%Vu#rfD;6hTA#%t}%>Prt4SAT-VpMl7?3aqa{k4 zVLqUXoV3*lk5&uG7F(QN1fXMU0CVMvP}T_ViUQXNMRL7Zt?B>6U*QUAP+Ey<&~IRl z27O3ULqd9nM;1YJW+XEbeBx1r&Tf+6&^W<-I2>-JvYgM$De7??`o|b>6`oo}i=6Vy zcbD&8n$56j?w(4gyY_Hz&$b7Xf&JT)gPo3tpAk|?lF}wg5R8L>?+*jcgW*2MVp8t! r=UA7qlM~h|w5qNAP4y=Jc^C##(KN7mCP`3|q#~?;uvP#Ug;>IW4$UpB literal 0 HcmV?d00001 diff --git a/pi_radio/rfm69_check.py b/pi_radio/rfm69_check.py index 8b48cdb59..484c46315 100644 --- a/pi_radio/rfm69_check.py +++ b/pi_radio/rfm69_check.py @@ -5,13 +5,12 @@ Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi Author: Brent Rubell for Adafruit Industries """ import time -from PIL import Image -from PIL import ImageDraw -from PIL import ImageFont import busio from digitalio import DigitalInOut, Direction, Pull import board -import Adafruit_SSD1306 +# Import the SSD1306 module. +import adafruit_ssd1306 +# Import the RFM69 radio module. import adafruit_rfm69 # Button A @@ -29,23 +28,17 @@ 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 -disp = Adafruit_SSD1306.SSD1306_128_32(rst=None) -# Initialize library. -disp.begin() -# Clear display. -disp.clear() -disp.display() -width = disp.width -height = disp.height -image = Image.new('1', (width, height)) -draw = ImageDraw.Draw(image) -draw.rectangle((0,0,width,height), outline=0, fill=0) -padding = -2 -top = padding -bottom = height-padding -x = 0 -font = ImageFont.load_default() +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) @@ -54,34 +47,32 @@ spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) while True: # Draw a black filled box to clear the image. - draw.rectangle((0,0,width,height), outline=0, fill=0) + display.fill(0) # Attempt to set up the RFM69 Module try: rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, 915.0) - draw.text((x+20, top+8), "RFM69: Detected", font=font, fill=255) + display.text('RFM69: Detected', 0, 0, 1) except RuntimeError: # Thrown on version mismatch - draw.text((x+20, top), "RFM69: ERROR", font=font, fill=255) + display.text('RFM69: ERROR', 0, 0, 1) # Check buttons if not btnA.value: # Button A Pressed - draw.text((x, top+16),'Radio', font=font, fill=255) - disp.image(image) - disp.display() + display.text('Ada', width-85, height-7, 1) + display.show() time.sleep(0.1) if not btnB.value: # Button B Pressed - draw.text((x, top+16),'LoRa', font=font, fill=255) - disp.image(image) - disp.display() + display.text('Fruit', width-75, height-7, 1) + display.show() + time.sleep(0.1) if not btnC.value: # Button C Pressed - draw.text((x, top+16),'LoRaWAN', font=font, fill=255) - disp.image(image) - disp.display() - - disp.image(image) - disp.display() - time.sleep(0.1) + display.text('Radio', width-65, height-7, 1) + display.show() + time.sleep(0.1) + + display.show() + time.sleep(0.1) \ No newline at end of file From 57e53327785b6786a79c416e0f6e9e395708dcf0 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 13:29:23 -0500 Subject: [PATCH 05/27] add framebuf text to rfm9x, remove PIL --- pi_radio/rfm9x_check.py | 62 +++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/pi_radio/rfm9x_check.py b/pi_radio/rfm9x_check.py index 7564fdffd..7034f12bc 100644 --- a/pi_radio/rfm9x_check.py +++ b/pi_radio/rfm9x_check.py @@ -5,13 +5,12 @@ Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi Author: Brent Rubell for Adafruit Industries """ import time -from PIL import Image -from PIL import ImageDraw -from PIL import ImageFont import busio from digitalio import DigitalInOut, Direction, Pull import board -import Adafruit_SSD1306 +# Import the SSD1306 module. +import adafruit_ssd1306 +# Import the RFM9x radio module. import adafruit_rfm9x # Button A @@ -29,23 +28,16 @@ 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 -disp = Adafruit_SSD1306.SSD1306_128_32(rst=None) -# Initialize library. -disp.begin() -# Clear display. -disp.clear() -disp.display() -width = disp.width -height = disp.height -image = Image.new('1', (width, height)) -draw = ImageDraw.Draw(image) -draw.rectangle((0,0,width,height), outline=0, fill=0) -padding = -2 -top = padding -bottom = height-padding -x = 0 -font = ImageFont.load_default() +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) @@ -53,37 +45,33 @@ 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. - draw.rectangle((0,0,width,height), outline=0, fill=0) + # Clear the image + display.fill(0) # Attempt to set up the RFM9x Module try: rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0) - draw.text((x+20, top+8), "RFM9x: Detected", font=font, fill=255) + display.text('RFM9x: Detected', 0, 0, 1) except RuntimeError: # Thrown on version mismatch - draw.text((x+20, top), "RFM9x: ERROR", font=font, fill=255) + display.text('RFM9x: ERROR', 0, 0, 1) # Check buttons if not btnA.value: # Button A Pressed - draw.text((x, top+16),'Ada', font=font, fill=255) - disp.image(image) - disp.display() + display.text('Ada', width-85, height-7, 1) + display.show() time.sleep(0.1) if not btnB.value: # Button B Pressed - draw.text((x, top+16),'Fruit', font=font, fill=255) - disp.image(image) - disp.display() + display.text('Fruit', width-75, height-7, 1) + display.show() time.sleep(0.1) if not btnC.value: # Button C Pressed - draw.text((x, top+16),'Radio', font=font, fill=255) - disp.image(image) - disp.display() - time.sleep(0.1) - - disp.image(image) - disp.display() + display.text('Radio', width-65, height-7, 1) + display.show() + time.sleep(0.1) + + display.show() time.sleep(0.1) From d4ac5c662f25889ed316a89178e3ffda03be8279 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 13:43:33 -0500 Subject: [PATCH 06/27] pylinting --- pi_radio/rfm69_check.py | 12 ++++++------ pi_radio/rfm9x_check.py | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pi_radio/rfm69_check.py b/pi_radio/rfm69_check.py index 484c46315..973077753 100644 --- a/pi_radio/rfm69_check.py +++ b/pi_radio/rfm69_check.py @@ -69,10 +69,10 @@ while True: 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) - + # Button C Pressed + display.text('Radio', width-65, height-7, 1) + display.show() + time.sleep(0.1) + display.show() - time.sleep(0.1) \ No newline at end of file + time.sleep(0.1) diff --git a/pi_radio/rfm9x_check.py b/pi_radio/rfm9x_check.py index 7034f12bc..f1c05d424 100644 --- a/pi_radio/rfm9x_check.py +++ b/pi_radio/rfm9x_check.py @@ -68,10 +68,10 @@ while True: 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) - + # Button C Pressed + display.text('Radio', width-65, height-7, 1) + display.show() + time.sleep(0.1) + display.show() time.sleep(0.1) From e8245f28c56757dccef5ff73927e911e3f454482 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 14:17:23 -0500 Subject: [PATCH 07/27] switchign to framebuf display --- pi_radio/radio.py | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 pi_radio/radio.py diff --git a/pi_radio/radio.py b/pi_radio/radio.py new file mode 100644 index 000000000..ad9643201 --- /dev/null +++ b/pi_radio/radio.py @@ -0,0 +1,121 @@ +""" +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 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 + +# 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' +packet_data = bytes('Hello Feather!\r\n',"utf-8") + +# packet = rfm69.receive() + +def receive_mode(): + """Switches the radio to only recieve packets. + """ + display.fill(0) + display.text('RX Mode', 25, 0, 1) + packet = None + while packet is None: + packet = rfm69.receive() + display.text('Waiting for packet...', 0, 20, 1) + display.show() + packet_text = str(packet, 'ascii') + draw.text((x, top+16),'RX: {0}'.format(packet_text), font=font, fill=255) + draw.text((x, top+25),'RSSI {0} dB'.format(rfm69.rssi), font=font, fill=255) + +def send_mode(): + """Switches the radio to only send packets. + """ + +def send_mode_interval(time): + """Sends packets every interval. + :param int time: Time to repeatedly send the packet, in seconds. + """ + +while True: + # Draw a black filled box to clear the image. + packet = None + display.fill(0) + display.text('RasPi Radio', 35, 0, 1) + + if not btnA.value: + # Send Data + rfm69.send(packet_data) + display.text('Sent Packet', 35, 25, 1) + display.show() + time.sleep(0.5) + if not btnB.value: + # switch to RX only + receive_mode() + if not btnC.value: + # Display the previous packet text and rssi + if prev_packet is not None: + packet_text = str(prev_packet, 'ascii') + display.text('RX: ', 0, 35, 1) + display.text(packet_text, 5, 35, 1) + display.text('RSSI: ', 0, 45, 1) + display.text(rfm69.rssi, 7, 45, 1) + display.text('No Pkt RCVd', 0, 16, 1) + display.show() + time.sleep(1) + + # default to rx mode, poll in background loop + packet = rfm69.receive() + print(packet) + if packet is None: + display.show() + display.text('- Waiting for PKT -', 0, 20, 1) + prev_packet = None + else: + packet_text = str(packet, 'ascii') + display.text() + display.text('RX: ', 0, 35, 1) + display.text(packet_text, 5, 35, 1) + display.text('RSSI: ', 0, 45, 1) + display.text(rfm69.rssi, 7, 45, 1) + prev_packet = packet + + display.show() + time.sleep(0.1) \ No newline at end of file From 6e8ef8b734bb718d572c52f6bd2cf560d5a01af6 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 14:23:35 -0500 Subject: [PATCH 08/27] pylint radio example --- pi_radio/radio.py | 82 +++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 46 deletions(-) diff --git a/pi_radio/radio.py b/pi_radio/radio.py index ad9643201..476f5378c 100644 --- a/pi_radio/radio.py +++ b/pi_radio/radio.py @@ -48,59 +48,28 @@ rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, 915.0) # 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' packet_data = bytes('Hello Feather!\r\n',"utf-8") - -# packet = rfm69.receive() +packet = None def receive_mode(): - """Switches the radio to only recieve packets. - """ - display.fill(0) - display.text('RX Mode', 25, 0, 1) - packet = None - while packet is None: - packet = rfm69.receive() - display.text('Waiting for packet...', 0, 20, 1) - display.show() - packet_text = str(packet, 'ascii') - draw.text((x, top+16),'RX: {0}'.format(packet_text), font=font, fill=255) - draw.text((x, top+25),'RSSI {0} dB'.format(rfm69.rssi), font=font, fill=255) - -def send_mode(): - """Switches the radio to only send packets. - """ - -def send_mode_interval(time): - """Sends packets every interval. - :param int time: Time to repeatedly send the packet, in seconds. - """ + """Switches the radio to only recieve packets. + """ + display.fill(0) + display.text('RX Mode', 25, 0, 1) + while packet is None: + #packet = rfm69.receive() + display.text('Waiting for packet...', 0, 20, 1) + display.show() + #packet_text = str(packet, 'ascii') + display.text('RX: ', 0, 35, 1) + display.text(packet_text, 5, 35, 1) + display.text('RSSI: ', 0, 45, 1) + display.text(rfm69.rssi, 7, 45, 1) while True: # Draw a black filled box to clear the image. - packet = None display.fill(0) display.text('RasPi Radio', 35, 0, 1) - if not btnA.value: - # Send Data - rfm69.send(packet_data) - display.text('Sent Packet', 35, 25, 1) - display.show() - time.sleep(0.5) - if not btnB.value: - # switch to RX only - receive_mode() - if not btnC.value: - # Display the previous packet text and rssi - if prev_packet is not None: - packet_text = str(prev_packet, 'ascii') - display.text('RX: ', 0, 35, 1) - display.text(packet_text, 5, 35, 1) - display.text('RSSI: ', 0, 45, 1) - display.text(rfm69.rssi, 7, 45, 1) - display.text('No Pkt RCVd', 0, 16, 1) - display.show() - time.sleep(1) - # default to rx mode, poll in background loop packet = rfm69.receive() print(packet) @@ -117,5 +86,26 @@ while True: display.text(rfm69.rssi, 7, 45, 1) prev_packet = packet + if not btnA.value: + # Send Data + rfm69.send(packet_data) + display.text('Sent Packet', 35, 25, 1) + display.show() + time.sleep(0.5) + if not btnB.value: + # switch to RX only + receive_mode() + if not btnC.value: + # Display the previous packet text and rssi + if prev_packet is not None: + packet_text = str(prev_packet, 'ascii') + display.text('RX: ', 0, 35, 1) + display.text(packet_text, 5, 35, 1) + display.text('RSSI: ', 0, 45, 1) + display.text(rfm69.rssi, 7, 45, 1) + display.text('No Pkt RCVd', 0, 16, 1) + display.show() + time.sleep(1) + display.show() - time.sleep(0.1) \ No newline at end of file + time.sleep(0.1) From 06527bf878945707f32025bef6857dedde528949 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 15:41:50 -0500 Subject: [PATCH 09/27] remove rcv_mode, fix display text directions --- pi_radio/radio.py | 73 ++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/pi_radio/radio.py b/pi_radio/radio.py index 476f5378c..82381e22a 100644 --- a/pi_radio/radio.py +++ b/pi_radio/radio.py @@ -7,10 +7,10 @@ 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 +# Import the SSD1306 module. +import adafruit_ssd1306 # Button A btnA = DigitalInOut(board.D26) @@ -22,11 +22,6 @@ 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) @@ -47,65 +42,53 @@ 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") -packet = None - -def receive_mode(): - """Switches the radio to only recieve packets. - """ - display.fill(0) - display.text('RX Mode', 25, 0, 1) - while packet is None: - #packet = rfm69.receive() - display.text('Waiting for packet...', 0, 20, 1) - display.show() - #packet_text = str(packet, 'ascii') - display.text('RX: ', 0, 35, 1) - display.text(packet_text, 5, 35, 1) - display.text('RSSI: ', 0, 45, 1) - display.text(rfm69.rssi, 7, 45, 1) +prev_packet = None while True: - # Draw a black filled box to clear the image. + packet = None + # draw a box to clear the image display.fill(0) display.text('RasPi Radio', 35, 0, 1) - # default to rx mode, poll in background loop + # check for packet rx packet = rfm69.receive() print(packet) if packet is None: display.show() display.text('- Waiting for PKT -', 0, 20, 1) - prev_packet = None else: - packet_text = str(packet, 'ascii') - display.text() - display.text('RX: ', 0, 35, 1) - display.text(packet_text, 5, 35, 1) - display.text('RSSI: ', 0, 45, 1) - display.text(rfm69.rssi, 7, 45, 1) + # 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 Data + # Send Packet rfm69.send(packet_data) - display.text('Sent Packet', 35, 25, 1) + display.fill(0) + display.text('Sent Packet', 0, 25, 1) display.show() - time.sleep(0.5) - if not btnB.value: - # switch to RX only - receive_mode() - if not btnC.value: + 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, 35, 1) - display.text(packet_text, 5, 35, 1) - display.text('RSSI: ', 0, 45, 1) - display.text(rfm69.rssi, 7, 45, 1) - display.text('No Pkt RCVd', 0, 16, 1) + 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(1) + time.sleep(2) display.show() time.sleep(0.1) From 1578c36773701f249800792c613aaf6ce0df1acb Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Dec 2018 17:38:56 -0500 Subject: [PATCH 10/27] add RFM9x example for LoRa --- pi_radio/radio_lora.py | 87 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 pi_radio/radio_lora.py diff --git a/pi_radio/radio_lora.py b/pi_radio/radio_lora.py new file mode 100755 index 000000000..5ce87f25c --- /dev/null +++ b/pi_radio/radio_lora.py @@ -0,0 +1,87 @@ +""" +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 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.D26) +btnA.direction = Direction.INPUT +btnA.pull = Pull.UP + +# Button B +btnB = DigitalInOut(board.D19) +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 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 +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() + 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) + time.sleep(1) + + if not btnA.value: + # Send Packet + rfm9x.send(data_to_send) + display.fill(0) + display.text('Sent Packet', 0, 25, 1) + display.show() + time.sleep(0.1) + 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(2) + + + display.show() + time.sleep(.1) From 3f90b010f5b956763e625bbc8aafe0b874b7c632 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 10:20:23 -0500 Subject: [PATCH 11/27] add LoRaWAN example --- pi_radio/radio_lorawan.py | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100755 pi_radio/radio_lorawan.py diff --git a/pi_radio/radio_lorawan.py b/pi_radio/radio_lorawan.py new file mode 100755 index 000000000..b899b5e12 --- /dev/null +++ b/pi_radio/radio_lorawan.py @@ -0,0 +1,78 @@ +""" +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 time +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.D26) +btnA.direction = Direction.INPUT +btnA.pull = Pull.UP + +# Button B +btnB = DigitalInOut(board.D19) +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 + +# 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) +# Data to send to TTN +data = bytearray(b"\x01\x02\x03\x04") + +while True: + packet = None + # draw a box to clear the image + display.fill(0) + display.text('RasPi LoRaWAN', 35, 0, 1) + + if not btnA.value: + # Send Packet + lora.send_data(data, len(data), lora.frame_counter) + display.fill(0) + display.text('Sent Packet to TTN!', 0, 25, 1) + display.show() + time.sleep(0.1) + if not btnB.value: + # Display pkt data + display.fill(0) + display.text('PKT Data:', 35, 0, 1) + display.text(data.decode(), 0, 25, 1) + display.show() + time.sleep(0.1) + + display.show() + time.sleep(.1) From cf869ceb2683cbaeec7887169f50ecf8c8048aa5 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 11:09:59 -0500 Subject: [PATCH 12/27] change btn mapping to reflect radio bonnet mapping --- pi_radio/radio.py | 4 ++-- pi_radio/radio_lora.py | 4 ++-- pi_radio/radio_lorawan.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pi_radio/radio.py b/pi_radio/radio.py index 82381e22a..78d21a203 100644 --- a/pi_radio/radio.py +++ b/pi_radio/radio.py @@ -13,12 +13,12 @@ import adafruit_rfm69 import adafruit_ssd1306 # Button A -btnA = DigitalInOut(board.D26) +btnA = DigitalInOut(board.D5) btnA.direction = Direction.INPUT btnA.pull = Pull.UP # Button B -btnB = DigitalInOut(board.D19) +btnB = DigitalInOut(board.D6) btnB.direction = Direction.INPUT btnB.pull = Pull.UP diff --git a/pi_radio/radio_lora.py b/pi_radio/radio_lora.py index 5ce87f25c..1a8eb4de5 100755 --- a/pi_radio/radio_lora.py +++ b/pi_radio/radio_lora.py @@ -14,12 +14,12 @@ import adafruit_ssd1306 import adafruit_rfm9x # Button A -btnA = DigitalInOut(board.D26) +btnA = DigitalInOut(board.D5) btnA.direction = Direction.INPUT btnA.pull = Pull.UP # Button B -btnB = DigitalInOut(board.D19) +btnB = DigitalInOut(board.D6) btnB.direction = Direction.INPUT btnB.pull = Pull.UP diff --git a/pi_radio/radio_lorawan.py b/pi_radio/radio_lorawan.py index b899b5e12..24513122b 100755 --- a/pi_radio/radio_lorawan.py +++ b/pi_radio/radio_lorawan.py @@ -14,12 +14,12 @@ import adafruit_ssd1306 from adafruit_tinylora.adafruit_tinylora import TTN, TinyLoRa # Button A -btnA = DigitalInOut(board.D26) +btnA = DigitalInOut(board.D5) btnA.direction = Direction.INPUT btnA.pull = Pull.UP # Button B -btnB = DigitalInOut(board.D19) +btnB = DigitalInOut(board.D6) btnB.direction = Direction.INPUT btnB.pull = Pull.UP From 439666dae29064e9062288ed8d62436f8722b562 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 11:23:53 -0500 Subject: [PATCH 13/27] add fritzing --- pi_radio/rfm69.fzz | Bin 0 -> 79208 bytes pi_radio/rfm9x.fzz | Bin 0 -> 80743 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 pi_radio/rfm69.fzz create mode 100644 pi_radio/rfm9x.fzz diff --git a/pi_radio/rfm69.fzz b/pi_radio/rfm69.fzz new file mode 100644 index 0000000000000000000000000000000000000000..9aeb3f515dbeb323640174d9a340ef88516220e2 GIT binary patch literal 79208 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 QFfHMcLwHvqb~Kj%3sBW_jsO4v literal 0 HcmV?d00001 diff --git a/pi_radio/rfm9x.fzz b/pi_radio/rfm9x.fzz new file mode 100644 index 0000000000000000000000000000000000000000..8054e3b8beb0cd4e1d251b6a4d08cd6a60b81de1 GIT binary patch literal 80743 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 z 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 Heb@g#J^}y_ literal 0 HcmV?d00001 From 44acce69344ef440379841b91546e653fafdec36 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 11:46:15 -0500 Subject: [PATCH 14/27] send pi cpu utilization over lorawan --- pi_radio/radio_lorawan.py | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/pi_radio/radio_lorawan.py b/pi_radio/radio_lorawan.py index 24513122b..72d823973 100755 --- a/pi_radio/radio_lorawan.py +++ b/pi_radio/radio_lorawan.py @@ -5,6 +5,7 @@ Learn Guide: https://learn.adafruit.com/lora-and-lorawan-for-raspberry-pi Author: Brent Rubell for Adafruit Industries """ import time +import subprocess import busio from digitalio import DigitalInOut, Direction, Pull import board @@ -50,8 +51,22 @@ app = bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ttn_config = TTN(devaddr, nwkey, app, country='US') # Initialize lora object lora = TinyLoRa(spi, cs, irq, ttn_config) -# Data to send to TTN -data = bytearray(b"\x01\x02\x03\x04") +# 2b array to store sensor data +data_pkt = bytearray(2) + +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) + display.show() + time.sleep(0.5) while True: packet = None @@ -59,18 +74,20 @@ while True: 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 - lora.send_data(data, len(data), lora.frame_counter) - display.fill(0) - display.text('Sent Packet to TTN!', 0, 25, 1) - display.show() - time.sleep(0.1) + send_pi_data(CPU) + if not btnB.value: - # Display pkt data + # Display CPU Load display.fill(0) - display.text('PKT Data:', 35, 0, 1) - display.text(data.decode(), 0, 25, 1) + display.text('CPU Load %', 45, 0, 1) + display.text(str(CPU), 60, 15, 1) display.show() time.sleep(0.1) From 01ee30aea8da0a4575ab5a0ba6cd8b05aa7f235a Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 11:59:20 -0500 Subject: [PATCH 15/27] adding TTN decoder for lorawan example --- pi_radio/ttn_decoder_lorawan.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 pi_radio/ttn_decoder_lorawan.js 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 From 8adfb4967475ec2085847594284580e6131f38cb Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 12:43:20 -0500 Subject: [PATCH 16/27] add method for periodic sending over lorawan --- pi_radio/radio_lorawan.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pi_radio/radio_lorawan.py b/pi_radio/radio_lorawan.py index 72d823973..0e7625664 100755 --- a/pi_radio/radio_lorawan.py +++ b/pi_radio/radio_lorawan.py @@ -4,6 +4,7 @@ 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 @@ -24,6 +25,11 @@ 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) @@ -53,6 +59,15 @@ ttn_config = TTN(devaddr, nwkey, app, country='US') 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 @@ -65,6 +80,7 @@ def send_pi_data(data): 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) @@ -82,7 +98,6 @@ while True: if not btnA.value: # Send Packet send_pi_data(CPU) - if not btnB.value: # Display CPU Load display.fill(0) @@ -90,6 +105,8 @@ while True: display.text(str(CPU), 60, 15, 1) display.show() time.sleep(0.1) + if not btnC.value: + send_pi_data_periodic() display.show() time.sleep(.1) From e208d61d5a5b5c3757df233c3b97abb5c32a25ff Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 12:53:41 -0500 Subject: [PATCH 17/27] add display to lorawan per. send example --- pi_radio/radio_lorawan.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pi_radio/radio_lorawan.py b/pi_radio/radio_lorawan.py index 0e7625664..f96b7c7db 100755 --- a/pi_radio/radio_lorawan.py +++ b/pi_radio/radio_lorawan.py @@ -106,7 +106,12 @@ while True: 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) From f0fdeb8563e2e71f8a203a94c74a3fb8678dcd6f Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 13:11:12 -0500 Subject: [PATCH 18/27] add periodic pkt sends to lora example --- pi_radio/radio_lora.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/pi_radio/radio_lora.py b/pi_radio/radio_lora.py index 1a8eb4de5..96df4b9fc 100755 --- a/pi_radio/radio_lora.py +++ b/pi_radio/radio_lora.py @@ -5,6 +5,7 @@ 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 @@ -23,6 +24,11 @@ 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) @@ -42,6 +48,22 @@ 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 = 5.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.1) + while True: packet = None # draw a box to clear the image @@ -50,7 +72,6 @@ while True: # check for packet rx packet = rfm9x.receive() - print(packet) if packet is None: display.show() display.text('- Waiting for PKT -', 0, 20, 1) @@ -65,11 +86,7 @@ while True: if not btnA.value: # Send Packet - rfm9x.send(data_to_send) - display.fill(0) - display.text('Sent Packet', 0, 25, 1) - display.show() - time.sleep(0.1) + send_pi_data() elif not btnB.value: # Display the previous packet text and rssi display.fill(0) @@ -80,7 +97,13 @@ while True: else: display.text('No Pkt RCVd', 0, 16, 1) display.show() - time.sleep(2) + 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() From 354e8751a0cacc2298b402b516c49c4473b05b36 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 13:24:35 -0500 Subject: [PATCH 19/27] inc. delay to prevent screen tearing --- pi_radio/radio_lora.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pi_radio/radio_lora.py b/pi_radio/radio_lora.py index 96df4b9fc..7d4ff6554 100755 --- a/pi_radio/radio_lora.py +++ b/pi_radio/radio_lora.py @@ -49,7 +49,7 @@ 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 = 5.0 +data_pkt_delay = 30.0 def send_pi_data_periodic(): threading.Timer(data_pkt_delay, send_pi_data_periodic).start() @@ -62,7 +62,7 @@ def send_pi_data(): display.text('Sent Packet', 35, 15, 1) print('Sent Packet!') display.show() - time.sleep(0.1) + time.sleep(0.5) while True: packet = None From b769fe45ca9d7c7888ee8f5f7ba4c09de2b9d38f Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 15:11:46 -0500 Subject: [PATCH 20/27] add RFM9x circuitpython transmit code --- pi_radio/rfm9x_tx.py | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 pi_radio/rfm9x_tx.py diff --git a/pi_radio/rfm9x_tx.py b/pi_radio/rfm9x_tx.py new file mode 100644 index 000000000..fa746cf98 --- /dev/null +++ b/pi_radio/rfm9x_tx.py @@ -0,0 +1,57 @@ +# Simple transmitter for RFM9x +import time +import board +import busio +import digitalio +import adafruit_rfm9x + +# Define pins connected to the chip, use these if wiring up the breakout according to the guide: +CS = digitalio.DigitalInOut(board.D6) +RESET = digitalio.DigitalInOut(board.D5) + +# Define the onboard LED +LED = digitalio.DigitalInOut(board.D13) +LED.direction = digitalio.Direction.OUTPUT + +# Initialize SPI bus. +spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) + +# Initialze RFM radio +rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0) + +# You can however adjust the transmit power (in dB). The default is 13 dB but +# high power radios like the RFM95 can go up to 23 dB: +rfm9x.tx_power = 23 + +# Packet counter, incremented per tx +packetNum = 0 +while True: + + rfm9x.send(bytes("Hello Pi #","utf-8")) + packetNum+=1 + print(packetNum) + rfm9x.send(bytes(packetNum)) + + # Listen for a new packet + packet = rfm9x.receive() + if packet is None: + print('No reply, is there a transmitter around?') + LED.value = False + else: + # Received a packet! + LED.value = True + # Print out the raw bytes of the packet: + print('Received (raw bytes): {0}'.format(packet)) + # And decode to ASCII text and print it too. Note that you always + # receive raw bytes and need to convert to a text format like ASCII + # if you intend to do string processing on your data. Make sure the + # sending side is sending ASCII data before you try to decode! + packet_text = str(packet, 'ascii') + print('Received (ASCII): {0}'.format(packet_text)) + # Also read the RSSI (signal strength) of the last received message and + # print it. + rssi = rfm9x.rssi + print('Received signal strength: {0} dB'.format(rssi)) + # Wait one second between Tx/Rx + time.sleep(1) + \ No newline at end of file From 4800bd327f1188e5f7ce5eba87ebc0f37524801b Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 15:17:24 -0500 Subject: [PATCH 21/27] add rfm69 tx code, pylint --- pi_radio/rfm69_tx.py | 60 ++++++++++++++++++++++++++++++++++++++++++++ pi_radio/rfm9x_tx.py | 3 +-- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 pi_radio/rfm69_tx.py diff --git a/pi_radio/rfm69_tx.py b/pi_radio/rfm69_tx.py new file mode 100644 index 000000000..f0ce84d53 --- /dev/null +++ b/pi_radio/rfm69_tx.py @@ -0,0 +1,60 @@ +# Simple transmitter for RFM69 +import time +import board +import busio +import digitalio +import adafruit_rfm69 + +# Define pins connected to the chip, use these if wiring up the breakout according to the guide: +CS = digitalio.DigitalInOut(board.D5) +RESET = digitalio.DigitalInOut(board.D6) + +# Define the onboard LED +LED = digitalio.DigitalInOut(board.D13) +LED.direction = digitalio.Direction.OUTPUT + +# Initialize SPI bus. +spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) + +# Initialze RFM radio +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' + +# Packet counter, incremented per tx +packetNum = 0 + +rfm69.send(bytes('Hello world!\r\n',"utf-8")) +print('Sent hello world message!') + +# Wait to receive packets. Note that this library can't receive data at a fast +# rate, in fact it can only receive and process one 60 byte packet at a time. +# This means you should only use this for low bandwidth scenarios, like sending +# and receiving a single message at a time. +print('Waiting for packets...') +while True: + rfm69.send(bytes("Hello Pi #","utf-8")) + packetNum+=1 + print(packetNum) + rfm69.send(bytes(packetNum)) + + # Listen for a new packet + packet = rfm69.receive() + if packet is None: + print('No reply, is there a transmitter around?') + LED.value = False + else: + # Received a packet! + LED.value = True + # Print out the raw bytes of the packet: + print('Received (raw bytes): {0}'.format(packet)) + # And decode to ASCII text and print it too. Note that you always + # receive raw bytes and need to convert to a text format like ASCII + # if you intend to do string processing on your data. Make sure the + # sending side is sending ASCII data before you try to decode! + packet_text = str(packet, 'ascii') + print('Received (ASCII): {0}'.format(packet_text)) + # Wait one second between Tx/Rx + time.sleep(1) diff --git a/pi_radio/rfm9x_tx.py b/pi_radio/rfm9x_tx.py index fa746cf98..5aeac3977 100644 --- a/pi_radio/rfm9x_tx.py +++ b/pi_radio/rfm9x_tx.py @@ -26,12 +26,11 @@ rfm9x.tx_power = 23 # Packet counter, incremented per tx packetNum = 0 while True: - rfm9x.send(bytes("Hello Pi #","utf-8")) packetNum+=1 print(packetNum) rfm9x.send(bytes(packetNum)) - + # Listen for a new packet packet = rfm9x.receive() if packet is None: From afe8b6c308a7b9ed347b133491f854fa13d678f4 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 31 Dec 2018 17:21:04 -0500 Subject: [PATCH 22/27] removing feather tx code from PR --- pi_radio/rfm69_tx.py | 60 -------------------------------------------- pi_radio/rfm9x_tx.py | 56 ----------------------------------------- 2 files changed, 116 deletions(-) delete mode 100644 pi_radio/rfm69_tx.py delete mode 100644 pi_radio/rfm9x_tx.py diff --git a/pi_radio/rfm69_tx.py b/pi_radio/rfm69_tx.py deleted file mode 100644 index f0ce84d53..000000000 --- a/pi_radio/rfm69_tx.py +++ /dev/null @@ -1,60 +0,0 @@ -# Simple transmitter for RFM69 -import time -import board -import busio -import digitalio -import adafruit_rfm69 - -# Define pins connected to the chip, use these if wiring up the breakout according to the guide: -CS = digitalio.DigitalInOut(board.D5) -RESET = digitalio.DigitalInOut(board.D6) - -# Define the onboard LED -LED = digitalio.DigitalInOut(board.D13) -LED.direction = digitalio.Direction.OUTPUT - -# Initialize SPI bus. -spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) - -# Initialze RFM radio -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' - -# Packet counter, incremented per tx -packetNum = 0 - -rfm69.send(bytes('Hello world!\r\n',"utf-8")) -print('Sent hello world message!') - -# Wait to receive packets. Note that this library can't receive data at a fast -# rate, in fact it can only receive and process one 60 byte packet at a time. -# This means you should only use this for low bandwidth scenarios, like sending -# and receiving a single message at a time. -print('Waiting for packets...') -while True: - rfm69.send(bytes("Hello Pi #","utf-8")) - packetNum+=1 - print(packetNum) - rfm69.send(bytes(packetNum)) - - # Listen for a new packet - packet = rfm69.receive() - if packet is None: - print('No reply, is there a transmitter around?') - LED.value = False - else: - # Received a packet! - LED.value = True - # Print out the raw bytes of the packet: - print('Received (raw bytes): {0}'.format(packet)) - # And decode to ASCII text and print it too. Note that you always - # receive raw bytes and need to convert to a text format like ASCII - # if you intend to do string processing on your data. Make sure the - # sending side is sending ASCII data before you try to decode! - packet_text = str(packet, 'ascii') - print('Received (ASCII): {0}'.format(packet_text)) - # Wait one second between Tx/Rx - time.sleep(1) diff --git a/pi_radio/rfm9x_tx.py b/pi_radio/rfm9x_tx.py deleted file mode 100644 index 5aeac3977..000000000 --- a/pi_radio/rfm9x_tx.py +++ /dev/null @@ -1,56 +0,0 @@ -# Simple transmitter for RFM9x -import time -import board -import busio -import digitalio -import adafruit_rfm9x - -# Define pins connected to the chip, use these if wiring up the breakout according to the guide: -CS = digitalio.DigitalInOut(board.D6) -RESET = digitalio.DigitalInOut(board.D5) - -# Define the onboard LED -LED = digitalio.DigitalInOut(board.D13) -LED.direction = digitalio.Direction.OUTPUT - -# Initialize SPI bus. -spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) - -# Initialze RFM radio -rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 915.0) - -# You can however adjust the transmit power (in dB). The default is 13 dB but -# high power radios like the RFM95 can go up to 23 dB: -rfm9x.tx_power = 23 - -# Packet counter, incremented per tx -packetNum = 0 -while True: - rfm9x.send(bytes("Hello Pi #","utf-8")) - packetNum+=1 - print(packetNum) - rfm9x.send(bytes(packetNum)) - - # Listen for a new packet - packet = rfm9x.receive() - if packet is None: - print('No reply, is there a transmitter around?') - LED.value = False - else: - # Received a packet! - LED.value = True - # Print out the raw bytes of the packet: - print('Received (raw bytes): {0}'.format(packet)) - # And decode to ASCII text and print it too. Note that you always - # receive raw bytes and need to convert to a text format like ASCII - # if you intend to do string processing on your data. Make sure the - # sending side is sending ASCII data before you try to decode! - packet_text = str(packet, 'ascii') - print('Received (ASCII): {0}'.format(packet_text)) - # Also read the RSSI (signal strength) of the last received message and - # print it. - rssi = rfm9x.rssi - print('Received signal strength: {0} dB'.format(rssi)) - # Wait one second between Tx/Rx - time.sleep(1) - \ No newline at end of file From f2b1be81b9561e5beaaf42c16559915d0a3aeb3e Mon Sep 17 00:00:00 2001 From: vgoodwinv <46117260+vgoodwinv@users.noreply.github.com> Date: Mon, 31 Dec 2018 17:28:59 -0500 Subject: [PATCH 23/27] changed frequency(2.0) to sample_rate(3.0) --- Sensor_Plotting_With_Mu_CircuitPython/audio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From 5abfa6afd6f9edc304f409cdd9555e6ffb326e86 Mon Sep 17 00:00:00 2001 From: Mike Barela Date: Wed, 2 Jan 2019 09:41:53 -0500 Subject: [PATCH 24/27] Create code.py code.py for the Gemma NanoRing by Amelia in the Adafruit Learning System --- Gemma_Nano_Ring/code.py | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Gemma_Nano_Ring/code.py 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) From 96ff73e04c7b70ded06666471196c8f1f459ba91 Mon Sep 17 00:00:00 2001 From: Mike Barela Date: Wed, 2 Jan 2019 09:50:05 -0500 Subject: [PATCH 25/27] create arduino code for ring This project may be coded in _either_: CircuitPythoin, Arduino, or Microsoft MakeCode Maker. This is the Arduino code. It uses the Adafruit_NeoPixel library. --- Gemma_Nano_Ring/NanoRing.ino | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Gemma_Nano_Ring/NanoRing.ino 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) +} From 066f8b4cb34663b0d864777f0818b585bd9c0aa8 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 2 Jan 2019 11:09:12 -0500 Subject: [PATCH 26/27] rename files radio_rfm9x, rfm69 --- pi_radio/{radio.py => radio_rfm69.py} | 0 pi_radio/{radio_lora.py => radio_rfm9x.py} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename pi_radio/{radio.py => radio_rfm69.py} (100%) rename pi_radio/{radio_lora.py => radio_rfm9x.py} (100%) diff --git a/pi_radio/radio.py b/pi_radio/radio_rfm69.py similarity index 100% rename from pi_radio/radio.py rename to pi_radio/radio_rfm69.py diff --git a/pi_radio/radio_lora.py b/pi_radio/radio_rfm9x.py similarity index 100% rename from pi_radio/radio_lora.py rename to pi_radio/radio_rfm9x.py From 4ed8f3483df8c7474fd97ec0640860006ec901b9 Mon Sep 17 00:00:00 2001 From: John Edgar Park Date: Fri, 4 Jan 2019 12:54:17 -0800 Subject: [PATCH 27/27] sequencer code, debouncer, and samples first commit --- Disc_Step_Sequencer/Disc_Step_Sequencer.py | 145 +++++++++++++++++++++ Disc_Step_Sequencer/ch_01.wav | Bin 0 -> 8422 bytes Disc_Step_Sequencer/clap_01.wav | Bin 0 -> 14286 bytes Disc_Step_Sequencer/debouncer.py | 96 ++++++++++++++ Disc_Step_Sequencer/fB_bd_tek.wav | Bin 0 -> 13274 bytes Disc_Step_Sequencer/fB_elec_hi_snare.wav | Bin 0 -> 13290 bytes 6 files changed, 241 insertions(+) create mode 100644 Disc_Step_Sequencer/Disc_Step_Sequencer.py create mode 100644 Disc_Step_Sequencer/ch_01.wav create mode 100644 Disc_Step_Sequencer/clap_01.wav create mode 100644 Disc_Step_Sequencer/debouncer.py create mode 100644 Disc_Step_Sequencer/fB_bd_tek.wav create mode 100644 Disc_Step_Sequencer/fB_elec_hi_snare.wav 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 0000000000000000000000000000000000000000..dc16722ffdd32ea0ba29631ceccd7c39c55a6db4 GIT binary patch literal 8422 zcmeHLX;_ojw*E2?WPkukm_u;Zj1Z6*Pzw$mMJZZr>!~&-VUQs-34>PK+Urn{?deg` zsvWFHYwJ+2M?0#tYL8e2vB-=-m<(hhAqkm>n}C9}dLHg+?{n{SACo^jJ8Qjbt@qt~ z?fre3X^R(kQUGAh!mLHvg)#~O005BpOU(j+)UyBp2K>DFtW<#pp)oM4_D=cRG^Z_59v}S^x}tLbtO`r#jpmo&ch+^xpBLGF zn3y|QLTK&{w``kn;=w2AFJbKVZPZ=RGV4|tZ~8kRovXHf!IZwXeMyY_8~j}4_25;t zugy(RL`PEe8Cbe0g%nvkYlgqQQA1Bj`TU!(KNC)Od^jZoJk7BU2}5T(+3jDTdKJ9e zn%F$t{k8=l4}D9s!gbXcPq+ZogKL89&I70_-JGDjx;;~_m@?h@*z^AD3>i2-YoiN} z+~c|9hjIl+C~s{>Et*}?L!~S;ZGoS#^wM8F6(1kimB!j)(BWsJPbolC#rG}2w_6LM zp>Ve;!I(k8${ADI1^^_D05!I1t${1ReRq|SN1A&fwYaN@0}&C`tMR4E=fnFP)o^-4 zSHz%s&&-Ou)6{2U{25>4rv5c8moYufULe^c3PV;5UN{+8$v;Pv_a

0Wnl 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..89cea991de56a902468693e07054bf11e410d301 GIT binary patch literal 13274 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

*ZU)`xywMqw8?qbB9+DGW9Ml#}62u(n9#DGC z{aXLk=qoT^ZQptC0dKm?o0m#G8r}KbQeBT+6r8>~Jhppdn`zx;sbFzrT4OR}n52j#ZrBxJW^5@N8U<)ywyK}M=Y*n%-cCc!4p zj*cex6L!irX4dML6BguW4X61gFOO*sdky^VjqTFyfVPx3Nj1pTR#uT!d?^hob}oEV zAe7ghGn{=blPsMxohqd;IUaY;B(HPF?c7+kKaYT853s zFHRz+PG%J5!xj^kA#0NxZQG5zhy%~#8>iP`%ZQigN#GHY3uzg79F;aLhW;LtBx@o2 zYc3w%FZ^ag<05|I!;-IMXyn}#rj@R$zEDrmiqY}Z^Dz8jY-0NEg13dP)v`^xotcBD z6Pfd&YsGGUYYNGF;FP(fh3(sb#5tQ=p*V0={jlGZF|-t*HqllTjyOXRoz|r zs649dSBY)0Tj9f>6Zy`0H*-gFlC#e;6*BkI9nxjfq*M2jpCl_Jr6<}YawiskclxgP z-Ta&MxAgd~_{jJ>@g(sd<0-*AH9x*89{6VV&HbATSjnUbFA{DgGA2sO&8xr$^Oo|C)SmLe)uWn|$g}sb1_TW{ z4YNbQON=6MA{U_yr}m?5qgQA2Vm@I#VSmKA#+}cb#osIVRk&0%SlnJRKssEuLyk-# zS@DbVOI12`9?jQUvO0!(FZ7KKVMeb_xXp4dw3y$rTb^}FXs z?}zk#?F;u=^Re)$@MiUX=tbZ~by?z4lxK!VqBQWJKt~DezFw*-=XIP6!Gf4fRYJzgIVj6@(o>rDb8Y6KaMj(n3Y8N2j zZ|2$H^5Mv0yT#(di4MYamZxy=N6C-;cr$1osZMk(<@) zwX1KIuPt7l=bSa0*`1P}M2u~Z91bA{Hu_F`xVi;9)!SWLpEp-EPSi`++0=wq%~fcX z7nhQkJStlJ`A@-S-j`hQA8Xl>S&o^s85HSrsY59%$#Y5YMBYS`gpc3XzNvmojwg*T zjN^}k#(Kpn#iC={V=7`&WAbBaVg_PPWB6lV$4a>>hy$rsrknDtFg_p3Fm6RJ)ZdOIr*wkU_TN^(& z+qNpSGjy(Z)%6theH!>{=>Ev9vC9+gQ*P59P`A0@g(pj)E17HQ8v|R=owGfLL*Zl7 zQ^((T;i1S3bPKRcNJzp*W=Ii8^%qStT_3{?6A3FFyCkP6w<)g+zo+0eVQIe1fn$p^OxgK8Ja658e^(ggxcj?+?TCaYutKMWj?|cY+pZYHNO8MOeakJn@c7^kb;1%vG zY*)7YhW#S^to;c63VbzvdweeYw0kRg$9o-Jmc4xc(s$1Zj}3P!cWO6=i&U-$&eKlS zj*$*#_5yZYHt($Eta>f3n-g95U`k^0&4|qKp8lS$qfVg~mF5lgT2%@aOQo+0tMdGE zmNGA-S|xsoaf|8;`v|_|FXM%BpK$VUh_MB+_%nTBNT+L|nWiG3BqmoS)g`tkybnA< zXChbc6iireL~Wz40!#p6XSg{?oE3I_9M z@=kMwa;<(u|OifIElNJyP;#xw$v;-1AinPf3N7NL{=%(Jgu#(qiOJHtZ8CyxzRe^X3|mLDcGIUBiQ$?Uu-aKNPnb# z^z!)j#JefB>8ct3SztbI!F6eOId9cyonSM4%VFnWw`%{|A?b0$$+a^Y*Z}-7QWg!v zBoO!$F_4UqekHf3q@*6Ec}WLhpkOLszQ-!UKEm;ii;riV_dY+TV40AO$d>3`@!t}0 zQp_@6WEthZKxh>2DIF-AsaC0RX*|^I&=S(Qsav2&WFT#L&nVfr!vt+gc|qD-$->G~ z-^$cl(MHCW*>2CS-agF1)se<&$mymtg-fZ6x@(QA>BS!xh25UIO}dG>2fL@bPq+gf zj2@yMsvdG4QXWhmTka$7QSMIewC>Gr*W9SwK3?RznB>as`pjj=+0OZ`(~={v;}wU0 z>?`a>ZI^8bZ2)VyCBkCW{MUs%vrnczCSt~L!yg8B^%?bsbna@CX%%Z2ssB>-Q`uFz zuDAiYDZeUfEi)jcBAFphE_PLCj6;e20c$5S6O#)=5#1(@8TALs zHF8n1CnP0AOoXbyJM)6N{dbNYGX=+TRl}>Z%tVBy(-B{ zii-WRp3CklBjJyny%)Ctgthy}I?8EG@ zIo3Z&ayxTl@3uJzZ6%rRw7gLuAmWq_=m3vgYuFS34t7ffrulrKJ+o03*u6eh` zx~;UGyYp2SVb7!9jlO#WyMqshNk*TKaZdc4l>W6e?FOZrOPSYS99nv?!nW43?!AfF zD%&yLJKj$`G&~+Vd2z-ABJdWH8l8>tA~+_DBfdZiCyS&|p_-=-r_VDQqHIAf_deCP^**N@iNtKt3L_tzfP6L3va~Sj|N}LStBS zPm4oGUiXsT75%#gZw=oW{R4hiziDb?W^qB(oWNqpBH7ZxO3Zq|`jL&K?Wk>#-HF{> zdkTkeha(4f$5BUCr@KxgP9)AI&X1gvojaXRoOhflU1(j9&M4;&=OO2B&exnF&Ie8z zPEJmAPWg^%j)M-)4!`Ve?VIhS?cUq&*+6XKtoyAvt&A)mS!9@ZT$nREGG#EOFp)B* zHKH`6H(1bH(5=?_pdF&6qe-SQtQM{6s=}e%r}$EV53(TlK$cIYU&=v}Tq0CVOtep#r^=S0q;(phz=}zC4;pV`)!`jly)#bg#&;{=K{8q=}4XlZ+ z&aRrMWT=#_cu-zc29z0;#+R%X+ZERo2^4)P#Qc2slkjI+fkHuj{=Iyr{Fc1Oc`|vl zd40Lrxvz3Pa-DKba&>brsRv*~?vVM|BraT`yE zYv(^*)!oFsT77T(M+Vr39t{tUaE(11U!5?TD*VMZ6As;)^_%Zl@LXzG)?fX(Cb^Nn zDYc!tBeIvh&wrSABz*GxRN(gq7!Bepk{10A!$goq$Uz)K!bw&}E<~9}B~DXAD@5PQ zAj(wCti+nc#?2ANNyL4PXPQ@=KTCjI$V<3egjejAc)Nszl!0`S%%-f6d;la_p+%8O zSy;tN^@duwda_2fW|LN%cArjzZl7M3eyYLWhS!Z$jrmMgOwvssnu%Rlxe#w|Zn0ny zZYgAyZ>3`0WNl_sZX;qFYKyY9w#&9Vv(vGEVqa>%Z%^g`ad36G>~O>3ro&$jUJiB+ zx(<8}C-#l@q4qZRfPKB4pBu@o7?Mtf;lB{!j^2Hc_HcoPd0j_mtz19gz-` zGL&2sj}y}p-4}i%q$>D}|27{zZwj|9*Dyy2J1tu%iwtuUqdvn5T_7!-I+{v^vXk6{ zY?yF8;zvaGJuy%bgw zRbpPURh(4pS1eMzUG$^qQ;}nlU6EW7YY{;aWf6T5aS;bNGAr^ciYh8CIxONUzEzxG zOjzPjl2O7~db@PC)V6H0%(}dt znw48*TIt)!+sQi!I+2~^-K;&ry-Ix-`@II<3}y|D4j+z)j(Lnfoamd}nUb5nGm`;5 zn^l>Aw$QT3wtQvf`zmbBb|Yo;WXpUfb9aBw<{;tl^vLcc;}m&j1j~V+A)HWoXac~G zpq!AI*pH-(l%4z$MLVT1bp*{gtvvm6h6P43=7%g}tSsz~966lxTx>i(ya{|m{N#d) zLf3?&MA}4G#0VwCC5@zfq(fw0%O=WY$>&0TDAX!uDWxhWsYI*ZQS(yQ(h$`=(VW&w z(+7o4Ll@-DpP5ga%UV3O zXtp4-G_bs9`N49)a>bI`ip@&c3Sy;fB@JSe&Fa*0-Llj&&eGRX)^g3Fz{1ah)8ePO zpE>-((+ffuip*rq@=QfdqfAi7LB<0{Y(~!vTMVcStn{PxdUP>5ayk~;54ApPmS|L{ zFQ`qa9;<9CZz`=QPAGIh%H%WU!ev8bOr#~G2qdB68DcL*wM5v2p@MM&{``D=t32`C zj$E9awd@bsAgqhb(M(2+2>KK{Pg)dpHI)Y?J4FYXFR3iaAkh;-1%h78d$bg41@Rg# z0N%M@Pt{M3j#3Ye4v6-%cLR2~x4SnZHcZwT*1A{Hmc5tM7k|$W&1KBKhFZ^PPK*8` zm^zr~8E+qJ7)=^!7)~3?9?TkO>u>Js=>6S8*2B^5*yYn1(b3+1+9uW(+?v#K)U4F} zs%frKy77C%VZD3(P@PF#eyv7rL5*h3X!Yf4pgOWjy=tNIL#2Kts-mIdPK84SSH)!c zV0m(RX!+mep5a0xuf}Ui)JfrTY1}ucJB`DPNuH;uFmfK zo=?5+`tJ984)_h)3|$;{9B~;98FL$dHSuin>r~aRzUhS-43u}yc;0^@Y%zancKK{Y zW6g2>@kZn3_Lk_5=5F|2>Hgk<#F6cB!b#mJ?2H}e4o^gsBhe^zj31CkFh|HpY(Vmw zw1MoHT!PYz>N9m04JjQPy(>dJV+j+S8N;H%c9H!NM>1y#R~PpN4}$lIPeg!CP+3S) zSVaUPDlDcdP9niAc`UglH7i{%6D#|-oV~m_ghio6AxZJF5=41Vxm@L{DzVzMTClpD zMwN!QCXLotEkW&OZ4I3f9S_|ST@$@3J!bvS`rG=K4Dt++23HKD4R;JBi~@{ujCza^ zM#9E!#-7GsjgyUYjBAXWjk}HOjWdn2z_FWgfHB0F#&`zYdD}?IXwNXqFxZgDu-d@T z05Ev3FQuQYr>WPZYoObpBchY9O{V=(t54HZGg1SluCM-8ZCq7Q)k7shc}5ANsH5nm z@B~sU|4VLBmR6QoMqOH2%1P2i!c+XR*iBJ)5f@<}Ap=1*0eOC2J~G~8?oqBz&QgwW z_WNv(timju%)5-e46*bt=xk_}X(*|uC~GKQkl!TJA!Q`lCF&xKCI|$KFpTICWGf;R z?gmr*eR>K#Njv^<FZ)cBU&+YD>E~&1k zovR&I9hL1e?b&TKZEspRTEkixTMC=intwIjZ$dY=G`ci$G`2RpZqRQ))c4natG{2b zQqNycRKEcJSF5V7ur3Saw7Q>lO?6#$b9L}K{(Aj-pZc%$z4hpNqlVCio(AT|%Z){i zWKH*)I-9hclbV@Zp0)gLx!;OvebGkR{=QwUBfG=8lc+1K%c6UtJG#fJ7u8$X=i9G7 zus_f;_-4p;SaO7Xv}3es?9;gCgxjRrl)x{FX`-3MnK5YJZ0B6veC0yrV#QM4a@I=o zYVBI>`pCu*i0!rQlO57MwtcPx$wR}V%f}uk4^N+*MgES1{eZV1rjYX}G@29OCQu!*EL+g002n^T)tdr#|^R<_nlEekCcttHI@ z%@9p4%~6do4KH})tYJggzDwAryilj=FvW{|^lB&`>MNY-L3Q&k8qEWNC!OsO=Hw4zkFAe)l6B-CXlV|w%#<1hcI zucNRL{gK{bf#J_X2ZJGl3j-blzxw_A$NFyc5%xXl73)pxvFTaw4(}H49_b40lIYs( ztn9St6ztsTDCl_6q1_?VfoY#@uWiq7k8gk8{-XVQyI=d`_P^WzX@AfY-%?`i5`?G5Wa=?&_e?Q`hg?sprQ z8Mr%$9DF*&K3qC%Iw_-^tmb9CtWXxQ@88xPy7vc}IDl^U3p1@V^#N66_MZ zEkr5&Q&>S{Sj10sUG$0Ak=PsYQ}MqgjwEhMj!2qFRZFo*Ka*aTR+sr8vngXK8zws? zD3|GDM!eI%7AB_`D+ z=`Oh~@mPXNB21hG{M0Nc7Awjw8YMz0@=|zDC`f2fP**TlfK}ir|16&gUn(yd?-iaV zZf@=eT>YGaoKHCh*hSbMuywMsv--1CFcUG`FnwU$WsqR_i@u(YhR%vMiDr&kk~)a0 zh7wL;NfAX3B@-dLLs~;ZKw?K6Ni<6+On8%^0w4k|U=q=@C^=LJvJpXzaE0f<4u2c{ zjy+pE)jo|lSvWR0jy&2rG(P-sKzwj%zh#eaFKqW<=i*M!He@?%i+w9{lVtPB#_9Ug z^|Q6-You!tt1PRTD{?D6%Z|&3OK+AWm#P-8FJcxd7MvD{7fR;+=b7hw=c49x=1At6 zXP?iS&$7-gLVrSEK`%ljpp4MjneLginedr=GZ$y9X4GfIW&~zfXXs{VW+-QQgJTo~1K)Io&&|A>2&>rX>RC?B7He$AU7B#CncWbV4Zf8z= z{@#4gJn4e#Lej$Cg7)Hv#RU+xkxNTUn#!xCZC@aOPDxG!Q9VTLS2ile@wDA0G%t7vOXD@GFd z4iFODAebaDB+MgZAbLzRPh?JGEwKc;J?OQgF^XHLgMcR<@l8%G;J zt4&KoJ4;hY^PI+lhM#7Ox{f-G+KF16dXK7^DwN8dN|NG*L`Y6JMUYGIn82QZmjDj514+Ogzz7fowlV#fM9h7R zEk+E3M$e#&(2?i>v_4t@jX+JIN>S0MnR3qgPcGXA>)ycke*0Gq!5xGxr3NN z)F5&Y;fP0w%LogEB7zsJv19lOd=Op>FM!9vBjAtV!EiUYHC!Jq2bYAi!s+0I@ZYc< z*eYxiHVW$isRC9B%Z25^l3}T^SXc}!8WsWj40{864|@v>1Nj{+6nut(<1lbF3YGxw zNP{JTCvsqA;OW|brHsMGV9OvK!p>lXaB?^^oEt6#SAr|UP2g7Wi*P^qP51+NC_ECL z3eSL7!W-dz@LBjG907;H*$~VKS%fme5Mht-LR?2YLA*i4BhnD%h(^R9VjjH5F$fYQ z7g7YNgfvB3BYlv!z$kn~Mk8~P707nvC~^^bfW#o_P@E_!lnTlW<$&@5P5|k0V_2Q zNC#4Y9N-6#50n7KKov-}Koigiv;kc}C(r{70o}kapbwY^#(_xy3V@drunf*@fiv5{ zBCrl@fV2+mg1irG0(-y?$a`QP%ZK3n5%@d;M_4`tX&*TFm$56`;CKhzvj_HeLEZ-C zu7jgxkQc%J3a|>&5;$H0#|ywb$WUMov|%j^AiV@UI5sJ0RG_EAEZFwDo6ofwgZ97;PVnVx&-)v>^2;l>028bbsiF(d#2L;PQB*cHP6 ztP+DeaI1gLp+K29$$0rVX(&)48q|f=fMu*stOV>VP9p9kco^J+o5RlI87~!YFA;bi z$LRmkh?R?#dA=X75$_w`Yn&}OZCFX?5y0y|pT*mR)sB^ewI3@7Zy#<3H^OQ@_Z@oz ze;T_E{CfuH1wMY*-FQ2&F~a`gto^fx_XD@~r#D!+cnN>ng|i@qZfZ8qPlKZ*=i7`?H7Bij4%$Z`|`we{oU4&EP!2ox$0D?iKQoE< z{?8}gf^+=fd^yJs&Rcx@zaxN)9@Z{wb`W6IVJiU}6I_e+0f#A^E$IL3LjDJXcuR43 z#OlQ}4sEy*Rt9zl{tutG^X%ZFfzyRs#n%va1v`Va@4u@QZ#6E$IQh7p=QW78AFuJh z>k}^-e-Gey4I;HwK4>+=?C305{% z2QE@r88~#E--KA);OYin+qmpvZNVZFD+51+yZi7N!TW}ljf)B17wi~Uz5k7W96tX0 z7R6eKw*Zf#|Ecl(hQQ_i+zUL0@%r!@{u@E~*x_P>w;MN$*M)nh;4AqYk@zhCiA9_Q zJUafwDPGh04jgu{T5#CJ_5R$4--}I5GPT<-C5u##}+&+~eIW8g50yYX<@z@9tThVA2K@bYkDT%F)6>pTWH zU-5hK&;RR+i;5@`d40rG1;)ILvpBCX_ zjJF!=C2ke(&7b!dHX7$S!R^GJI6w1e{_u9;tLywE-sb-cNjOa4e8J-dzaLk%IJr1~ zuzhT;<31%}qk;DjYZX3AxZL7$jy-|T0q$Lc9b++sL+km?fxkWQxyPgI9B+6z=NZFV sg@1qId-#gRjqz4seLs)-xraC_aC@NRi%q2Lb5_BBFqFkWL7Y zkc9Md{chXLck8;}p|9`ex7pp9XP)Q({GT#=mvn3U*=L!_0Q73sv(<>PlM-zJ02ug5 z>Ip#0V*nsv1H%SS8hj-n(;BviaVQeGD4O~Vjz)u-UNBD@g7;Gt_qD#3zBLlaR5=4$ z^iJ+59fD#p4ep4S-R(Wo@G(?@FL55m-%u9a9`=8zMc|SDIXVD4GZ|zXeT8a z64l4VNvW^zrtV3LyxacRwWuW@N3(nVz5G4Ijqfl0@$JcrKNOv%UiB$xMmn4CHyqqG zx9#DojQfYY?cRExT|#JanG%0S9al%g)5h}#HSM^$T8jOW>69h4;^$E-ouhp1t9R)$ zrAJ>=ExBRTS$`$qlinrPNjh4!UGlm5ubX#iy|u%TwjFAu8s;WVNnTnr)>i%JmHF$c zPBDLP`IK6&n}G*QfBLF8I_I^?&CW`BoqwfhWtZ=l9=epV0Kal?^1SxXgwMsbMZNQ% zuH8I#*7zhgm1{8N6l)ExQG z3NIV4jew5Wch_7sspqg?_#Vr7=2gY{H4ZggQa!hFpGGU|)6MQQ+?w2?G=e!?)fN47 z{K?4OWj96qOr7w)dhzt;70)?o+@E_6kW*DlM`XvJFMfQoco&=tXOTAgCn06S3%s-6 zgmPn(Dp{&mH2{9kB`;1M!voKe#T|`XW$2Cy>?;7}YkKZnh+!B5{L}v`q z?JG0B+}zly`gO)Fy4kRet4d+#lBB$}$J=xDsdX+bxj)I%GcG4&N%U+}6MoChz31<~ znpYgn#gIA{s?LBoQwDRflBjOVcUrt~#(I~n^`&86{9e)RR;ZwnG;BvusAy@e%b;=6{nFTMU? zkk@JL@4n!#g@?U4ifdQA6;hn$y1DR??!At3zx_4u1a+?d?goyUQPA={-jyY^weHl{ zPv{?8q44324gAa+?`oW*x4M0{RrD`%EEubAtcwll7JokGtnH$)*qTb$kOnx%rGvE0 zyPrI*E#j(ID*eos2S;;b*^p6h9=~uFmy4ZWt$F3_q*WFA>KZ#k zBQ|o?bCYwn=$~2g4gD+$x=zfooPmWO!@8bnA-}{9vNjVt%a06C5in*NN~r^HzR2C^ zUCM1Y{ZeSPFSP$|cjeT{-;uNR$@a%f-aGs`aCq1hZZ3P){jM?@&74-kwgkt&DI)CP(Lpbm1d$Db*ZS zMi%oK%LN=462jHvlS{T`ml%r7L($V)1*zBNex`e#?A-5+O~DT7xvPa|U+y27*PI{w zj@gY4udBEG(owEBDx1$-1fvlmYw-4UHPWD zA>rYBsQcmds=ui{DRwUNX?_`>A>w|_*_dBUN(5?;4>aQy9?_9LU*LY;(SJH*-IFIUvIef8bsUOT|XqG()+l_r?{% zesEM8WjkN~^Z3q&^1|#QN8W)K^s`d=lX9yQhWMND{n78G-1~)@`L3bX5mt+Ch`(x4 zb-9}HEv{1X3H-jo_VDHIUO9)@1{Drfcp1N=f~(r$%9oA5mt67o$Tj1&Y_HJgvFAfy zi^Cvg(sSMM%bWvwcXgX8c8r>4KI;j|{W$&B`*8U@mE!FoT+P~*jmUc4hEn76`ur}3 zBljFXjq@8Wc*EX_X(8#u^5*%k=)RG2^>jpeW;7*&y?Bt=$L;kM`?gT+bVY{R@mJXF zvW==m$Lx<7GYmc^#3)C{SK zbk7q(`k{8rp9UjpR(d%l8 zOe6A9(RfF7ZnyiW{Q;^{ywV$Qz3MJwAH?@AU6|o}&@6q4w~1+xX|C_L;&QIfgciC+ zhD>)I*Gc_&>3iR7YI;bcP$FVqW$VJkGnU#WLnLLaD>E@2Vjt@sv0H83BZ=X-p*PwV z{w!>g=P8pEKHU})5+c^~T%bBxukm!ruONpS!Ig!h3R}NzmHS2Z30D_+DYwb{5jlg( zr9VqQ;*N@58lDiDmY4i$hj4{EOHP$gg~wr^s1DY}qEtv_%td$0EVFGUd*37#%4yyC zPE@3@UE(b3E14p*aY(kwFVj5*Z$W=@05tU;_lmv(T$Zi^yD=k7Z9JXz-J>p8EvAj` z$t7PiZK6-ccZ)b^ejOE8wn2D;VH)+)cTH!o&WyepJ;$<&xu7d!*%&rnsG3Z z601GBX=t8nGaF|*N*^<4MIZcZyF(u+ zxcDxvkn^2lLzwe;tj-)=7`rpnuAA%~>zP?>$r@?D=No2wQeKJ)H=FW|Z+AP8r=R!- zKEaK%HRh}Gsf^4{qaIQRO?kF;){fTija`}9axacE&XBH!P6@4GnnKMW&)EgGx0Z5r zDOD%ryyclE&NZ(XQRhOdf*s;F_=wn;Z6pnI#>orNMekEzZn3UVL6W zV$24Q?c41oaxXd0S0}Sk#>mnKJ`?*J+70d*dq++;R*rO(jf!XuoBH#(9=3bTipaU4 zjm%wQw#2bHnVCA*xXq$YeaKfQP~Uy=HZ;LPfI zQSK3>CC%t&nU9b?)Fs;|zCk$${e#I{JRPnuY}I3~E?kfEy{Xb0`jLNg$x(g`+tD^F zFs?JZM7R)#Op9d*rPZ&^9=S*}W} z8Eovw?AFg9rBqjQcjjc)A&2M~1Rv7-0&niNQUhIVU*(UZy3y6xU-XlNf#i{R$30!F zAeMvKTxm#&wG918dg6ZVEGS^*o!lBQONj9|(~0O)Pqos%a5I=^$fEaBUVKQJNZ;}` z^Hq|bg!T>Xi#M0_gLhafy+hwPY;EXBI@x!?bHjUuY@)_Fa?pH3y!8Z_0;ZT;Om&ze zY%o8K{8c}L`O*kTuB(s#wEU~l6k6L_!mJ=~tevc*tRX@osAJeB-|?qAK8Gw@o@*$# zVopdeiz*i*M?y}ocT=Qowj)s|>E-$M>^UV@1BKBqKh#&k?u&^HW2I`|P`MAAOBchA zI3F}Lwg~?bjxXKDH3rciPAT|$;H1pzmS^X&qP|-CNyvlB=6Wl#x0~s z=W(R&0Daw?D_LC?#W1dpZn*9hlSPh-2DHSs$NJV#UzcKjZK@-;G;}qO2y1NE?EMkn zfV_UJ?mif#yK5K)Upm@5T9et{1-geOD+g{Dis{}pYX&8 z-^tkhg?pLUNq0#+BsBxm_-SHQP=)S9M!2_or_wj+0x*tTfQ#sja3;d&jM$oK4+nt3 z>>WzNg)q*S=uQ$C*dX*c^DVcSP3L3K8(i1DRJ_QIH4C$Qblp~#= zs%whU{c++WFq=9or|^RuwMvfp6UlDJ;*6|}`GuUc0wAfaa8vAVsu6Y<{s=s%jd(!t z$>Y$sHiP*-$1!t-)wIR*lXXW}$B@Nnj?3=;hFO&GC?*0n0OfU&h6~J(D8qZlwcB~n z)5D(vlZ@#)7hA39dQn?n7Cll<%Xw1T2wbAvxFfSyKNf9dzS75%Wxicfh+(6-74s}_ zbm20lf!Tyt2@l-)-Unc?Z;AH{`yyvOp{Kr0NE!W9Ul))-HStr9Zyj#A1)CLmHR8Cr z0{_$*=BEQ$(a?U~yO3H=r_smpd?AtU$9{(!3n}tL5M?DO6=DL4H9eo0^&n z*s}Tpb|5hk21!)0K3}(jO2>nwSj$S=MVKIr6@MTd;4slA9|yCgYjS^TvFvy^D}8Lv zQV$RIOR>xu*h_5UAL6;`nc)s~&j-5&PwA)PZIH{Z!-BNN*V4XGmYHjMH*!4V;dcI1ix~1XUki*m}1ROxjZ?M8DMc+ zpO{;N+H?Uu-}A`Vglc8(Vdw+aferF}eU6c0&U2F}tJmsG6ow04d4v2dK(HZGma6F~ z>r0cPIf@w~p5hnD$wG|lw!akAz(0AGdkgJD?GOA5{mc31u9ePdI9t3TUUbFeL;HT` zL2Q**1E(&JeFCQVk4bOA9Nh}jG2;nqfd%6h(lBV1hr>RgHRBIA#SV-uwREKfZkHA4 z8}ljlDso#3WTvAXv>)6+)8&=aCi+X}Bf}2gFOHt>2wxPgNH3>lYB{;&%5s^#4SXBP zW;jREp&S^6(>+H#>->4ng@w+dzP_#ec)q(Y-C9; zHI{iKymy^)9uY2Z4|OwiVax=&56Gilz|H>ppf9(9T}cfS9KHm)qoF-13ibuE}mgKu)`Oo>)?#oh5_&J5>L3jsvE;sN;xb8b7y1Vs2 zsM)X*meoBn-!kSKmKd6w&Kl=(lTiYkYhdU-ru#O`H4T{=`OH+s{J_kFw2UmH9|C%z zA-ZC=9C;&dx1O+eMot`q`m^E8G&Cd^`W1z~}KRd?OF-8|F8bh8D*-TNKVK?k`oKYjHPy>+S2j`3{eJ{I{eNy~@A*jOuFG2lOp$}c2E;(8LWj<8539{UiTgpen-#QTJ#9eLvH5V z?e8Y;^=hk zTA|a(j-SYSd9%>d|6JNF){$pmq?jB#IXzOEW~6`aA>MbV%XYW41uoJZfEDFjq0m=R7(@^| z2yK!#K}0tK9i`uKE`5tLQ6teW@Q7GVoPytwp|W1AgUbXyp&df~WF2JCN6;l#Mkl!_ z*1*J}VK_m)EhmwVI02ku3-omj?{rD*w{%ldM(&5^qgMDdf8007|E+jkeC3}a8__rL z5$GcSj4yx{;$oiX#|X)|GPg|kfC;6_z*2Y^ynx3vP~IsK%E2_Jb6`jDG2dNC^QL)|oj?2gQK@t`>CUev!|71n z45_atLCgXTsQ&U>Jb~!pLEID62Zw}~*e`Svj?q;NJ(yfH2y_qhj0CBLuZg%F|13b? zZ7_f#f$txt2I4;krBR4Dpn6itARUdO zmV*S)9QP$n@ORwmK}}I>CKc@i5AX0HCLNa&s5;;+t}5@8TjDYD6Zn`qPUTUT@fSk2 zutoI9nPRB>6HjyRT%n3oLHIq8`#zi@>V#9|2QXCJ&KEiddY9qza*13bBzt>Hf66n( z8)AQH4*3%1!J%*zH5N~kJkmJ~p$l$f%y@xszLbMMLu0s7ZbD#3dck}T+lW(y`+ldq zlkLua#MI@s>ssm-(#dc)8ISkDVro3sm3zdphR(W+6eLgadi(`ljT(n%%5%UqeLPo{ zY5|ASU!V@sQmMQAseg>;rRx$O2Or=@-~#RioH#=QUbB0oKSIh7rudS)$$Uk$4Alh! zkN8()Eqj(~De?Xx!cuSrjF26uIg>-32lM5vWFC5qqPg|lVbB{ygL_ODHk|!~`G`43 zkA;2kSVEJw*a=Pq_WW<5h~A=7DIEU+D^$x$g7>rWccr=7U{S1~pWEFWr(SNP77y@q=opi3Ef${7KJLf4EpI z$i6-PKJq$nM*0+1f#s!cez#zkUt$~CD*X-%nU=^yRY2v$iLxMn34VrMC|jVq68%Sg zufPt_k&MFtw8LHTpJWvM8<;GaQ46p`o{m?d=IkQ0R&Is+OReSk=wtShZlCTCSV$_P z>Tou-0=0xXm;kPVs`LZ8H9HG-#eG11xE@r*<)swy3PI$sI7V6nYQf|18K@`ai!G$f z;(oEKa9VDTZPHljF1$mseD`=Ju!q%`Hi|>|b^h=8%Tg3xB6&pvIRXpdXadj-dI9we zd`1RSKU0TbJSDI%xLMRBbcfo6rqj#O$M8PjfS&Hdt)wzwFVIdrB~0Q?(o^&!JDG9H zze$PoOYlT^Cfy*j(2wXRSWF6~VNzYv3NIs0u#S#lJn{s51&qVJ&I(|9CI2bc5A4f*0{c%28H1mYZ{a&~PCOt! zlOj=P*aXCoePAPM6nHl)kZ<_Vf1w-@}ZR8p~IOCej7*cllz#<8j0-jQ7X#$Au6vU3v^E z=>VliYpGoDCGp9vKq7cVJw)T^3CtF-7TeGj>hnNPY5>Xwc3LAdlAc2iV>#|gz?*k) zFl(o`!cHgwowZp)_1uNcIor&w+;GSq_OzZNZI1Kux7fezl1 z)Rt?@N2FHd8PVb1fk+(%LpTPRd=kGFe2Er-H^c$<13=!8+E5Sg!6d4H%9LwL9q3Uo zMdszBI0DrV?8)QcOY9Yn3o}K#xF5d*PsvX52`YpG!EG{=oF!w(1#$`2#cSos438Mt z3@!#6=_Y|UQ6s!B&nD05T=o`InVCgD#pzH zdSV^e9QgLDD&GRTU?+S=T;n@LK7k{MEaeLW1!Le%pdM8ZoR*yO6x>nnjn9!-@I7Mb z$8=Y;kxT%P>POHi4r4ys9E!hWH?+>va@J@G;? z7XArm;8^j7L{tAm_n-?Y3H}O3;$`wSG={ywJqqmnx7n(&KADZ%26oa=Y5+QdrXv^d z$aSPp@SMz(%i+q(x2Iy5bXl$`_Li2B2$F%TH^dBkB-)A6-DP)H-wk_yTOygNISaK*ZO;P`a24XIg?$ z;2@pC^=8@!@?s765geAsldYf=(0#AVt19z2SG&oJ%q%!aa-q~{S9bBC}53KC~ z)|1BI9q2XaQru6tafA4^-fIuo8%57uifQz&20`yd)`%pra#eo$HE=5|^sf;Tls;q)fvrGMj zO`TUq6-mX1ptN?Ut@#iq^S6H*8kG^n4hh&-ky8I(pTe4|S-A_crgEm?QtT)w6b3a7 zDh8G1pihdNHl|oqbSj5tBZ%~$_JXSvy$Vw*pFwoWsHW}T(jU$#mQ*>_rh-}idqm9w z#rvRtD!2c9R-&s$RzVZIR~b@PXrnlMxvP3ocOQw|lYf>X=*583;WQO!GTjV7;J{pYO0v4%#& zrNvCm>3_yND6O!mtk(QeYDtZl>b1(dR!u59YCb5L&Hm-1#-xH&(X4T)MoW!}7>I#V zZ7Mo-#eaFC<+L2oqSeR0qxxUDsG?S4ts++KC{G$6|K?VUhMM8Q*?-65!-%PDsoh5P zRrOcVrQE43YJ4b~gZ>8Rf_G|E{v9brn|i2Or23$-@lTIb6k5!*98i5yvs24VrR)7) za%#*zjJTE;YE1u`gPP~s=!aRZ+El#$zwoLU6dlT;UH|u;%Da-C8g4bZ8dfc@6)g() zS~h8YQOyIb*MBIj%B$Qfdyvu{v^_|j(_*RCy^2lq`oFG9UHr4AHEz`E($@T2le%-M zR#X`kl{TXGupste=4f}S=Nisnr&8Ee^H04~B>wCCXRlK@l>Y9PYEM!0t0)yo#Y?r5 zYU_eIqt0u{m8b-dU|yX=$zL9Wz0<+qYMYF|+ELY3Drs>sz|uf|=? z6)j_e*wpxHQBkg{cBMmUvDEwtVhehqFrsQz_cJZ)HIKFEsPWUftFq$5-21TZHQlO= zRz2EIsp-|ER7`5FsJ7LLS2U^_r>sz<)u^k{`e$yb94PTqw5i?%b5MO&Gw4G*Dn3QG zYD=p-Ek_m4l^M03v?~ex4MMFCORkWI}535G~RHD|4 z+L2Tig1d!c@t>#agPLvXO11X1ex~hm!Rx>CPVq@Yqu5h){co)b1OKin6^YhyRXrL{ z!M6`(TqJtQ1?SZ>m+bKZybVl$Zpgr`#+2 z{5zV;D)3j9Dfy(VQ86m`R5mnU6cnnB4=o1sQjt^74}Dd0P1B)j_~*P@3+m3KcEVr{ zX?3D9pdwHs5`1gd@+T;x=?}82NUJea=M)_ZCiSZ2hRUe&q`fI