[Digi-Key Follow me Season 2 Episode 1] Task submission + infrared function usage
[Copy link]
This post was last edited by Yi Zejiu on 2024-9-1 21:56
Part 1: 3-5 minute short video
Video link: Video
Part II: Task Implementation Details
(1) Task/project introduction
①Project Introduction
The Follow me event is a large-scale development board experience event initiated by DigiKey and EEWorld. In each issue, technical experts recommend development boards/instrument kits that are easy to play and learn, and take everyone to actual operation. Participants can return JD cards after completing the tasks.
The activity aims to help electronics enthusiasts learn practical electronic technology knowledge, accumulate DIY experience, and become better versions of themselves!
② Bill of Materials
1. Purchased materials:
Adafruit Circuit Playground Express (Core Board)
JOY FEATHERWING (joystick button control panel)
NEOKEY FEATHERWING (Mechanical key control board)
2. Non-purchased materials:
NEC code infrared wireless communication control board
Adafruit ESP32-S3 TFT Feather Development Board
③Design ideas
Use Adafruit ESP32-S3 TFT Feather development board, NEOKEY FEATHERWING , JOY FEATHERWING and NEC code infrared wireless communication control board to form an infrared remote controller, which can remotely control the development board of FollowMe in this issue (onboard infrared transceiver). The communication between the two development boards is realized through the NEC protocol.
(2) Software flow chart
(3) The main code snippets, function demonstrations, and graphic descriptions corresponding to each task (each task must include at least one corresponding physical picture)
Getting Started Tasks (Required): Build the Development Environment and Light Up the Onboard LED
Main code:
import time
import board
import digitalio
led = digitalio.DigitalInOut(board.D13)
led.switch_to_output()
buttonA = digitalio.DigitalInOut(board.BUTTON_A)
buttonA.switch_to_input(pull=digitalio.Pull.DOWN)
buttonB = digitalio.DigitalInOut(board.BUTTON_B)
buttonB.switch_to_input(pull=digitalio.Pull.DOWN)
while True:
if buttonA.value:
led.value = True
elif buttonB.value:
led.value = False
time.sleep(0.01)
Adapted from Adafruit official website , press A to turn on the LED, press B to turn it off
Basic Task 1 (Must Do): Control the onboard colorful LED, light up the marquee and change the color
import time
import board
from rainbowio import colorwheel
import neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=0.2, auto_write=False)
color_chase_demo = 1
flash_demo = 1
rainbow_demo = 1
rainbow_cycle_demo = 1
def color_chase(color, wait):
for i in range(10):
pixels[i] = color
time.sleep(wait)
pixels.show()
time.sleep(0.5)
def rainbow_cycle(wait):
for j in range(255):
for i in range(10):
rc_index = (i * 256 // 10) + j * 5
pixels[i] = colorwheel(rc_index & 255)
pixels.show()
time.sleep(wait)
def rainbow(wait):
for j in range(255):
for i in range(len(pixels)):
idx = int(i + j)
pixels[i] = colorwheel(idx & 255)
pixels.show()
time.sleep(wait)
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
WHITE = (255, 255, 255)
OFF = (0, 0, 0)
while True:
if color_chase_demo:
color_chase(RED, 0.1)
color_chase(YELLOW, 0.1)
color_chase(GREEN, 0.1)
color_chase(CYAN, 0.1)
color_chase(BLUE, 0.1)
color_chase(PURPLE, 0.1)
color_chase(OFF, 0.1)
if flash_demo:
pixels.fill(RED)
pixels.show()
time.sleep(1)
pixels.fill(GREEN)
pixels.show()
time.sleep(1)
pixels.fill(BLUE)
pixels.show()
time.sleep(1)
pixels.fill(WHITE)
pixels.show()
time.sleep(1)
if rainbow_cycle_demo:
rainbow_cycle(0.05)
if rainbow_demo:
rainbow(0.05)
Achieve four lighting effects
Basic Task 2 (Required): Monitor ambient temperature and light, and display comfort level through onboard LEDs
import time
import neopixel
import adafruit_thermistor
import board
thermistor = adafruit_thermistor.Thermistor(
board.TEMPERATURE, 10000, 10000, 25, 3950)
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=0.2, auto_write=False)
warn = False
de_warn = False
while True:
temp_c = thermistor.temperature
print("Temperature is: %f C " % (temp_c))
if temp_c > 30 and not warn:
warn = True
de_warn = False
if temp_c < 30 and not de_warn:
de_warn = True
warn = False
if warn:
pixels.fill((15,0,0))
pixels.show()
if de_warn :
pixels.fill((0,0,0))
pixels.show()
time.sleep(0.25)
The code sets the temperature limit to 30 degrees. If it exceeds this limit, the red light will turn on, otherwise it will turn off. In the video, you can see that the red light turns on when the temperature is raised by a lighter, and turns off when the fire source is removed.
Basic Task 3 (Required): Proximity Detection - Set a safe distance and display it through the onboard LED. When an intrusion is detected, an audible alarm is triggered.
import board
import digitalio
import analogio
import time
import math
from adafruit_circuitplayground.express import cpx
ir_tx = digitalio.DigitalInOut(board.IR_TX)
ir_tx.direction = digitalio.Direction.OUTPUT
proximity = analogio.AnalogIn(board.IR_PROXIMITY)
def detect_invade_vel():
ir_tx.value = True
time.sleep(0.001)
ir_tx.value = False
proximity_value = proximity.value
print("proximity value: %d" % proximity_value)
max_value = 42000
min_value = 20000
invade_step = (max_value - min_value) / 11
invade_level = math.floor((proximity_value - min_value) / invade_step)
return invade_level
while True:
invade_level = detect_invade_vel()
if invade_level > 0:
for item in range(invade_level):
cpx.pixels[item] = (math.floor(1.5*invade_level),math.floor(15-1.5*invade_level),0)
cpx.play_tone(262, 0.55-0.05*invade_level)
cpx.pixels.fill((0, 0, 0))
time.sleep(0.05)
The closer the distance to the alarm, the redder the color (from green to red), the more lights will light up, and the higher the alarm frequency will be.
Advanced task (must do): Make a tumbler - show the different lighting effects during the movement of the tumbler
This task requires an acceleration sensor. In order to realize the tumbler, my design is to convert the original acceleration value into polar coordinates, and then determine which light should be turned on based on the angle of the polar coordinates, calculate the color (from green to red) based on the ρ of the polar coordinates, and set the tolerance to prevent frequent jumps in the static state.
#将笛卡尔坐标系向极坐标系转化
def Cartesian2Polar(cor = (0,0)):
r = math.sqrt(cor[0]*cor[0]+cor[1]*cor[1])
if r == 0:
return None,None
else:
if cor[0]<0:
theta = math.pi - math.asin(cor[1]/r)
else:
theta = math.asin(cor[1]/r)
if theta<0:
theta += 2*math.pi
return r,theta*6/math.pi
Complete code:
import math
import time
from adafruit_circuitplayground import cp
cp.pixels.auto_write = False
cp.pixels.brightness = 0.3
def Cartesian2Polar(cor = (0,0)):
r = math.sqrt(cor[0]*cor[0]+cor[1]*cor[1])
if r == 0:
return None,None
else:
if cor[0]<0:
theta = math.pi - math.asin(cor[1]/r)
else:
theta = math.asin(cor[1]/r)
if theta<0:
theta += 2*math.pi
return r,theta*6/math.pi
def neo_be_light(polar_msg, mode, tolerance = 2):
degree = 90/9.8*(polar_msg[0]-tolerance)
if degree>90:
degree = 90
l_light = math.floor(float(polar_msg[1]))
r_light = math.ceil(float(polar_msg[1]))
if mode == "multi":
if polar_msg[1] - l_light < 0.2:
belight = (l_light - 1,l_light,r_light)
elif r_light - polar_msg[1] > 0.2:
belight = (l_light,r_light,r_light + 1)
else:
belight = (l_light,r_light)
elif mode == "single":
belight = r_light if (l_light - float(polar_msg[1])) > (r_light - float(polar_msg[1])) else l_light
return degree,belight
#返回倾斜程度(角度制)和要点亮的灯的弧度值
def judge_neopixle(data, degree):
if data > -1 and data < 3 :
cp.pixels[data + 7] = (15-15/degree*90, 15/degree*90, 0)
elif data == 3:
pass
elif data >3 and data < 9:
cp.pixels[data - 4] = (15-15/degree*90, 15/degree*90, 0)
elif data == 9:
pass
elif data > 9 and data < 12:
cp.pixels[data - 5] = (15-15/degree*90, 15/degree*90, 0)
elif data == 12:
cp.pixels[7] = (15-15/degree*90, 15/degree*90, 0)
elif data == 13:
cp.pixels[6] = (15-15/degree*90, 15/degree*90, 0)
else:
print("data error")
def tumbler(mode = "multi", tolerance = 2): #opt: "multi", "single"
r,area = Cartesian2Polar(cp.acceleration)
if not(r == None and area == None):
if r < tolerance:
cp.pixels.fill((15, 15, 15))
else:
a,b=neo_be_light(Cartesian2Polar(cp.acceleration), mode, tolerance)
cp.pixels.fill((0, 0, 0))
if isinstance(b,int):
judge_neopixle(b, a)
else:
for item in b:
judge_neopixle(item, a)
cp.pixels.show()
time.sleep(0.1)
while True:
tumbler( "single", 1)
In addition, I also set two modes: single light mode ("single") and multi-light mode ("multi"), as well as parameter tolerance (tolerance), which is convenient for setting the tumbler effect
Creative Task 1: Creative wearable decorations - can be combined with a variety of sensors and lighting effects for display
Matching devices: Adafruit Circuit Playground Express , pendants, homemade remote control
The core of this task is to use the infrared sensor. The other codes have basically appeared above, so only the infrared sensor code is placed:
import pulseio
import board
import adafruit_irremote
pulsein = pulseio.PulseIn(board.IR_RX, maxlen=120, idle_state=True)
decoder = adafruit_irremote.GenericDecode()
while True:
pulses = decoder.read_pulses(pulsein)
try:
do_msg_neokey(decoder.decode_bits(pulses)[2])
except adafruit_irremote.IRNECRepeatException: # unusual short code!
print("NEC repeat!")
except adafruit_irremote.IRDecodeException as e: # failed to decode
print("Failed to decode: ", e.args)
Effect:
(4) Your experience with this activity
Thanks to EEworld and Digikey for providing the activity platform, I learned a lot while playing with the board, such as managing Python memory, because memory resources are extremely limited on embedded platforms. In the process of completing the task, I encountered Memory Error many times. Finally, I consulted the information, re-understood Python, and learned about CircuitPython, and finally solved the problem and realized the function.
It is recommended that such activities continue to be held to allow more people to become electronic engineers.
Part 3: Compilable and downloadable code
Source code: code
|