【Follow me第二季第4期】任务汇总_By CJ
[复制链接]
本帖最后由 andy11112 于 2024-12-29 21:48 编辑
大家好,以下是此次Follow me第二季第4期的任务汇总,欢迎提出宝贵意见并交流。
【视频汇总】:
必做任务一,0:13
必做任务二,1:55
必做任务三,2:57
选做任务一,3:37
【源码链接】:https://download.eeworld.com.cn/detail/andy11112/635456
【总体心得】:
有参加Follow me的活动,此次使用的板子是Nano RP2040 Connect,特点是尺寸小,集成度高,这次任务使用到了速度计、陀螺仪、RGB LED和麦克风模块,另外板上还有任务中未涉及的蓝牙和WiFi模块。通过此次活动任务,学习了在Arduino环境中进行相关功能的开发。
- 必做任务一:搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld!
1、【任务介绍】
首先搭建开发环境,然后是让三色LED闪烁,同时在串口中打印“Hello DigiKey & EEWorld!”。
1.1【开发环境搭建】
- 首先,下载编辑器。此次计划用Arduino进行开发,所以需要使用对应的编辑器。有桌面版和云端版两种选择,考虑避免网络稳定性的影响,此次我选择用桌面版。
- 从相关资料中(ABX00053-datasheet.pdf中的最后一页)可以找到桌面版编辑器的对应连接:https://www.arduino.cc/en/software
- 在页面中找到和自己系统匹配的下载链接。
- 下载后,运行安装包,完成后打开编辑器。可见如下界面,常用的快捷按钮包括:
a、【代码上传】将当前代码进行编译并上传到开发板中。
b、【串口绘图仪】将串口打印的信息,转换为坐标图形显示
c、【串口监视器】输入和输出串口信息
d、【项目文件夹】新建项目
e、【开发板管理器】安装和管理对应开发板所需要的内核包
f、【库管理器】安装和管理所需要的库
1.2【开发板连接和配置】
- 所需物料:这次活动中的全部任务,所需的物料只有开发板和Micro USB数据线。
- 将开发板通过USB线连接电脑后,在编辑器中选择对应开发板Nano RP2040 Connect。
- 编辑器会根据开发板状态,提示是否需要安装对应的Arduino Mbed OS RP2040 Boards内核包。
- 可以在菜单栏的 文件—>示例 中找到很多代码示例,用于实现特定功能的参考。
1.3【RGB闪烁和串口打印】
a、RGB是由WiFi模块直接控制,所以要引入WiFiNINA库,在代码头部包含如下代码:
#include <WiFiNINA.h>
b、在void setup()中定义3种颜色灯的引脚为输出。
c、在void loop()中,可以用digitalWrite控制RGB,High表示点亮,Low表示熄灭;也可以用analogWrite控制RGB,设置引脚输出范围255~0,其中0表示最亮,255表示最暗。
a、可以在示例中参考相关代码(文件—>示例—>01.Basics—>AnalogReadSerial)。
b、在void setup()中对串口做初始化。在void loop()中用Serial.println进行串口输出。
2、【软件流程图】
3、【代码片段】
#include <WiFiNINA.h>
void setup() {
//定义输出引脚
pinMode(LEDR, OUTPUT); //定义红灯控制引脚
pinMode(LEDG, OUTPUT); //定义绿灯控制引脚
pinMode(LEDB, OUTPUT); //定义蓝灯控制引脚
Serial.begin(9600); //设置串口波特率
}
void loop() {
//数字引脚方式写入
digitalWrite(LEDR, HIGH); //RED ON
delay(1000); //延时1秒
digitalWrite(LEDR, LOW); //RED OFF
digitalWrite(LEDG, HIGH); //GREEN ON
delay(1000);
digitalWrite(LEDG, LOW); //GREEN OFF
digitalWrite(LEDB, HIGH); //BLUE ON
delay(1000);
digitalWrite(LEDB, LOW); //BLUE OFF
delay(1000);
Serial.println("Hello DigiKey & EEWorld!"); //串口打印内容
}
4、【功能展示】
- 串口循环打印“Hello DigiKey & EEWorld!”。
- 必做任务二:学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据
1、【任务介绍】
1.1【IMU】学习
- IMU具有许多功能,其中包括一个机器学习核心,可用于运动检测,如自由落体、步数检测器、步数计数器、计步器。另外还内置了温度传感器。
- 【加速度计】是一种用于测量加速度的机电设备。这种力可以是静态的,如连续的重力,也可以是动态的,如许多移动的情况,以感知运动或振动。可以能够通过向上、向下、向左或向右倾斜板来读取板的相对位置以及角度。
- 【陀螺仪传感器】是一种可以测量物体方向和角速度的设备。陀螺仪比加速度计更先进,因为它可以测量物体的倾斜和横向方向,而加速度计只能测量线性运动。陀螺仪传感器也称为“角速率传感器”或“角速度传感器”。可使用陀螺仪作为施加到板上的力方向的指示器。
1.2【IMU】使用
#include <Arduino_LSM6DSOX.h>
- 在void setup()中,用IMU.begin()做初始化,用IMU.accelerationSampleRate()设置采样频率。
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
1.3【IMU】读取数据
float x, y, z;
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);
}
float x, y, z;
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(x, y, z);
}
2、【软件流程图】
3、【代码片段】
#include <Arduino_LSM6DSOX.h> //导入IMU库
float Ax, Ay, Az; //定义加速度计变量
float Gx, Gy, Gz; //定义陀螺仪变量
void setup() {
Serial.begin(9600); //初始化串口通信,波特率为9600
while(!Serial); //等待串口连接
if (!IMU.begin()) { //初始化IMU
Serial.println("Failed to initialize IMU!"); //如果初始化失败,打印错误信息
while (1); //停止程序运行
}
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate()); //打印加速度计采样率,单位为Hz
Serial.println("Hz");
Serial.println();
Serial.print("Gyroscope sample rate = ");
Serial.print(IMU.gyroscopeSampleRate()); //打印陀螺仪采样率,单位为Hz
Serial.println("Hz");
Serial.println();
}
void loop() {
if (IMU.accelerationAvailable()) { //检查加速度计数据是否可用,如果可用,则读取数据,否则跳过
IMU.readAcceleration(Ax, Ay, Az); //读取加速度计数据,将数据存储到Ax,Ay,Az变量中
Serial.println("Accelerometer data: ");
Serial.print(Ax);
Serial.print('\t');
Serial.print(Ay);
Serial.print('\t');
Serial.println(Az);
Serial.println();
}
if (IMU.gyroscopeAvailable()) { //检查陀螺仪数据是否可用,如果可用,则读取数据,否则跳过
IMU.readGyroscope(Gx, Gy, Gz); //读取陀螺仪数据,将数据存储到Gx,Gy,Gz变量中
Serial.println("Gyroscope data: ");
Serial.print(Gx);
Serial.print('\t');
Serial.print(Gy);
Serial.print('\t');
Serial.println(Gz);
Serial.println();
}
delay(500);
}
4、【成果展示】
4.1【加速计】
- 开发板处于不同的静止姿态,仅有重力作用,可以从加速计中读出不同方向上的数据。
- 必做任务三:学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形
1、【任务介绍】
1.1【PDM】学习
- 型号:MP34DT06JTR。这是是一款紧凑型、低功耗、带IC接口的全向数字MEMS麦克风。使用PDM(脉冲密度调制)用二进制信号表示模拟信号。如下是关键参数。
信噪比:64dB
灵敏度:-26dBFS±3dB
温度范围:-40至85°C
- PDM库包含在Arduino Mbed OS Nano Board Package中,无需额外安装PDM库。
1.2【PDM使用】
- 菜单栏 文件 > 示例 > PDM > PDMSerialPlotter ,可以找到对应的参考代码。
- 首先设置声道和采样率。PDM通过回调函数将接收到的声音数据写入缓存中,然后读取数据,通过串口打印出来以及绘图仪显示出来。
- 由于绘图仪的刷新率较快,为了更方便观察波形,每次输出之间增加延时语句delay(100)。
2、【软件流程图】
3、【代码片段】
#include <PDM.h> //导入PDM库
static const char channels = 1; //单声道,如果使用双声道,则将1改为2
static const int frequency = 16000; //采样频率,默认为16000Hz
short sampleBuffer[512]; //缓冲区,用于读取采样数据,每个采样数据是16位,即2字节,所以缓冲区大小为512*2=1024字节
volatile int samplesRead; //采样数据读取计数器,用于记录已经读取的采样数据数量,该变量是volatile的,因为它是被中断服务程序修改的
void setup() {
Serial.begin(9600); //初始化串口通信,波特率为9600
while (!Serial); //等待串口连接
PDM.onReceive(onPDMdata); //设置在准备读取新PDM数据时调用的回调函数,onPDMdata函数将在PDM数据接收中断时会被调用
if (!PDM.begin(channels, frequency)) { //初始化PDM,设置采样通道数和采样频率,如果初始化失败,则输出错误信息并停止程序
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop() {
if (samplesRead) { //如果已经读取了采样数据,则进行处理
for (int i = 0; i < samplesRead; i++) { //遍历采样数据,将每个采样数据输出到串口
if(channels == 2) { //如果使用双声道,则将每个采样数据分为左右两个声道,分别输出
Serial.print("L:"); //输出左声道采样数据
Serial.print(sampleBuffer[i]); //输出左声道采样数据
Serial.print(" R:"); //输出右声道采样数据
i++; //右声道采样数据在左声道采样数据之后,所以需要将i加1
}
Serial.println(sampleBuffer[i]); //输出采样数据
delay(100); //延时,降低串口打印频率,是串口绘图仪的刷新速率降低,方便查看
}
samplesRead = 0; //重置采样数据读取计数器
}
}
void onPDMdata() { // PDM数据接收回调函数
int bytesAvailable = PDM.available(); //获取当前可用的采样数据字节数
PDM.read(sampleBuffer, bytesAvailable); //将采样数据读取到缓冲区中,缓冲区大小为bytesAvailable字节,即bytesAvailable/2个采样数据
samplesRead = bytesAvailable / 2; //更新采样数据读取计数器,采样数据数量为bytesAvailable/2个
}
4、【成果展示】
- 选做任务一:通过RGB LED不同颜色、亮度显示PDM麦克风收到的声音大小
1、【任务介绍】
brightness = map(constrain(abs(sampleBuffer[i]),0,32700), 0, 32700, 255, 0); //将采样数据映射到255-0的范围,用于控制RGB灯的亮度
//麦克风采样值有正和负,所以取绝对值
analogWrite(LEDR, brightness); //将亮度值写入RGB灯的红色通道,控制红色通道的亮度
analogWrite(LEDG, brightness); //将亮度值写入RGB灯的绿色通道,控制绿色通道的亮度
analogWrite(LEDB, brightness); //将亮度值写入RGB灯的蓝色通道,控制蓝色通道的亮度
2、【软件流程图】
3、【代码片段】
#include <PDM.h> //导入PDM库
#include <WiFiNINA.h> //导入WiFiNINA库,用于RGB的控制
static const char channels = 1; //单声道,如果使用双声道,则将1改为2
static const int frequency = 16000; //采样频率,默认为16000Hz
short sampleBuffer[512]; //缓冲区,用于读取采样数据,每个采样数据是16位,即2字节,所以缓冲区大小为512*2=1024字节
volatile int samplesRead; //采样数据读取计数器,用于记录已经读取的采样数据数量,该变量是volatile的,因为它是被中断服务程序修改的
int brightness = 0; //RGB灯的亮度,用于控制RGB灯的亮度
void setup() {
Serial.begin(9600); //初始化串口通信,波特率为9600
while (!Serial); //等待串口连接
pinMode(LEDR, OUTPUT); //设置RGB灯的引脚为输出模式
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
PDM.onReceive(onPDMdata); //设置在准备读取新PDM数据时调用的回调函数,onPDMdata函数将在PDM数据接收中断时会被调用
if (!PDM.begin(channels, frequency)) { //初始化PDM,设置采样通道数和采样频率,如果初始化失败,则输出错误信息并停止程序
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop() {
if (samplesRead) { //如果已经读取了采样数据,则进行处理
for (int i = 0; i < samplesRead; i++) { //遍历采样数据,将每个采样数据输出到串口
if(channels == 2) { //如果使用双声道,则将每个采样数据分为左右两个声道,分别输出
Serial.print("L:"); //输出左声道采样数据
Serial.print(sampleBuffer); //输出左声道采样数据
Serial.print(" R:"); //输出右声道采样数据
i++; //右声道采样数据在左声道采样数据之后,所以需要将i加1
}
Serial.println(sampleBuffer); //输出采样数据
brightness = map(constrain(abs(sampleBuffer[i]),0,32700), 0, 32700, 255, 0); //将采样数据映射到255-0的范围,用于控制RGB灯的亮度
//麦克风采样值有正和负,所以取绝对值
analogWrite(LEDR, brightness); //将亮度值写入RGB灯的红色通道,控制红色通道的亮度
analogWrite(LEDG, brightness); //将亮度值写入RGB灯的绿色通道,控制绿色通道的亮度
analogWrite(LEDB, brightness); //将亮度值写入RGB灯的蓝色通道,控制蓝色通道的亮度
Serial.print("The brightness of RGB is: ");
Serial.println(brightness); //输出RGB灯的亮度值
delay(100);
}
samplesRead = 0; //重置采样数据读取计数器
}
}
void onPDMdata() { // PDM数据接收回调函数
int bytesAvailable = PDM.available(); //获取当前可用的采样数据字节数
PDM.read(sampleBuffer, bytesAvailable); //将采样数据读取到缓冲区中,缓冲区大小为bytesAvailable字节,即bytesAvailable/2个采样数据
samplesRead = bytesAvailable / 2; //更新采样数据读取计数器,采样数据数量为bytesAvailable/2个
}
4、【成果展示】
- 串口输出麦克风采样值,以及RGB亮度设置值(255~0范围,数值越小,亮度越高)。
|