【Follow me第二季第1期】+ 小白带你使用circuitpython开发CircuitPlaygroundExpress
[复制链接]
本帖最后由 lihuahua 于 2024-8-12 12:22 编辑
视频介绍
【Follow me第二季第1期】+ 小白带你使用circuitpython开发CircuitPlaygroundExpress-EEWORLD大学堂
代码链接
【Follow me第二季第1期】+ 小白带你使用circuitpython开发CircuitPlaygroundExpress-嵌入式开发相关资料下载-EEWORLD下载中心
一、入门任务(必做):开发环境搭建,板载LED点亮
1、从CircuitPython官网下载UF2文件:https://circuitpython.org/board/circuitplayground_express/
2、单击开发板中间“Reset”按钮,开发板环形灯变为“绿色”,我的电脑出现开发板图标,并将下载的“UF2”文件拖入其中。
3、从 https://codewith.mu 下载 Mu,然后安装软件
4、打开软件Mu,选择模式“CircuitPython”
5、从 CIRCUITPY 驱动器加载 code.py 文件
6、编写“闪灯”代码:
#use the Circuit Playground library
from adafruit_circuitplayground import cp
import time
#不断循环
while True:
cp.red_led = True #led引脚为高电平
time.sleep(0.5) #0.5s
cp.red_led = False #led引脚为高电平
time.sleep(0.5) #0.5s
print("Hello World!") #通过串口输出
“闪灯”软件流程图
7、然后将将 code.py 文件保存在 CIRCUITPY 驱动器上,发现LED闪烁。
点击下载程序按钮
实物效果
MU软件串口界面
二、基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
使用到板载NeoPixel, 每个NeoPixel LED由Red、Green、Blue三种颜色组成,每种颜色控制数值在0~255间变化,最终可以合成不同颜色。
板载NeoPixel编号
软件流程图
“跑马灯+颜色变换”实物图片
#use the Circuit Playground library
from adafruit_circuitplayground import cp
import time
cp.pixels.brightness = 0.1 #亮度
i = 0 #当前显示索引
color_index = 0 #颜色索引
R = 25
G = 25
#跑马灯颜色显示缓冲区
color = [(255, 0, 0),(0, 255, 0),(0, 0, 255),(255, 255, 0),(255, 0, 255),(0, 255, 255),(255, 255, 255)]
#不断循环
while True:
cp.pixels.brightness = 0.1 + 0.05 * i #亮度逐渐增加
cp.pixels[i] = color[color_index] #点亮i号
if i == 0:
j = 9
else:
j = i - 1
cp.pixels[j] = (0, 0, 0) #关闭上一次点亮的灯
i = (i + 1)%10 #i 的值会从 0 开始递增,当它达到 10 时,再次回到 0 并继续递增
color_index = (color_index + 1)%7
time.sleep(0.1) #延迟0.1s
三、基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
1、本实验使用到板载温度、光强传感器
2、使用CircuitPython库读取板载温度的数值,通过序号为9~5的NeoPixel显示舒适程度,温度越高亮的NeoPixel(蓝灯)的数目越多;
3、读取光强传感器的数值,通过序号为0~4的NeoPixel显示舒适程度,光照越强亮的NeoPixel(绿灯)的数目越多。
软件流程图
(初始状态)
(光照变强,绿灯数量变多)
(温度变高,蓝灯数目变多)
实物图片
#use the Circuit Playground library
import time
from adafruit_circuitplayground import cp
cp.pixels.auto_write = False #需要调用cp.pixels.show()显示函数
cp.pixels.brightness = 0.3 #亮度
#最低、最高温度
minimum_temp = 24
maximum_temp = 30
while True:
light_now = cp.light #获取当前亮度
light_peak = round(light_now / 320 * 4)#光线传感器输出值0~320,输出亮度等级
for i in range(5):
if i <= light_peak:
cp.pixels[i] = (0, 255, 0)
else:
cp.pixels[i] = (0, 0, 0)
Temperature_now = cp.temperature #获取当前温度值
#获得温度等级
Temperature_peak = int((Temperature_now - minimum_temp) / (maximum_temp - minimum_temp) * 5)
print((light_now,Temperature_now)) #绘图
print("亮度等级",int(light_peak)) #串口输出
print("温度等级",int(Temperature_peak))
for i in range(9,4,-1): #循环变量从9递减到5
if i >= 10 - Temperature_peak:
cp.pixels[i] = (0, 0, 255)
else:
cp.pixels[i] = (0, 0, 0)
cp.pixels.show() #pixels显示使能
time.sleep(0.1) #延迟0.1s
四、基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
使用到板载红外发射管、接收管,红外发射管发射38khz的红外线,通过检测IR_PROXIMITY引脚的电压来获得距离信息。
电路原理图
软件流程图
眼镜盒靠近电路板前
眼镜盒不断靠近,绿灯数目增加,同时报警
实物图片
import time
import board
import analogio
import digitalio
from adafruit_circuitplayground import cp
# 红外线输出控制引脚
IR_Tx_pin = digitalio.DigitalInOut(board.REMOTEOUT)
IR_Tx_pin.switch_to_output()
# 红外接近传感器模拟量读取
analogin = analogio.AnalogIn(board.IR_PROXIMITY)
# 红外接近传感器模拟量读取的最大、小值
minimum_temp = 39500
maximum_temp = 43000
cp.pixels.auto_write = False #需要调用cp.pixels.show()显示函数
cp.pixels.brightness = 0.3 #亮度
while True:
#输出38khz,50%占空比的红外线
for i in range(32):
IR_Tx_pin.value = True
time.sleep(0.000013)
IR_Tx_pin.value = False
time.sleep(0.000013)
analog_now = analogin.value #获取当前红外线强度对应模拟量
analog_peak = int((analog_now - minimum_temp) / (maximum_temp - minimum_temp) * 10) #将模拟量转化为强度等级
print((analog_now,analog_peak)) #绘图
for i in range(10):
if i <= analog_peak:
cp.pixels[i] = (0, 255, 0)
else:
cp.pixels[i] = (0, 0, 0)
cp.pixels.show() #pixels显示使能
if analog_peak >= 8:
cp.play_tone(300, 0.1) #频率hz,持续时间s
time.sleep(0.1)
五、进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
使用到板载3轴加速度传感器,获得加速度值,作为pixels颜色显示分量。
软件流程图
水平放置
竖直放置
侧置
实物图片
#use the Circuit Playground library
import time
from adafruit_circuitplayground import cp
#基础颜色
R = 0
G = 0
B = 0
while True:
#如果还未打开拨码开关
if not cp.switch:
# If the switch is to the right, it returns False!
print("Slide switch off!")
cp.pixels.fill((0, 0, 0))
continue #跳过本次循环
x, y, z = cp.acceleration #获取3轴加速度值,单位m/s2
print((x, y, z))
# int处理浮点数,会自动截断小数部分
cp.pixels.fill(((R + abs(int(x))), (G + abs(int(y))), (B + abs(int(z)))))
time.sleep(0.05) #50ms运行周期
六、创意任务二:章鱼哥——章鱼哥的触角根据环境声音的大小,章鱼哥的触角可舒展或者收缩
使用到板载mic、外接舵机
舵机连接方法
本实验需要安装库:/CircuitPython_Servo/,然后单击与正在使用的 CircuitPython 版本匹配的目录,并将该目录的内容复制到 CIRCUITPY 驱动器。
软件流程图
舵机基础偏转角
声音增加后,舵机角度偏转
实物图片
import array
import math
import audiobusio
import board
import neopixel
import time
import pwmio
from adafruit_motor import servo
PEAK_COLOR = (100, 0, 255)# Color of the peak pixel.
NUM_PIXELS = 90 # Number of total pixels - 10 build into Circuit Playground
# Exponential scaling factor.
# Should probably be in range -10 .. 10 to be reasonable.
CURVE = 2 #对声音敏感程度
SCALE_EXPONENT = math.pow(10, CURVE * -0.1)
NUM_SAMPLES = 160 # Number of samples to read at once.
#限幅
def constrain(value, floor, ceiling):
return max(floor, min(value, ceiling))
# 在output_min和output_max之间按指数缩放input_value.
def log_scale(input_value, input_min, input_max, output_min, output_max):
normalized_input_value = (input_value - input_min) / (input_max - input_min) #输入缩放
return output_min + math.pow(normalized_input_value, SCALE_EXPONENT) * (output_max - output_min)
#计算一组值的标准化均方根值,在计算RMS之前消除直流偏压
def normalized_rms(values): #该函数接受一个参数values,用于存储要进行处理的值的列表
minbuf = int(mean(values)) #计算给定值列表 values 的平均值,将结果转换为整数
#计算了一组已经减去平均值的样本值的平方和。
#使用列表解析来计算每个值减去平均值后的平方,并将这些平方值相加得到 samples_sum。
samples_sum = sum(float(sample - minbuf) * (sample - minbuf) for sample in values)
#计算标准化均方根值。首先将平方和除以值的数量得到平均平方值,
#然后使用 math.sqrt 函数计算其平方根。最后函数返回这个标准化均方根值
return math.sqrt(samples_sum / len(values))
#求平均值
def mean(values):
return sum(values) / len(values)
def volume_color(volume):
return 200, volume * (255 // NUM_PIXELS), 0
# Main program
#################################舵机初始化####################################
# 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)
#################################mic初始化####################################
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16)
#创建名为samples的数组,类型为"unsigned short"("H")
#初始化NUM_SAMPLES个元素的数组,每个元素的初始值为0。
samples = array.array("H", [0] * NUM_SAMPLES)
##记录初始样品以进行校准。假设开始的时候很安静
mic.record(samples, len(samples))
# Set lowest level to expect, plus a little.
input_floor = normalized_rms(samples) + 10
# OR: used a fixed floor
# input_floor = 50
# You might want to print the input_floor to help adjust other values.
print(input_floor)
# Corresponds to sensitivity: lower means more pixels light up with lower sound
# Adjust this as you see fit.
input_ceiling = input_floor + 500
angle_now = 0
systick = 0
while True:
if systick % 4 == 0:
mic.record(samples, len(samples)) #对短时间的音频进行采样
magnitude = normalized_rms(samples) #使用均方根计算 (RMS) 计算样本中的能量(对应于音量)
# 计算0到NUM_PIXELS范围内的缩放对数读数
c = log_scale(
constrain(magnitude, input_floor, input_ceiling),
input_floor,
input_ceiling,
0,
NUM_PIXELS,
)
#舵机角度控制周期
if systick % 2 == 0:
if angle_now < c:
angle_now = angle_now + 2
if angle_now > c:
angle_now = angle_now - 2
#输出角度限幅
if angle_now > 90:
angle_now = 90
elif angle_now < 0:
angle_now = 0
my_servo.angle = angle_now #舵机角度输出
print((c,angle_now)) #串口打印输出
time.sleep(0.01) #延时10ms
systick = systick + 1 #时钟增加
七、心得体会
1、在使用MicroPython(或 CircuitPython)开发时,通常需要将特定的固件(通常是.uf2文件)烧录到开发板中,用于:初始化文件系统、包含驱动程序和功能、启动MicroPython解释器
2、MicroPython 没有将 Python 代码编译为本机机器码的步骤。相比之下,传统的 C 代码需要经过编译以生成可在特定硬件上运行的二进制文件。
3、.uf2 文件通常用于存储 MicroPython 或 CircuitPython 解释器以及用户的 Python 代码,而引导加载程序是负责将这些内容加载到设备中并启动它们的关键组件。
|