467|2

6

帖子

3

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第1期】简单方法实现 [复制链接]

  本帖最后由 再造巴别 于 2024-10-12 17:38 编辑

使用Adafruit Circuit Playground Express2442(舵机)

 

 
入门任务(必做):开发环境搭建,板载LED点亮

首先访问Circuit Playground Express Download (circuitpython.org),先更新Bootloader

 

直接复制到开发板连接到电脑后出现的U盘根目录,稍等片刻开发板会自动重启一下,然后烧录CircuitPython,也是类似的。

 

简单点亮led

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""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.auto_write = False
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)
    

# while True:
   
#     cp.pixels[1]=(0,0,245)
#     cp.pixels[0] = (255, 0, 0)

 

基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""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)  # rainbowcycle with 1ms delay per step

  

 

基础任务二(必做):监测环境温度和光线,通过板载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):
    #input a value 0 to 255 to get a color value.
    #The colors are a transition r - g - b - back to r.
    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):
    #input a value 0 to 255 to get a color value.
    #The colors are a transition r - g - b - back to r.
    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)
                
  1. 读取加速度计数据:读取加速度计的 x、y 和 z 方向的加速度值。
  2. 计算角度和大小:根据 x 和 y 方向的加速度值计算角度和大小。
  3. 控制 NeoPixel 灯环:根据角度和大小的变化控制 NeoPixel 灯环的颜色。
  4. 循环:每秒钟重复以上步骤。
  5.  

创意任务二:章鱼哥——章鱼哥的触角根据环境声音的大小,章鱼哥的触角可舒展或者收缩

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

# # create a PWMOut object on Pin A2.
# pwm = pwmio.PWMOut(board.A2, duty_cycle=2 ** 15, frequency=50)

# # Create a servo object, my_servo.
# my_servo = servo.Servo(pwm)

# create a PWMOut object on Pin A2.
pwm = pwmio.PWMOut(board.A2, frequency=50)

# Create a servo object, my_servo.
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()  # This will deinitialize the PWM output.
        # Wait a bit before checking the switch again.
        
  1. 导入必要的库

    • adafruit_circuitplayground: 用于访问 Adafruit Circuit Playground Express 或 Adafruit Circuit Playground Bluefruit 的功能。
    • adafruit_circuitplayground.express: 同上。
    • digitalio: 提供数字输入输出功能。
    • audiobusio: 用于处理音频信号。
    • analogio: 提供模拟输入输出功能。
    • time: 提供时间相关函数,如 sleep()
    • board: 提供访问硬件端口的功能。
    • math: 提供数学运算功能。
    • pwmio: 提供 PWM(脉宽调制)输出功能。
    • array: 提供高效的数组存储。
    • adafruit_motor.servo: 提供伺服电机控制功能。
  2. 定义辅助函数

    • mean(values): 计算一组数值的平均值。
    • normalized_rms(values): 计算一组数值的归一化均方根(RMS)。
  3. 初始化麦克风

    • 使用 PDMIn 类型创建一个麦克风对象,指定采样率和位深度。
  4. 初始化音频样本数组

    • 创建一个包含 320 个元素的 array.array 对象用于存储声音样本。
  5. 初始化伺服电机

    • 创建一个 PWMOut 对象,指定频率。
    • 创建一个连续旋转伺服电机对象 ContinuousServo
  6. 定义变量

    • reachout: 用于跟踪伺服是否正在伸出。
    • temp: 用于记录声音的状态(嘈杂或安静)。
  7. 主循环

    • 持续记录声音样本,并使用 normalized_rms 函数计算声音的强度。
    • 设定最大和最小的可接受声音强度范围。
    • 如果声音强度超过阈值(300),则执行以下操作:
      • 输出“Sound is loud.”,并改变 temp 变量的值。
      • 如果 reachout 为 False,则驱动伺服电机正转(伸出),然后停顿,再停止转动。
      • 如果 reachout 为 True,则记录 “reaching out”。
    • 如果声音强度低于阈值(300),则执行以下操作:
      • 输出“Sound is quiet.”,并改变 temp 变量的值。
      • 如果 reachout 为 True,则驱动伺服电机反转(收回),然后停顿,再停止转动。
      • 如果 reachout 为 False,则记录 “withdrawing”。
    • 如果滑动开关关闭,则停止伺服电机,并取消 PWM 输出。

这个程序的主要功能是让伺服电机在检测到足够大的声音时伸出,在声音消失时缩回。它利用了 Circuit Playground Express/Bluefruit 板上的麦克风和滑动开关,以及 PWM 输出控制伺服电机。

PS:我在嵌入式开发方面只能算是初窥门径,有些地方还是有点问题。比如这里我不知道为什么有的时候这个舵机会发生本来不应该动的情况下会非常缓慢的转动。

  源码下载

源代码
心得体会

本次活动我学会了电机PWA的简单控制,以及传感器数据的读取使用。原本遥不可及的东西现在也消除了很多陌生感。总体比较满意,学到很多东西。希望下次还有这种活动。实在要说建议的话,就是感觉论坛里同一个活动的帖子可能归类不太明显,有的时候还得翻找一下。下次可能活动页面直接点进去就是这次活动的帖子就好了。

点赞 关注
 
 

回复
举报

6

帖子

3

TA的资源

一粒金砂(中级)

沙发
 
本帖最后由 再造巴别 于 2024-8-28 17:20 编辑

接近检测的视频忘记放了

 
 
 

回复

6

帖子

3

TA的资源

一粒金砂(中级)

板凳
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表