- 2024-12-18
-
发表了主题帖:
【Follow me第二季第4期】任务合集-主板正反面识别,音量大小识别【z75993971】
本帖最后由 z75993971 于 2024-12-18 22:33 编辑
[localvideo]adb3ec67e1f69fa4bfcbff9a93258678[/localvideo]
(1)任务/项目介绍(需要包含项目简介;全部物料清单,含物料名称、实物图片;设计思路)
【物料清单】:本任务仅使用Arduino Nano RP2040 connect开发板和USB-C转MicroUSB转接线(做数据通信和供电)
【任务介绍】:
主要任务有以下几个部分
0.上电后绿灯闪烁,频率2Hz,持续5S钟
1.串口打印Hello DigiKey & EEWorld!
2.Blink三色LED(红灯亮->绿灯亮->蓝灯亮),每个灯亮0.2S,灭0.1S,持续循环,保持10S的时间
3.串口打印加速度和陀螺仪的值,分别6轴的信息,通过Float类型打印,打印频率10HZ,通过加速度计,判定板子正面朝上还是朝下,如果朝上,则输出正面朝上,如果朝下,则输出正面朝下
4.根据MIC输入的响度,控制蓝色led灯的亮度
【设计思路】:
1.上电后,初始化LED为输出,并控制LED以2Hz频率闪灯:亮250ms,灭250ms
2.控制三色灯,RGB分别以亮200ms,灭100ms闪灯,持续10s的时间,并在输出完成后,关闭所有LED输出
3.读取IMU的6轴数据,并通过陀螺仪的任意一轴判断,是否有移动(门限为30),若有移动,则判断加速度计Z轴的值,大于0则正面朝上,小于0则正面朝下,根据正反面控制LED蓝灯或者红灯亮,并在UART输出对应消息
4.初始化MIC,并读取PDM数据,每组取8个数据,并在8个数据中取出最大值,根据PDM的值,映射到0~255的范围内,来控制LED的亮度
(2)软件流程图
(3)各任务对应的主要代码片段、功能展示及图文说明(每个任务需要包含至少一张对应的实物图)
【任务一】:绿灯慢闪,串口打印Hello DigiKey & EEWorld!
【任务一代码片段】:
void greenPin_blink_2hz()
{
digitalWrite(greenPin, HIGH);
delay(250);
digitalWrite(greenPin, LOW);
delay(250);
}
/****
*Step1:串口打印Hello DigiKey & EEWorld!
****/
void step_1()
{
Serial.println("Hello DigiKey & EEWorld!!!");
}
/****
*Step2:三色灯闪灯10S钟,每秒钟每个灯各亮200ms
****/
void step_2()
{
digitalWrite(redPin, HIGH);
delay(200);
digitalWrite(redPin, LOW);
delay(100);
digitalWrite(greenPin, HIGH);
delay(200);
digitalWrite(greenPin, LOW);
delay(100);
digitalWrite(bluePin, HIGH);
delay(200);
digitalWrite(bluePin, LOW);
delay(200);
}
【任务一图文说明】:任务一比较简单,通过控制LED输出高低电平来驱动红绿蓝三色灯,并通过UART打印
【任务一实物图片】:
【任务二】:Blink三色LED(红灯亮->绿灯亮->蓝灯亮->全亮->全灭),每个灯亮0.2S,持续循环,保持10S的时间
【任务二代码片段】:
//step_2:三色灯闪灯10S钟
unsigned long startTime = millis();
Serial.println("step_2 start");
while((millis()-startTime) < 10*1000)
{
step_2();
}
Serial.println("step_2 end ");
void step_2()
{
digitalWrite(redPin, HIGH);
delay(200);
digitalWrite(redPin, LOW);
delay(100);
digitalWrite(greenPin, HIGH);
delay(200);
digitalWrite(greenPin, LOW);
delay(100);
digitalWrite(bluePin, HIGH);
delay(200);
digitalWrite(bluePin, LOW);
delay(200);
}
【任务二图文说明】:在主循环中,判定当前时间是否超过10S,如果没有超过,则循环调用step_2();函数进行闪灯
【任务二实物图片】:
[localvideo]2a38b21bbe970e78a909b31a896908e3[/localvideo]
【任务三】:串口打印加速度和陀螺仪的值,分别6轴的信息,通过Float类型打印,打印频率10HZ,通过加速度计,判定板子正面朝上还是朝下,如果朝上,则输出正面朝上,如果朝下,则输出正面朝下
【任务三代码片段】:
//step3:调用IMU数据
Serial.println("step_3 start");
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Acceleration in g's");
Serial.println("X\tY\tZ");
Serial.print("Gyroscope sample rate = ");
Serial.print(IMU.gyroscopeSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Gyroscope in degrees/second");
Serial.println("X\tY\tZ");
//注意有溢出风险
startTime = millis();
while((millis()-startTime) < 10*1000)
{
step_3();
}
Serial.println("step_3 end");
void step_3()
{
float x, y, z;
float a, b, c;
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);
Serial.print(x);
Serial.print('\t');
Serial.print(y);
Serial.print('\t');
Serial.print(z);
Serial.print('\t');
}
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(a, b, c);
Serial.print(a);
Serial.print('\t');
Serial.print(b);
Serial.print('\t');
Serial.print(c);
Serial.println("\t");
}
//如果检测到有移动,则判定板子是否正面朝上
if(abs(a)>GYROSCOPE_THRESHOLD || abs(b)>GYROSCOPE_THRESHOLD ||abs(c)>GYROSCOPE_THRESHOLD )
{
Serial.print("\n检测到移动\n");
if(z>0)
{
digitalWrite(greenPin, HIGH);
Serial.print("\n正面朝上\n");
}
else
{
digitalWrite(redPin, HIGH);
Serial.print("\n反面朝上\n");
}
}
delay(100);
disable_all_leds();
}
【任务三图文说明】:该任务仍然在主循环中完成,首先获取任务开始时间,在step_3函数中获取陀螺仪和加速度值,并根据加速度值是否有明显的变化(门限大于3),只要在任何一个轴上陀螺有大于门限的变化则根据Gsensor的值来判定板子朝向,如果正面朝上则亮绿灯,朝下则亮红灯,如果陀螺
【任务三实物图片】:
[localvideo]354a4ddeed7cbda340fb599c769e58ff[/localvideo]
【任务四】:根据MIC输入的响度,控制蓝色led灯的亮度
【任务四代码片段】:
//step4,根据PDM数据来控制蓝灯亮度
startTime = millis();
Serial.println("step_4 start");
while((millis()-startTime) < 10*1000)
{
step_4();
}
Serial.println("step_4 end");
// 映射PDM数据到LED亮度
unsigned char mapPDMToLED(short pdmValue) {
unsigned char ledBrightness = 0;
if(pdmValue <= 50)
{
ledBrightness = 1;
}
else if(pdmValue<1000)
{
//0~50
ledBrightness = pdmValue/20;
}
else if(pdmValue<2500)
{
//51~150
ledBrightness = 50;
ledBrightness += (pdmValue - 1000)/100;
}
else if(pdmValue<4000)
{
//161~200
ledBrightness = 160;
ledBrightness += (pdmValue - 2500)/50;
}
else if(pdmValue<6000)
{
//200~240
ledBrightness = 200;
ledBrightness += (pdmValue - 4000)/40;
}
else
{
ledBrightness = 0xFF;
}
return ledBrightness;
}
/****
*Step4:根据PDM数据来设定蓝灯亮度
****/
short maxVolume = 0;
void step_4()
{
unsigned char ledBrightness = 0x00;
if(samplesRead)
{
Serial.print("samplesRead is: \t");
Serial.println(samplesRead);
}
else
{
return;
}
maxVolume = 0;
for (unsigned int i = 0; i < samplesRead; i++)
{
Serial.print(sampleBuffer[i]);
Serial.print("\t");
if(sampleBuffer[i] < 0)
{
sampleBuffer[i] = abs(sampleBuffer[i]);
}
if(sampleBuffer[i] > maxVolume)
{
maxVolume = sampleBuffer[i] ;
}
}
Serial.print("\n");
Serial.print("maxVolume is: \t");
Serial.println(maxVolume);
ledBrightness = mapPDMToLED(maxVolume);
//int brightness = map(maxVolume, 0, 8096, 0, 255); // 将PDM值映射到PWM范围
Serial.print("ledBrightness is: \t");
Serial.println(255-ledBrightness);
analogWrite(bluePin,255-ledBrightness);
delay(10);
// clear the read count
samplesRead = 0;
}
【任务四图文说明】:本任务主要难点在于通过模拟输出来控制LED的亮度,会存在两个问题:A.模拟亮越高,LED亮度越低,这个如果没注意的话,会出现音量低时LED亮度高,音量高了反而LED亮度变低了,这个需要注意;B.音亮和LED的亮度变化,不能完全做线性映射,要分段进行线性映射,大致是下面个意思(也就是mapPDMToLED(maxVolume)函数的功能),类似于做了个分段线性拟合,这样做出来的效果,才会相对比较明显
【任务四实物图片】:
[localvideo]8209107ea4bdcc5067f65adf489cb083[/localvideo]
【可编译下载的代码】:https://download.eeworld.com.cn/detail/z75993971/635249
(4)对本活动的心得体会(包括意见或建议)
活动非常好,深刻的了解了Arduino的开发环境和应用方法,同时对IMU有了更具象的认识,在MIC输入方面,对PDM数据有了初步的认识,但是相关资料还是不太全面,想了解具体的增益配置(如何配,影响是什么),读到的PDM值其负值的含义是什么,还需要继续研究
另外,遇到了很多次程序下载完成后,运行正常,但是重新插拔后下电前的应用没有正常运行,按复位键复位后也不行,但是在多次插拔后又正常了,暂时没有找到原因,准备用JLINK连上调试一把,看下具体原因是什么
- 2024-12-15
-
加入了学习《【Follow me第二季第4期】任务合集-主板正反面识别,音量大小识别【z75993971】》,观看 【Follow me第二季第4期】任务合集-主板正反面识别,音量大小识别【z75993971】
-
上传了资料:
【Follow me第二季第4期】任务合集-主板正反面识别,音量大小识别【z75993971】
-
加入了学习《【Follow me第二季第4期】任务合集-主板正反面识别,音量大小识别【z75993971】》,观看 【Follow me第二季第4期】任务合集-主板正反面识别,音量大小识别【z75993971】