【Follow me第二季第1期】简单方法实现
[复制链接]
本帖最后由 再造巴别 于 2024-10-12 17:38 编辑
使用Adafruit Circuit Playground Express和2442(舵机)
入门任务(必做):开发环境搭建,板载LED点亮
首先访问Circuit Playground Express Download (circuitpython.org),先更新Bootloader
直接复制到开发板连接到电脑后出现的U盘根目录,稍等片刻开发板会自动重启一下,然后烧录CircuitPython,也是类似的。
简单点亮led
-
-
-
- """This example lights up the NeoPixels with a rainbow swirl."""
- import time
- from adafruit_circuitplayground import cp
- from rainbowio import colorwheel
-
- color =(255, 0, 0)
- light_off=(0,0,0)
-
- cp.pixels.brightness = 0.01
- count = 0
- while True:
- for j in range(255):
- cp.pixels[count] = color
- if cp.button_a:
- idx = int((count * 256 / len(cp.pixels)+j))
- cp.pixels[count] = colorwheel(idx & 255)
- time.sleep(0.5)
- cp.pixels[count]= light_off
- count += 1
- if count >= cp.pixels.n:
- count = 0
- time.sleep(0.1)
-
-
-
-
-
-
基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
-
-
-
- """This example lights up the NeoPixels with a rainbow swirl."""
- import time
- from rainbowio import colorwheel
- from adafruit_circuitplayground import cp
-
-
- def rainbow_cycle(wait):
- for j in range(255):
- for i in range(cp.pixels.n):
- idx = int((i * 256 / len(cp.pixels)) + j)
- cp.pixels[i] = colorwheel(idx & 255)
- cp.pixels.show()
- time.sleep(wait)
-
-
- cp.pixels.auto_write = False
- cp.pixels.brightness = 0.3
- while True:
- rainbow_cycle(0.001)
-
基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
- from adafruit_circuitplayground import cp
- import time
-
- while True:
- temperature_c = cp.temperature
- temperature_f = temperature_c * 1.8 + 32
- print("Temperature celsius:", temperature_c)
- print("Temperature fahrenheit:", temperature_f)
- print("Light:", cp.light)
- score = 100
- if cp.light > 25:
- print('The brightness is:',cp.light,'deduct points:',(cp.light-30))
- score -= (cp.light-30)
- if temperature_c > 27:
- score -=(temperature_c-27)*1.5
- print('temperature is:',temperature_c,'deduct points:',(temperature_c-27)*1.5)
- print("now the score is:",score)
- if score<60:
- for i in range(cp.pixels.n):
- cp.pixels[i]=(255,0,0)
- elif score>=60 and score <= 80:
- for i in range(cp.pixels.n):
- cp.pixels[i]=(255,255,0)
- elif score>80:
- for i in range(cp.pixels.n):
- cp.pixels[i]=(0,255,0)
- time.sleep(1)
-
低亮度显示绿色,中亮度黄,高亮度红。
基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
- from adafruit_circuitplayground import cp
- from adafruit_circuitplayground.express import cpx
- from digitalio import DigitalInOut, Direction,Pull
- from analogio import AnalogIn
- import time
- import board
-
- def wheel(pos):
-
-
- if(pos<0) or (pos)>255:
- return (0,0,0)
- 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))
- cp.pixels.brightness = 0.2
- ir_tx = DigitalInOut(board.IR_TX)
- ir_tx.direction = Direction.OUTPUT
- proximity = AnalogIn(board.IR_PROXIMITY)
- while True:
- ir_tx.value=True
- time.sleep(0.1)
- ir_tx.value = False
- proximity_value = proximity.value
- print("proximity Level: %d" % proximity_value)
- max_value=42500
- min_value=31500
- interval_value = (max_value - min_value)/11
- proximity_index = (proximity_value - min_value)//interval_value
- for p in range(10):
- if p<= proximity_index:
- cpx.pixels[p] = tuple(int(c*((10-p%10))/10.0) for c in wheel(25*(p%10)))
- else:
- cpx.pixels[p] = (0,0,0)
- if proximity_index >5:
- cp.play_tone(500,0.5)
我这里发现发射红外和接受红外的时间不能太短,要不然就会发生意料之外的情况。
进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
- from adafruit_circuitplayground import cp
- from adafruit_circuitplayground.express import cpx
- from digitalio import DigitalInOut, Direction,Pull
- from analogio import AnalogIn
- import time
- import board
- import math
-
- def wheel(pos):
-
-
- if(pos<0) or (pos)>255:
- return (0,0,0)
- 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))
- cp.pixels.brightness = 0.2
-
- while True:
- x,y,z=cpx.acceleration
- angle=(2-(math.atan2(x,y)/math.pi+1))*180
- magnitude = math.sqrt(x*x+y*y)
- print(
- "Accelerometer:(%0.1f,%0.1f,%0.1f) m/s^2;Angle:%0.1f,Magnitude:%0.1f"
- % (x,y,z,angle,magnitude)
- )
- if magnitude >2:
- magnitude = min(magnitude,9.8)
- for p in range(10):
- if p==(angle*10//360):
- cpx.pixels[p]=tuple(
- int(c*((10-p%10))/10.0) for c in wheel(25*(p%10))
- )
- else:
- cpx.pixels[p] =(0,0,0)
-
- 读取加速度计数据:读取加速度计的 x、y 和 z 方向的加速度值。
- 计算角度和大小:根据 x 和 y 方向的加速度值计算角度和大小。
- 控制 NeoPixel 灯环:根据角度和大小的变化控制 NeoPixel 灯环的颜色。
- 循环:每秒钟重复以上步骤。
-
创意任务二:章鱼哥——章鱼哥的触角根据环境声音的大小,章鱼哥的触角可舒展或者收缩
- from adafruit_circuitplayground import cp
- from adafruit_circuitplayground.express import cpx
- from digitalio import DigitalInOut, Direction,Pull
- import digitalio
- import audiobusio
- from analogio import AnalogIn
- import time
- import board
- import math
- import pwmio
- from adafruit_motor import servo
- import array
-
-
-
- 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)
-
- reachout = False
-
-
-
-
-
-
-
-
- pwm = pwmio.PWMOut(board.A2, frequency=50)
-
-
- my_servo = servo.ContinuousServo(pwm)
-
- temp = 'quiet'
- 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)
- time.sleep(0.5)
-
- if cp.switch:
- if sound_value > 300:
-
- if temp == 'quiet':
- print("Sound is loud.")
- temp = 'loud'
-
- if not reachout:
-
- my_servo.throttle = 1.0
- reachout = True
- print("Sound Level: %d" % sound_value)
- print(reachout)
- print('reaching out')
- time.sleep(0.5)
- my_servo.throttle = 0.0
- time.sleep(0.5)
-
- else:
- if temp == 'loud':
- print("Sound is quiet.")
- temp = 'quiet'
-
- if reachout:
-
- my_servo.throttle = -1.0
- print("Sound Level: %d" % sound_value)
- print(reachout)
- print('withdrawing')
-
- reachout = False
-
-
- time.sleep(0.5)
- my_servo.throttle = 0.0
- time.sleep(0.5)
-
- else:
- my_servo.throttle = 0.0
- pwm.deinit()
-
-
-
导入必要的库:
- adafruit_circuitplayground
: 用于访问 Adafruit Circuit Playground Express 或 Adafruit Circuit Playground Bluefruit 的功能。
- adafruit_circuitplayground.express
: 同上。
: 提供数字输入输出功能。
: 用于处理音频信号。
: 提供模拟输入输出功能。
: 提供时间相关函数,如 。
: 提供访问硬件端口的功能。
: 提供数学运算功能。
: 提供 PWM(脉宽调制)输出功能。
: 提供高效的数组存储。
: 提供伺服电机控制功能。
-
定义辅助函数:
: 计算一组数值的平均值。
: 计算一组数值的归一化均方根(RMS)。
-
初始化麦克风:
- 使用
类型创建一个麦克风对象,指定采样率和位深度。
-
初始化音频样本数组:
- 创建一个包含 320 个元素的
对象用于存储声音样本。
-
初始化伺服电机:
- 创建一个
对象,指定频率。
- 创建一个连续旋转伺服电机对象
。
-
定义变量:
: 用于跟踪伺服是否正在伸出。
: 用于记录声音的状态(嘈杂或安静)。
-
主循环:
- 持续记录声音样本,并使用
函数计算声音的强度。
- 设定最大和最小的可接受声音强度范围。
- 如果声音强度超过阈值(300),则执行以下操作:
- 输出“Sound is loud.”,并改变
变量的值。
- 如果
为 ,则驱动伺服电机正转(伸出),然后停顿,再停止转动。
- 如果
为 ,则记录 “reaching out”。
- 如果声音强度低于阈值(300),则执行以下操作:
- 输出“Sound is quiet.”,并改变
变量的值。
- 如果
为 ,则驱动伺服电机反转(收回),然后停顿,再停止转动。
- 如果
为 ,则记录 “withdrawing”。
- 如果滑动开关关闭,则停止伺服电机,并取消 PWM 输出。
这个程序的主要功能是让伺服电机在检测到足够大的声音时伸出,在声音消失时缩回。它利用了 Circuit Playground Express/Bluefruit 板上的麦克风和滑动开关,以及 PWM 输出控制伺服电机。
PS:我在嵌入式开发方面只能算是初窥门径,有些地方还是有点问题。比如这里我不知道为什么有的时候这个舵机会发生本来不应该动的情况下会非常缓慢的转动。
源码下载
源代码
心得体会
本次活动我学会了电机PWA的简单控制,以及传感器数据的读取使用。原本遥不可及的东西现在也消除了很多陌生感。总体比较满意,学到很多东西。希望下次还有这种活动。实在要说建议的话,就是感觉论坛里同一个活动的帖子可能归类不太明显,有的时候还得翻找一下。下次可能活动页面直接点进去就是这次活动的帖子就好了。
|