【Follow me第二季第1期】任务提交:疯狂章鱼哥
[复制链接]
本帖最后由 cc1989summer 于 2024-9-27 22:19 编辑
非常有幸参加EEWORLD和得捷举办的Follow me活动,让大家尽其所能折腾。
而且大概每年都是在暑期举办(虽然打工人没有暑假)(去年我也参加了Follow me第1期Raspberry Pi Pico W),外面虽然热但在家吹着空调安心搞软硬件开发也是一种乐趣。
项目视频演示
本项目完成了本期活动的全部内容,所有任务的展示如下:
Adafruit
物料展示
我购买物料为活动必备物料开发板、推荐物料舵机。
实物如图:
任务成果展示
入门任务:开发环境搭建,板载LED点亮
原帖详见:
https://bbs.eeworld.com.cn/thread-1289929-1-1.html
开发环境搭建:
Python是目前最流行的开发方式,官方介绍的开发工具是Mu Editor,而我因为开发树莓派pico时电脑上安装过thonny,觉得挺好用,就沿用下来了。
开发板安装CircuitPython的方法我就不赘述了。
按默认方法安装软件。
https://thonny.org/
右下角选择对用的COM口,即可连上开发板。
以下为灯(Board.LED)闪烁程序。
import time
from adafruit_circuitplayground import cp
while True:
cp.red_led = True
time.sleep(1)
cp.red_led = False
time.sleep(1)
演示:
基础任务一:控制板载炫彩LED,跑马灯点亮和颜色变换
所使用的板载元件:彩色LED(NeoPixel)
NeoPixel是具备MCU控制功能的单总线LED,并非常规LED,运行的是NZR单总线协议。
本段代码的流程为,大循环内嵌套小循环,大循环为颜色变换,小循环为亮度变换
代码:
import time
import board
import neopixel
# 定义颜色
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)
#定义灯的数量
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10)
#核心显示函数
def color_change(color, wait):
for i in range(10):
pixels[i] = color
time.sleep(0.1)
pixels.show()
time.sleep(0.4)
while True:
color_change(RED, 0.1)
color_change(YELLOW, 0.1)
color_change(GREEN, 0.1)
color_change(CYAN, 0.1)
color_change(BLUE, 0.1)
color_change(PURPLE, 0.1)
color_change(OFF, 0.1)
演示:
基础任务二:监测环境温度和光线,通过板载LED展示舒适程度
通过读取到光线和温度数据后,根据当前数值和舒适数值的差异,数字的大小来表示舒适度。数字越大时,代表环境越不好,板子上的RGB灯会亮的越多。
代码:
import time
from adafruit_circuitplayground import cp
cp.detect_taps = 1
cp.pixels.auto_write = False
cp.pixels.brightness = 0.3
color_cnt = 0
marquee_cnt = 0
def marquee_range(light, tem):
red = 0
green = 0
blue = 0
if tem < 28.5:
green = 150
elif 28.5 <= tem <= 29.5:
red = 150
green = 150
elif tem > 29.5:
red = 150
for i in range(10):
if i <= light / 320 * 9:
cp.pixels[i] = (2 + red * i / 10, 2 + green * i / 10, 2 + blue * i / 10)
else:
cp.pixels[i] = (0, 0, 0)
cp.pixels.show()
while True:
marquee_range(cp.light, cp.temperature)
print(cp.temperature)
time.sleep(0.1)
演示:
![](https://bbs.eeworld.com.cn/data/attachment/forum/202408/07/231015czm6j5hwcchdaww3.png)
基础任务三:接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
详细帖子见:
https://bbs.eeworld.com.cn/thread-1290049-1-1.html
利用光照传感器的感应,思路见以下:
把全部白光LED灯打开,照度一般在4000+,用手接近的话,形成反射效果,照度瞬间上升至30000~40000+
只需要加个判断即可。
代码见以下:
import board
import time
import analogio
import neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10)
for i in range(10):
pixels[i] = (255, 255, 255)
pixels.show()
light = analogio.AnalogIn(board.LIGHT)
while True:
time.sleep(1)
print(light.value)
if light.value >10000:
print("Hurry UP")
演示:
进阶任务:制作不倒翁——展示不倒翁运动过程中的不同灯光效果
这个任务使用的是加速度传感器,利用它的测值,并映射到rgb值上,从而改变led的颜色。
代码:
import time
from adafruit_circuitplayground import cp
cp.pixels.fill((255,255,255))
while True:
if not cp.shake():
(x,y,z)=cp.acceleration
r=int(abs(x)/10*255)
g=int(abs(y)/10*255)
b=int(abs(z)/10*255)
cp.pixels.fill((r,g,b))
展示:
本次来到最终的作品提交,我选择的任务是疯狂章鱼哥
■ 创意任务二:章鱼哥——章鱼哥的触角根据环境声音的大小,章鱼哥的触角可舒展或者收缩
搭配器件: Adafruit Circuit Playground Express、舵机
配合使用舵机FS90R,通过PWM(A1)引脚驱动。
工作原理:PWM信号由接收通道进入信号解调电路进行解调,获得一个直流偏置电压。直流偏置电压与电位器的电压比较,获得电压差并输出。该输出送入电机驱动集成电路以驱动电机正反转。当电机转动时,通过级联减速齿轮带动电位器旋转,直到电压差为O,电机停止转动。舵机的控制信号是PWM信号,利用占空比的变化,改变舵机的位置。
这是他的规格:
程序架构:
当检测到声音后,计算声音升压的平均值,然后将这个值转到舵机可接受的pwm脉宽范围,并将PWM信号送出去驱动舵机,同时根据平均声压大小来亮起对应数量的指示灯。
以下为驱动程序:
import time
import math
import board
import array
import audiobusio
import pwmio
from digitalio import DigitalInOut, Direction, Pull
from analogio import AnalogIn
import microcontroller
from adafruit_circuitplayground.express import cpx
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
color = {
"black": 0x000000,
"white": 0xFFFFFF,
"red": 0xFF0000,
"green": 0x00FF00,
"blue": 0x0000FF,
"cyan": 0x00FFFF,
"magenta": 0xFF00FF,
"yellow": 0xFFFF00,
}
# Not too bright!
cpx.pixels.brightness = 0.3
# Number of Pixel on board
pix_num = 10
def map_range(input_value, input_min, input_max, output_min, output_max):
std_value = (input_value - input_min) / (input_max - input_min)
return std_value * (output_max - output_min) + output_min
def wheel(pos):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if (pos < 0) or (pos > 255):
return color["black"]
if pos < 85:
return (int(255 - pos * 3), int(pos * 3), 0)
elif pos < 170:
pos -= 85
return (0, int(255 - (pos * 3)), int(pos * 3))
else:
pos -= 170
return (int(pos * 3), 0, int(255 - pos * 3))
# 创意任务二:章鱼哥——章鱼哥的触角根据环境声音的大小,章鱼哥的触角可舒展或者收缩
def servo_duty_cycle(pulse_us, frequency=50):
period_us = 1.0 / frequency * 1000000.0
duty_cycle = int(pulse_us / (period_us / 65535.0))
return duty_cycle
def mean(values):
return sum(values) / len(values)
def normalized_rms(values):
minbuf = int(mean(values))
sum_of_samples = sum(
float(sample - minbuf) * (sample - minbuf) for sample in values
)
return math.sqrt(sum_of_samples / len(values))
mic = audiobusio.PDMIn(
board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16
)
samples = array.array("H", [0] * 320)
mic.record(samples, len(samples))
pwm = pwmio.PWMOut(board.A1, frequency=50, duty_cycle=0)
while True:
mic.record(samples, len(samples))
sound_value = normalized_rms(samples)
max_value = 1500
min_value = 150
sound_value = min(sound_value, max_value)
sound_value = max(sound_value, min_value)
print("音量: %d" % sound_value)
pwm.duty_cycle = servo_duty_cycle(int(map_range(sound_value, min_value, max_value, 500, 2500)))
sound_index = int(map_range(sound_value, min_value, max_value, 0, 10))
for p in range(10):
if p <= sound_index:
cpx.pixels[p] = tuple(
int(c * ((10 - p % 10)) / 10.0) for c in wheel(25 * (p % 10))
)
else:
cpx.pixels[p] = color["black"]
展示:
本次项目的全部代码见:
download.eeworld.com.cn/detail/cc1989summer/634046
对本活动的心得体会:
本次活动增强了我对基于micropython平台开发的熟练度,常见的传感器(温度、照度、声音大小等等)都学会了运用,充分利用这些传感器可以更好的解决生活中遇到的问题,实现自动化、智能化。
micropytho方便易用的同时,也存在不知低层的缺点,尤其是对适应了仿真、调试功能的硬件开发工程师来说,有种盲人摸象的感觉。
后期我尝试过,用J-Link 接入SWD调试接口,使用microchip的IDE MPLAB IPE v6.20开发,但始终提示无法识别,不知坛友们有没有解决方案。
最后再次感谢EEworld及得捷电子提供的学习机会,谢谢!![](https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/victory.gif)
|