- 2024-12-27
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 打响指报温度
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 Arduino NANO RP2040演示合集
-
回复了主题帖:
2025年测评中心,DigiKey得捷赞助继续,欢迎跟帖推你期待的上线的测品啦~
有没有FPGA啊
- 2024-12-25
-
发表了主题帖:
【Follow me第二季第4期】汇总提交帖:全部任务
本帖最后由 yilonglucky 于 2024-12-27 11:16 编辑
视频合集:
视频切片可参考大学堂视频合集:
【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
代码下载合集:
Follow me第二季第4期代码合集ARDUINO NANO RP2040 CONNECT-嵌入式开发相关资料下载-EEWORLD下载中心
前置任务:物料准备、环境部署
得捷订单
物料
作用
价格
ARDUINO NANO RP2040 CONNECT
Arduino主板
¥239.32
MCP9808 TEMP I2C BREAKOUT BRD
MCP9808温度模块
¥41.71
ARDUINO NANO STACKABLE HEADERS
Nano用双向长排针
¥14.25
自购物料
物料
作用
价格
USB数据线
连接Arduino与电脑
杜邦线若干
连接各个模块
SSD1306模块
OLED显示屏
BMP085模块
测量气压强度
继电器模组
IO控制大电流设备
百为语音播放模块
播放语音助手的提示音
TTS模块
文字转语音模块
软硬件环境
Arduino IDE官网下载网址: https://www.arduino.cc/en/software
本文档使用的版本是2.3.3.
使用USB数据线将ARDUINO NANO RP2040 CONNECT连接到PC后,在自动化安装完成的IDE中点击工具>获得开发板信息后能弹出如下图的提示窗口,则说明软硬件开发环境已经准备就绪,否则可以在IDE中指定别的COM后进行尝试。
知识准备
电源部分
在使用Arduino Nano有可能需要从主板引出电源供外围器件使用,因此需要先了解下主板的供电情况。
Arduino Nano RP2040 Connect本身使用的电源芯片是MP2322GQH,支持输入电压范围是3-22V,实际输入4V到22V时可以为负载提供3.3V、最大1A的电流。
板载的Micro USB接口已经将VBus引入到LDO前端的二极管前,因此,当不使用USB电源输入时,VIN引脚也可以同时接入大于5V的电压而不用担心烧坏USB部分。
还有一个细节是VBus到排针默认断开的,如果需要使用请自己进行短接。
这样,外围器件就可以从主板上取到5V或者3.3V的电源。
GPIO
本期活动发放的开发板是Arduino Nano RP2040 Connect,这块主板上的主芯片是树莓派的RP2040,其GPIO基本上都可以与各种通信总线进行复用。根据实际电路可以知道:在尝试使用nano控制外部继电器时发现实际硬件并不是任意一个IO都适合,现整理资料如下。
RP2040的手册中有总结到该芯片支持30个多功能GPIO:
然后找到RP2040的芯片引脚图,图中分别有GPIO 0~29:
然后分析原理图汇总结果如下:
RP2040
pin number
RP2040 GPIO
pinMode
功能
是否支持PWM
排插
硬件原理图
备注
2
GPIO0
UART1 TX
JP3.1
TX
3
GPIO1
UART1 RX
JP3.2
RX
4
GPIO2
直连+TP
NINA GPIO0
5
GPIO3
直连+TP
RSTN_NINA
6
GPIO4
12
JP3.15
SPI RX?
7
GPIO5
10
PWM
JP3.13
D10
8
GPIO6
13
LED_BUILTIN
PWM
JP2.1
SPI CLK
9
GPIO7
11
JP3.14
SPI TX?
10
11
GPIO8
UART1 TX
直连+TP
SPI1 CIPO
12
GPIO9
UART1 RX
直连+TP
SPI1 CS
13
GPIO10
直连
SPI1 ACK
缺TP
14
GPIO11
直连
SPI1 COPI
缺TP
15
GPIO12
18
I2C SDA
JP2.8
A4
16
GPIO13
19
I2C SCL
JP2.9
A5
17
GPIO14
18
GPIO15
3
PWM
JP3.6
D3
27
GPIO16
4
PWM
JP3.7
D4
28
GPIO17
5
PWM
JP3.8
D5
29
GPIO18
6
PWM
JP3.9
D6
30
GPIO19
7
PWM
JP3.10
D7
31
GPIO20
8
PWM
JP3.11
D8
32
GPIO21
9
PWM
JP3.12
D9
34
GPIO22
PDMDIN
直连
缺TP
35
GPIO23
PDMCLK
直连
缺TP
36
GPIO24
直连
INT1
缺TP
37
GPIO25
2
PWM
JP3.5
D2
38
GPIO26
14
ADC0
JP2.4
39
GPIO27
15
ADC1
JP2.5
40
GPIO28
16
ADC2
JP2.6
41
GPIO29
17
ADC3
JP2.7
56
JP2.13
SPI_CSn
黄色是目前主板已经确定使用功能的,比如UART,I2C,PDM
紫色是RP2040对应的4路ADC
蓝色对应SPI接口
剩下的是可以在主板排插引出来的,适合控制外部的IO,且同时支持PWM。
GPIO6对应的是板载的提示灯,实际也可以使用,但不推荐。
综上,适合通过pinMode API控制的RP2040的管脚编号有2~10这个9个。
注:A4~A7是nina芯片映射出来的,不是RP2040直接控制的。
注:RGB对应的三根GPIO也不是RP2040直连的。
UART总线
本期活动发放的开发板是Arduino Nano RP2040 Connect,这块主板上的主芯片是树莓派的RP2040。
RP2040是支持两路UART的。
Arduino Nano RP2040 Connect主板的pinout图中有标注一路TX、RX:
另外参考RP2040 GPIO功能图:
可知这一路硬件连线实际使用的是RP2040的UART0,但是在Arduino IDE中如果想使用这一路硬件的话,需要使用对应的代码对象Serial1。
Arduino Nano RP2040 Connect的USB是支持CDC类型,可以直接使用Arduino IDE的Serial来控制。
所以我猜测了两种UART的实现接口,不知道Arduino在封装时实际是哪一种:
硬件
Arduino IDE初始化代码
RP2040 UART控制器
JP3.1
Serial1.begin(115200);
UART0
TX
GPIO0
JP3.2
RX
GPIO1
USB CDC
Serial.begin(115200);
UART1
TX
endpoint
RX
endpoint
或者
硬件
Arduino IDE初始化代码
RP2040 UART控制器
JP3.1
Serial1.begin(115200);
UART0
TX
GPIO0
JP3.2
RX
GPIO1
USB CDC
Serial.begin(115200);
?
TX
endpoint
RX
endpoint
?
?
UART1
TX
?
?
RX
?
I2c总线
本期活动发放的开发板是Arduino Nano RP2040 Connect,这块主板上的主芯片是树莓派的RP2040。
RP2040是有两个独立的i2c控制器的。
而Arduino Nano是将i2c0复用到GPIO16和GPIO17使用的。
RP2040 GPIO功能图:
在Arduino IDE中可以直接使用Wire库来使用这个i2c控制器。
根据Arduino Nano原理图知其已经连接了两个i2c slave,一个是加速度陀螺仪,一个是认证芯片,我另外连接了两个i2c slave。
前两者硬件原理图:
在实际使用时,可以通过i2c_scanner来遍历i2c总线上的所有slave是否在位,并且将所有设备清单列出来。
对应代码请从本帖附件下载,或参考【Follow me第二季第4期】Arduino RP2040之i2c总线附i2c_scanner - DigiKey得捷技术专区 - 电子工程世界-论坛
必做任务一:Blink三色LED、串口打印
任务介绍
本任务需要点亮RGB三色灯,并且在串口打印出字符串“Hello DigiKey & EEWorld!”。
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
另外一组USB转串口
设计思路
首先根据硬件原理图可知RGB三色灯没有直接连接到主控RP2040上,三色灯是连接在WiFi芯片的,因此运行的代码应该是通知WiFi芯片去控制三色灯。
图表 1 三色灯连接情况硬件原理图
在安装WiFi芯片对应的Nina库后,可以像控制本身GPIO一样去控制WiFi芯片的IO,此时可以将WiFi芯片当作是一块IO扩展芯片。对于上层应用而言,可以忽略主控RP2040与WiFi芯片具体是怎么连接的。
为了简化代码,特将RGB颜色编码如下:
Index
R
G
B
0
0
0
0
1
0
0
1
2
0
1
0
3
0
1
1
4
1
0
0
5
1
0
1
6
1
1
0
7
1
1
1
软件流程图
Setup函数负责初始化硬件资源,输出提示信息到串口后,启动两个任务,分别控制RGB三色灯和主板默认提示灯。
主要代码片段
// Include Scheduler since we want to manage multiple tasks.
#include <Scheduler.h>
#include "WiFiNINA.h"
#define led1 LEDR
#define led2 LEDG
#define led3 LEDB
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial1.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
// Setup the 3 pins as OUTPUT
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
Serial1.println("\n~~~~~~~~~~ RGB Blink Demo on Arduino Nano RP2040 ~~~~~~~~~~");
Serial.println("Hello DigiKey & EEWorld!");
Serial1.println("Hello DigiKey & EEWorld!");
Serial1.println("Please input the index number to blink the RGB LED:");
Serial1.println("IndexRGB");
Serial1.println("0:000");
Serial1.println("1:001");
Serial1.println("2:010");
Serial1.println("3:011");
Serial1.println("4:100");
Serial1.println("5:101");
Serial1.println("6:110");
Serial1.println("7:111");
Scheduler.startLoop(loop1);
Scheduler.startLoop(loop2);
}
/*
* Name: set_rgb
* Para: rgb index
* bit2: red led
* bit1: green led
* bit0: blue led
*/
void set_rgb(char c) {
int r, g, b;
r = (c >> 2) % 2;
g = (c >> 1) % 2;
b = (c % 2);
digitalWrite(led1, (PinStatus)r);
digitalWrite(led2, (PinStatus)g);
digitalWrite(led3, (PinStatus)b);
}
void loop() {
if (Serial1.available()) {
char c = Serial1.read();
set_rgb(c);
}
// IMPORTANT:
// We must call 'yield' at a regular basis to pass
// control to other tasks.
yield();
}
void loop1() {
set_rgb(4);
delay(1000);
set_rgb(2);
delay(1000);
set_rgb(1);
delay(1000);
}
void loop2() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
功能展示
本视频演示了ARDUINO NANO RP2040 CONNECT的Blink RGB与UART功能,开机后从USB串口和排针串口打印出提示语,并同步闪烁RGB。另外可以从排针串口输入‘1’、‘2’、‘4’来打开对应颜色,输入‘0’来关闭RGB。
请参考网址:Blink RGB与UART功能演示-ARDUINO NANO RP2040 CONNECT-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
源代码下载地址:ARDUINO NANO RP2040 CONNECT点亮三色灯-嵌入式开发相关资料下载-EEWORLD下载中心
使用另一组串口收到的消息截图:
必做任务二:学习IMU基础知识
任务介绍
学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据。
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
设计思路
ARDUINO NANO RP2040 CONNECT主板搭载了ST的LSM6DSOX,具体型号是LSM6DSOXTR,是一款继承了加速度与陀螺仪的MEMS芯片。
在Arduino IDE中需要先安装对应的lib库:
图表 2 安装IMU库成功截图
首先来确定一下芯片与主板的安装方向:
图表 3 加速度三轴方向说明
图表 4 陀螺仪三轴旋转正方向
软件流程图
主要代码片段
#include <Arduino_LSM6DSOX.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1)
;
}
}
void loop() {
// put your main code here, to run repeatedly:
float accx, accy, accz;
float picth, roll, yaw;
float temperature;
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(accx, accy, accz);
Serial.print(accx);
Serial.print('\t');
Serial.print(accy);
Serial.print('\t');
Serial.print(accz);
Serial.print('\t');
}
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(picth, roll, yaw);
Serial.print(picth);
Serial.print('\t');
Serial.print(roll);
Serial.print('\t');
Serial.print(yaw);
Serial.print('\t');
}
#if 1
if (IMU.temperatureAvailable()) {
IMU.readTemperatureFloat(temperature);
Serial.print(temperature);
}
#endif
Serial.println();
delay(100);
}
功能展示
IMU功能演示视频链接地址:IMU功能演示与方向讲解-ARDUINO NANO RP2040 CONNECT-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
加速度的数值演示视频地址:IMU加速度数值演示-ARDUINO NANO RP2040 CONNECT-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
陀螺仪的数值演示视频地址:IMU陀螺仪数值演示-ARDUINO NANO RP2040 CONNECT-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
源代码下载地址:ARDUINO NANO RP2040 CONNECT打印IMU原始数据-嵌入式开发相关资料下载-EEWORLD下载中心
实际打印IMU数值曲线截图:
必做任务三:学习PDM麦克风相关技术知识
任务简介
学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。
在Arduino主板上有一个ST的MEMS数字麦克风芯片MP34DT06J,可以将声音编码PDM传输给主控芯片。麦克风芯片在主板上的对应位置如下图所示:
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
继电器
设计思路
首先通过原理图可知该麦克风LR引脚拉高,所以这颗麦克风在CLK为高电平时数据线生效,应该是对应右通道的声音。
TCK周期支持308到1000ns,对应频率即1MHz到3.247MHz之间。
图表 5 PDM全览图
图表 6 PDM信号线测量过孔位置
然后设计代码将采集到的数据存入一个1024个元素的数组中。当检测到收到的声音超过阈值时则切换LED的状态和继电器的通断状态。
实际抓到的PDM信号线的波形:
软件流程图
主要代码片段
#include <WiFiNINA.h>
#include <PDM.h>
bool LED_SWITCH = false;
// default number of output channels
static const char channels = 1;
// default PCM output frequency
static const int frequency = 14000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[1024];
#define PIN_LED (13u)
#define PIN_S (10u)
// Number of audio samples read
volatile int samplesRead;
void setup() {
Serial.begin(9600);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_S, OUTPUT);
//while (!Serial);
Serial.println("***************************************************************");
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Optionally set the gain
// Defaults to 20 on the BLE Sense and -10 on the Portenta Vision Shields
// PDM.setGain(30);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shields
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1)
;
}
}
void loop() {
// Wait for samples to be read
if (samplesRead) {
// Print samples to the serial monitor or plotter
for (int i = 0; i < samplesRead; i++) {
if (channels == 2) {
Serial.print("L:");
Serial.print(sampleBuffer[i]);
Serial.print(" R:");
i++;
}
Serial.println(sampleBuffer[i]);
if (sampleBuffer[i] > 10000 || sampleBuffer[i] <= -10000) {
LED_SWITCH = !LED_SWITCH;
if (LED_SWITCH) {
Serial.println();
digitalWrite(PIN_LED, HIGH);
digitalWrite(PIN_S, HIGH);
Serial.println("ON!");
Serial.println();
delay(500);
} else {
Serial.println();
digitalWrite(PIN_LED, LOW);
digitalWrite(PIN_S, LOW);
Serial.println("OFF!");
Serial.println();
delay(500);
}
}
}
// Clear the read count
samplesRead = 0;
}
}
/**
Callback function to process the data from the PDM microphone.
NOTE: This callback is executed as part of an ISR.
Therefore using `Serial` to print messages inside this function isn't supported.
* */
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = PDM.available();
// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
功能展示
本视频演示了ARDUINO NANO RP2040 CONNECT的PDM应用,通过USB串口打印音频数值,同时利用Arduino IDE自带的串口绘图工具将波形绘制出来。
当Arduino检测到大音量,比如打响指指,打开或关闭LED灯,打开或关闭继电器。
视频链接地址:PDM功能演示-ARDUINO NANO RP2040 CONNECT-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
源代码下载地址:ARDUINO NANO RP2040 CONNECT声音检测打开LED和继电器-嵌入式开发相关资料下载-EEWORLD下载中心
打印声音曲线截图:
选做任务一:RGB LED显示声音大小
项目简介
通过RGB LED不同颜色、亮度显示PDM麦克风收到的声音大小。将收到声音的大小,通过BUILDIN LED的亮度显示出来,同时根据声音的大小范围点亮不同颜色的RGB LED。
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
设计思路
在必做任务三中可以得到PDM上报的声音大小的数值,在实际显示时效果不是太好,因此在本次任务中,首先将一组数据先计算平均值,然后将平均值换算到0~255这个范围内,就可以直接通过LED的亮度显示出来。
软件流程图
主要代码片段
#include <WiFiNINA.h>
#include <PDM.h>
bool LED_SWITCH = false;
// default number of output channels
static const char channels = 1;
// PCM output frequency
static const int frequency = 14000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[1024];
short avg;
long minv,maxv;
short led255;
#define PIN_LED (13u)
#define PIN_S (10u)
// Number of audio samples read
volatile int samplesRead;
/*
* Name: set_rgb
* Para: rgb index
* bit2: red led
* bit1: green led
* bit0: blue led
*/
void set_rgb(char c) {
int r, g, b;
r = (c >> 2) % 2;
g = (c >> 1) % 2;
b = (c % 2);
digitalWrite(LEDR, (PinStatus)r);
digitalWrite(LEDG, (PinStatus)g);
digitalWrite(LEDB, (PinStatus)b);
}
/**
Callback function to process the data from the PDM microphone.
NOTE: This callback is executed as part of an ISR.
Therefore using `Serial` to print messages inside this function isn't supported.
* */
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = PDM.available();
// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
void setup() {
Serial.begin(9600);
//pinMode(PIN_LED, OUTPUT);
pinMode(PIN_S, OUTPUT);
while (!Serial)
;
Serial.println("***************************************************************");
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Optionally set the gain
// Defaults to 20 on the BLE Sense and -10 on the Portenta Vision Shields
// PDM.setGain(30);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shields
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1)
;
}
minv=maxv=0;
}
void loop() {
// Wait for samples to be read
if (samplesRead) {
//Serial.println(samplesRead);
//return;
avg = 0;
// Print samples to the serial monitor or plotter
for (int i = 0; i < samplesRead; i++) {
if (channels == 2) {
Serial.print("L:");
Serial.print(sampleBuffer[i]);
Serial.print(" R:");
i++;
}
//Serial.print(sampleBuffer[i]);
//Serial.print('*');
avg += (sampleBuffer[i] - avg) / (i + 1);
#ifdef WHATEVEREEEEEE
//if (sampleBuffer[i] > 10000 || sampleBuffer[i] <= -10000) {
if (abs(sampleBuffer[i]) > 10000) {
LED_SWITCH = !LED_SWITCH;
if (LED_SWITCH) {
Serial.println();
digitalWrite(PIN_LED, HIGH);
digitalWrite(PIN_S, HIGH);
Serial.println("ON!");
Serial.println();
delay(10000);
} else {
Serial.println();
digitalWrite(PIN_LED, LOW);
digitalWrite(PIN_S, LOW);
Serial.println("OFF!");
Serial.println();
delay(10000);
}
}
#endif
}
//Serial.println(avg);
led255 = map(abs(avg), 0, 65535, 0, 255);
if(led255 > maxv)
{
maxv = led255;
}
if(minv > led255)
{
minv = led255;
}
Serial.print(minv);
Serial.print('\t');
Serial.print(led255);
Serial.print('\t');
Serial.println(maxv);
analogWrite(PIN_LED, led255);
if (led255 > 15) {
set_rgb(7);
//digitalWrite(PIN_LED, LOW);
} else if (led255 > 10) {
set_rgb(4);
//digitalWrite(PIN_LED, LOW);
} else if (led255 > 5) {
set_rgb(2);
//digitalWrite(PIN_LED, LOW);
} else {
set_rgb(1);
//digitalWrite(PIN_LED, HIGH);
}
// Clear the read count
samplesRead = 0;
}
}
功能展示
视频链接地址:PDM波形演示-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
效果截图:
自选任务A:打响指触发播报温度
项目简介
上一个任务已经可以识别外界声音是否超过某个阈值,本次任务在检测到外部声音超过阈值后则播报一次通过MCP9808读到的温度。
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
MCP9808
TTS模块
软件流程图
主要代码片段
#include <WiFiNINA.h>
#include <PDM.h>
#include <Adafruit_MCP9808.h>
Adafruit_MCP9808 sensor;
bool LED_SWITCH = false;
// default number of output channels
static const char channels = 1;
// PCM output frequency
static const int frequency = 14000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[1024];
#define PIN_LED (13u)
#define PIN_S (10u)
// Number of audio samples read
volatile int samplesRead;
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
//语音模块默认 GBK 编码, arduino 默认是 utf 编码
//需要先发<C>1 设置语音模块编码
Serial1.print("<C>1");
delay(500);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_S, OUTPUT);
//while (!Serial)
;
Serial.println("***************************************************************");
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Optionally set the gain
// Defaults to 20 on the BLE Sense and -10 on the Portenta Vision Shields
// PDM.setGain(30);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shields
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1)
;
}
if (!sensor.begin()) {
Serial.println("Failed to find Adafruit MCP9808 chip");
while (1) { delay(10); }
}
Serial.println("MCP9808 Found!");
Serial1.println("初始化完成");
}
void loop() {
char buffer[500];
sensors_event_t event;
sensor.getEvent(&event);
// Wait for samples to be read
if (samplesRead) {
//Serial.println(samplesRead);
//return;
// Print samples to the serial monitor or plotter
for (int i = 0; i < samplesRead; i++) {
if (channels == 2) {
Serial.print("L:");
Serial.print(sampleBuffer[i]);
Serial.print(" R:");
i++;
}
//Serial.println(sampleBuffer[i]);
if (sampleBuffer[i] > 10000 || sampleBuffer[i] <= -10000) {
//Serial.print(event.temperature);
memset(buffer, 0, sizeof(buffer));
//event.temperature = -5.8;
if (event.temperature > 0) {
sprintf(buffer, "现在温度是%.1f摄氏度", event.temperature);
} else {
sprintf(buffer, "现在温度是零下%.1f摄氏度",-1.0*event.temperature);
}
Serial.println(buffer);
Serial1.print(buffer);
LED_SWITCH = !LED_SWITCH;
if (LED_SWITCH) {
Serial.println();
digitalWrite(PIN_LED, HIGH);
digitalWrite(PIN_S, HIGH);
Serial.println("ON!");
Serial.println();
delay(6000);
} else {
Serial.println();
digitalWrite(PIN_LED, LOW);
digitalWrite(PIN_S, LOW);
Serial.println("OFF!");
Serial.println();
delay(6000);
}
}
}
// Clear the read count
samplesRead = 0;
}
//yield();
//delay(100);
}
功能展示
视频链接:打响指报温度-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
自选任务B:利用IMU数据实现鼠标功能
项目简介
将Arduino NANO模拟成USB鼠标后,将IMU数据转换成鼠标移动动作。
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
设计思路
Arduino NANO可以模拟成为一个USB鼠标,可以将IMU重力加速度三轴数据转换为鼠标的移动动作。当Z轴数据为负数时,说明主板背面朝上,则不发送鼠标移动动作,给真正的鼠标控制留出窗口。当Z轴数据为正数时,将X轴和Y轴的数据转换为鼠标的上下左右移动动作,从而实现鼠标的移动控制。
软件流程图
主要代码片段
#include <Arduino_LSM6DSOX.h>
#include "PluggableUSBHID.h"
#include "USBMouse.h"
USBMouse Mouse;
#define STEP 80
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1)
;
}
}
void loop() {
// put your main code here, to run repeatedly:
float accx, accy, accz;
float picth, roll, yaw;
float temperature;
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(accx, accy, accz);
Serial.print(accx);
Serial.print('\t');
Serial.print(accy);
Serial.print('\t');
Serial.print(accz);
Serial.print('\t');
}
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(picth, roll, yaw);
Serial.print(picth);
Serial.print('\t');
Serial.print(roll);
Serial.print('\t');
Serial.print(yaw);
Serial.print('\t');
}
#if 1
if (IMU.temperatureAvailable()) {
IMU.readTemperatureFloat(temperature);
Serial.print(temperature);
}
#endif
Serial.println();
if(accz > 0.2)
{
Mouse.move(0,accy*STEP);
Mouse.move(-accx*STEP, 0);
}
delay(25);
}
功能展示
视频演示地址:利用IMU实现鼠标控制-ARDUINO NANO RP2040 CONNECT-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
自选任务C:语音识别助手
项目简介
VR全称voice recognizing,该任务音特定关键词的检测,即实现语音助手功能。
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
继电器
语音播放模块
OLED显示屏
设计思路
Arduino Nano主板自带PDM,当提前预置声音特征值到主板内时,可以实现声音特定关键词的检测,即实现语音助手功能。
由于VR语音库的license限制,另外申请的试用版license的VR指令每次要间隔20秒,使用体验不好。因此在LED control的demo上进行改装,将蓝色灯的打开新绑定GPIO5控制的一路继电器,在关闭LED的命令绑定关闭继电器动作。
使用OLED显示屏作为提词器,提示用户当前可以说出的语音指令。
同时使用UART控制语音播放模块,用来在合适的时机播放语音反馈声音,形成交互效果。
软件流程图
主要代码片段
const char voicecmd[21][7] = {
{ 0x7E, 0x05, 0x41, 0x00, 0x01, 0x45, 0xEF }, //播放0001
{ 0x7E, 0x05, 0x41, 0x00, 0x02, 0x46, 0xEF }, //播放0002
{ 0x7E, 0x05, 0x41, 0x00, 0x03, 0x47, 0xEF }, //播放0003
{ 0x7E, 0x05, 0x41, 0x00, 0x04, 0x40, 0xEF }, //播放0004
{ 0x7E, 0x05, 0x41, 0x00, 0x05, 0x41, 0xEF }, //播放0005
{ 0x7E, 0x05, 0x41, 0x00, 0x06, 0x42, 0xEF }, //播放0006
{ 0x7E, 0x05, 0x41, 0x00, 0x07, 0x43, 0xEF }, //播放0007
{ 0x7E, 0x05, 0x41, 0x00, 0x08, 0x4C, 0xEF }, //播放0008
{ 0x7E, 0x05, 0x41, 0x00, 0x09, 0x4D, 0xEF }, //播放0009
{ 0x7E, 0x05, 0x41, 0x00, 0x0A, 0x4E, 0xEF }, //播放0010
{ 0x7E, 0x05, 0x41, 0x00, 0x0B, 0x4F, 0xEF }, //播放0011
{ 0x7E, 0x05, 0x41, 0x00, 0x0C, 0x48, 0xEF }, //播放0012
{ 0x7E, 0x05, 0x41, 0x00, 0x0D, 0x49, 0xEF }, //播放0013
{ 0x7E, 0x05, 0x41, 0x00, 0x0E, 0x4A, 0xEF }, //播放0014
{ 0x7E, 0x05, 0x41, 0x00, 0x0F, 0x4B, 0xEF }, //播放0015
{ 0x7E, 0x05, 0x41, 0x00, 0x10, 0x54, 0xEF }, //播放0016
{ 0x7E, 0x05, 0x41, 0x00, 0x11, 0x55, 0xEF }, //播放0017
{ 0x7E, 0x05, 0x41, 0x00, 0x12, 0x56, 0xEF }, //播放0018
{ 0x7E, 0x05, 0x41, 0x00, 0x13, 0x57, 0xEF }, //播放0019
{ 0x7E, 0x05, 0x41, 0x00, 0x14, 0x50, 0xEF }, //播放0020
{ 0x7E, 0x05, 0x41, 0x00, 0x15, 0x51, 0xEF }, //播放0021
};
// Callback function for VR engine
void VRCallback(int nFlag, int nID, int nScore, int nSG, int nEnergy) {
if (nFlag == DSpotterSDKHL::InitSuccess) {
//ToDo
Serial.println("InitSuccess");
} else if (nFlag == DSpotterSDKHL::GetResult) {
/*
When getting an recognition result,
the following index and scores are also return to the VRCallback function:
nID The result command id
nScore nScore is used to evaluate how good or bad the result is.
The higher the score, the more similar the voice and the result command are.
nSG nSG is the gap between the voice and non-command (Silence/Garbage) models.
The higher the score, the less similar the voice and non-command (Silence/Garbage) models are.
nEnergy nEnergy is the voice energy level.
The higher the score, the louder the voice.
*/
switch (nID) {
case COMMAND_LED_GREEN:
Serial.println("Copy That: LED_GREEN");
Serial1.write(voicecmd[15], 7);
LED_RGB_Green();
break;
case COMMAND_LED_RED:
Serial.println("Copy That: LED_RED");
Serial1.write(voicecmd[15], 7);
LED_RGB_Red();
break;
case COMMAND_LED_BLUE:
Serial.println("Copy That: LED_BLUE");
Serial1.write(voicecmd[15], 7);
LED_RGB_Blue();
Serial.println("Switch ON!");
digitalWrite(PIN_S, HIGH);
break;
case COMMAND_LED_OFF:
Serial.println("Copy That: LED_OFF");
Serial1.write(voicecmd[16], 7);
LED_RGB_Off();
Serial.println("Switch ON!");
digitalWrite(PIN_S, LOW);
break;
default:
Serial.println("unkown nID!");
break;
}
} else if (nFlag == DSpotterSDKHL::ChangeStage) {
switch (nID) {
case DSpotterSDKHL::TriggerStage:
Serial.println("I'm waiting for\n\t\"Hey Arduino\"");
LED_BUILTIN_Off();
//LED_RGB_Off();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("You can say:");
display.setTextSize(2);
display.setCursor(0, 16);
display.println("Hey");
display.println("Arduino");
display.display(); // actually display all of the above
break;
case DSpotterSDKHL::CommandStage:
Serial.println("I'm here! You can say:\n\t\"LED red\"\n\t\"LED blue\"\n\t\"LED green\"");
Serial1.write(voicecmd[17], 7);
LED_BUILTIN_On();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("You can say:");
display.setTextSize(2);
display.setCursor(0, 16);
display.println("LED red");
display.println("LED blue");
display.println("LED green");
display.display(); // actually display all of the above
break;
default:
break;
}
} else if (nFlag == DSpotterSDKHL::GetError) {
if (nID == DSpotterSDKHL::LicenseFailed) {
Serial.print("DSpotter license failed! The serial number of your device is ");
Serial.println(DSpotterSDKHL::GetSerialNumber());
Serial.println("\nPlease get your license via https://tool.cyberon.com.tw/ArduinoDSpotterAuth/CTMain.php\n\n");
}
g_oDSpotterSDKHL.Release();
while (1)
; //hang loop
} else if (nFlag == DSpotterSDKHL::LostRecordFrame) {
//ToDo
//Serial.println("LostRecordFrame");
}
}
全部源码下载地址:ARDUINO NANO RP2040 CONNECT语音识别控制功能演示-嵌入式开发相关资料下载-EEWORLD下载中心
注意:该源码中使用的license是我的主板对应序列号的license,如果在其他主板上进行演示,需要去SDK官网申请新的license进行编译。
功能展示
视频演示地址:语音识别功能演示-【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT-EEWORLD大学堂
本次活动心得体会
Arduino NANO RP2040自带很多传感器和控制器,集成度高,可玩度高,对于原型验证、方案演示是一款不可多得的优秀硬件。软件开发也有很多成熟的lib、SDK、demo,对软件开发也非常友好。
但是Arduino NANO RP2040让人也有些许遗憾,RP2040的好多引脚直接连接到对面芯片,没有引出测试点,例如PDM的两根线,虽然可以勉强用探针点中过孔进行测量,但是实践中还是比较难受和危险的;IMU到RP2040的中断线直连,没有引出测试点;RP2040到Flash的SPI总线,有两根也是直连,没有引出测试点。
IMU是支持作为Sensor Hub工作的,但是对应的引脚却没有预留出来,很可惜。
调试功能不太好用。
- 2024-12-24
-
加入了学习《直播回放: Keysight 应对未来高速算力芯片的设计与测试挑战》,观看 Keysight 从仿真到测试,是德科技高速芯片测试
- 2024-12-23
-
发表了日志:
【Follow me第二季第4期】汇总提交帖:全部任务
-
上传了资料:
Follow me第二季第4期代码合集ARDUINO NANO RP2040 CONNECT
- 2024-12-18
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 PDM波形演示
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 语音识别功能演示
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 IMU功能演示与方向讲解-ARDUINO NANO RP2040 CONNECT
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 利用IMU实现鼠标控制-ARDUINO NANO RP2040 CONNECT
-
上传了资料:
ARDUINO NANO RP2040 CONNECT声音检测分贝仪
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 Blink RGB与UART功能演示-ARDUINO NANO RP2040 CONNECT
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 PDM功能演示-ARDUINO NANO RP2040 CONNECT
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 IMU陀螺仪数值演示-ARDUINO NANO RP2040 CONNECT
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 IMU加速度数值演示-ARDUINO NANO RP2040 CONNECT
- 2024-12-17
-
回复了主题帖:
【Follow me第二季第4期】任务三:PDM麦克风小知识+数据读取+波形呈现+wav存储
用的IDE自带的PDM的库,抄作业不知道怎么抄
-
上传了资料:
ARDUINO NANO RP2040 CONNECT声音检测打开LED和继电器
-
发表了主题帖:
【Follow me第二季第4期】任务三 调试PDM麦克风
本帖最后由 yilonglucky 于 2024-12-17 10:09 编辑
任务简介
学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。
在Arduino主板上有一个ST的MEMS数字麦克风芯片MP34DT06J,可以将声音编码PDM传输给主控芯片。麦克风芯片在主板上的对应位置如下图所示:
全部物料清单
ARDUINO NANO RP2040 CONNECT主板
USB数据线
已经部署Arduino IDE的PC
继电器
设计思路
首先通过原理图可知该麦克风LR引脚拉高,所以这颗麦克风在CLK为高电平时数据线生效,应该是对应右通道的声音。
TCK周期支持308到1000ns,对应频率即1MHz到3.247MHz之间。
然后设计代码将采集到的数据存入一个1024个元素的数组中。当检测到收到的声音超过阈值时则切换LED的状态和继电器的通断状态。
实际抓到的PDM信号线的波形:
视频演示:
- 2024-12-16
-
回复了主题帖:
治疗打呼噜的止鼾器
里面就一个麦克风呗,检测到超过多少分贝就开启一次电击?