496|3

57

帖子

5

TA的资源

一粒金砂(高级)

楼主
 

【Follow me第二季第1期】创意任务二:害怕声音的纸章鱼~ [复制链接]

 

这个任务就是要用开发板识别环境中的声音大小,然后控制舵机作出相应的动作。至于章鱼哥其实用3D打印实现是一个不错的选择,网上有很多这样的模型,直接切片软件里找个立方体布尔一下,挖一个能放下舵机的位置就可以了,然后用绳子之类的很好改装,都不需要自己建模。奈何暑期我不在实验室用不了,所以就自己用传单的纸折了一个🤦。

 

第一步,纸章鱼哥的制作以及控制结构制作

基本就是折个章鱼(这个是Splatoon3里的章鱼角色~),头部贴到快递纸板上,背面用回形针+风筝线拉到两个触角上,给纸板打个洞挂到舵机上

 

 

第二步,识别环境中的音量

这里先制作了一个音量指示器,开发板会根据环境音量大小进行亮灯,#include <Adafruit_CircuitPlayground.h>中已经封装了相应功能,调用CircuitPlayground.mic.soundPressureLevel(10)即可获取声音大小,音量计的颜色还是参考上一个创意任务一里面的。顺便加了一个滑动平均滤波器,让音量的识别平滑一点。

效果如下:

 

 

代码:

#include <Adafruit_CircuitPlayground.h>



// 定义渐变颜色

uint32_t gradientColors[10] = {

CircuitPlayground.colorWheel(90),

CircuitPlayground.colorWheel(80),

CircuitPlayground.colorWheel(70),

CircuitPlayground.colorWheel(60),

CircuitPlayground.colorWheel(50),

CircuitPlayground.colorWheel(40),

CircuitPlayground.colorWheel(30),

CircuitPlayground.colorWheel(20),

CircuitPlayground.colorWheel(10),

CircuitPlayground.colorWheel(0)

};



// 滤波系数

const float alpha = 0.3;

float filteredSoundLevel = 0;



void setup() {

CircuitPlayground.begin();

Serial.begin(115200); 

}



void loop() {

float soundLevel = CircuitPlayground.mic.soundPressureLevel(10);

// 移动平均滤波

filteredSoundLevel = alpha * soundLevel + (1 - alpha) * filteredSoundLevel;

Serial.print("Raw Sound Level: ");

Serial.print(soundLevel);

Serial.print(", Filtered Sound Level: ");

Serial.println(filteredSoundLevel);

updateLEDs(filteredSoundLevel);

delay(200); // 更新频率

}



void updateLEDs(float soundLevel) {

// 计算亮灯的数量

int ledCountToLight = map(soundLevel, 55, 70, 0, 10);




for (int i = 0; i < 10; i++) {

if (i < ledCountToLight) {


CircuitPlayground.setPixelColor(i, gradientColors[i]);

} else {

CircuitPlayground.setPixelColor(i, 0);

}

}


}



void turnOffAllLEDs() {

for (int i = 0; i < 10; i++) {

CircuitPlayground.setPixelColor(i, 0); // 关闭每个 LED

}



}

 

 

第三步,加入舵机控制

官方推荐的那个舵机是个连续舵机,没法控制具体的角度,只能让它以某个速度向什么方向转动多少时间来控制,我们使用#include <Servo.h>这个库来实现,用Servo.write来设置转速,当设置为90时舵机停止,具体来说连续旋转舵机在接收到中立脉宽时停止旋转,在接收到不同偏离中立脉宽的信号时分别以不同速度和方向旋转,两个方向离90越远转的越快。这个速度和时间,每个舵机都不太一样需要自己试一试。板子上的按钮也做了设置,可以控制舵机左转右转。

 

在代码实现中还遇到一个问题,#include <Servo.h>和彩色led的库有冲突,如果同时使用舵机和彩色led灯话,舵机会时不时朝一个方向抽搐,所以就简单粗暴的把亮灯部分灯功能删掉了,但判断逻辑还是沿用上面的代码,9颗灯珠都亮起时,转动舵机180度(触角收缩),等几秒再转回去。

以下是效果,视频中就不放声音了,可以对这板子的mic吹一口气基本声音就够大了:

纸章鱼

 

#include <Adafruit_CircuitPlayground.h>
#include <Servo.h>

// 定义渐变颜色
uint32_t gradientColors[10] = {
  CircuitPlayground.colorWheel(90), 
  CircuitPlayground.colorWheel(80),
  CircuitPlayground.colorWheel(70),
  CircuitPlayground.colorWheel(60),
  CircuitPlayground.colorWheel(50),
  CircuitPlayground.colorWheel(40),  
  CircuitPlayground.colorWheel(30),
  CircuitPlayground.colorWheel(20),
  CircuitPlayground.colorWheel(10),
  CircuitPlayground.colorWheel(0)
};

// 滤波系数
const float alpha = 0.3;
float filteredSoundLevel = 0;

// 舵机定义
const int servoPin = A3; // 舵机连接的引脚
Servo myServo; 
const int neutralSpeed = 90; // 中立位置速度
const int leftSpeed = 84; // 左转速度
const int rightSpeed = 94; // 右转速度
const int turnDuration = 700; // 转动持续时间
const int delayAfterTurn = 5000; // 等待时间

void setup() {
  CircuitPlayground.begin();
  Serial.begin(115200); // 用于调试
  myServo.attach(servoPin); // 附加舵机到指定引脚
  myServo.write(neutralSpeed); // 设置舵机初始速度为停止
}

void loop() {
  checkButtons();
  
  float soundLevel = CircuitPlayground.mic.soundPressureLevel(10);
  // 滤波
  filteredSoundLevel = alpha * soundLevel + (1 - alpha) * filteredSoundLevel;
  
  Serial.print("Raw Sound Level: ");
  Serial.print(soundLevel);
  Serial.print(", Filtered Sound Level: ");
  Serial.println(filteredSoundLevel);
  
  updateLEDs(filteredSoundLevel);
   myServo.write(neutralSpeed);
  delay(200); 
}

void updateLEDs(float soundLevel) {
  // 计算亮灯的数量
  int ledCountToLight = map(soundLevel, 55, 70, 0, 10);
  
 
  Serial.print("LED Count: ");
  Serial.println(ledCountToLight);
  


  if (ledCountToLight >= 9) { 
    turnLeft180();
    delay(delayAfterTurn); 
    turnRight180();
  }
}

void turnLeft180() {
  myServo.write(leftSpeed); // 设置舵机左转速度
  delay(1900); // 转动持续时间
  myServo.write(neutralSpeed); // 停止舵机
}

void turnRight180() {
  myServo.write(rightSpeed); // 设置舵机右转速度
  delay(turnDuration); // 转动持续时间
  myServo.write(neutralSpeed); // 停止舵机
}

void checkButtons() {//按钮控制
  if (CircuitPlayground.leftButton()) {
    turnLeft180();
    delay(500); 
  }
  if (CircuitPlayground.rightButton()) {
    turnRight180();
    delay(500); 
  }
}

 

 

 

 

 

 

 

 

 

 

最新回复

很有意思呀~大佬真的是想法很多~   详情 回复 发表于 2024-7-31 18:24
点赞 关注
 
 

回复
举报

6449

帖子

10

TA的资源

版主

沙发
 

这个小章鱼还是挺巧妙的  

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

34

帖子

2

TA的资源

一粒金砂(中级)

板凳
 

非常巧妙

 
 
 

回复

7175

帖子

2

TA的资源

版主

4
 

很有意思呀~大佬真的是想法很多~

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表