194 views|0 replies

7

Posts

5

Resources
The OP
 

[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

This post is from DigiKey Technology Zone
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list