277|1

120

帖子

12

TA的资源

一粒金砂(中级)

楼主
 

【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是否在位,并且将所有设备清单列出来。

必做任务一: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。
使用另一组串口收到的消息截图:
 

必做任务二:学习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数值曲线截图:
 

必做任务三:学习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灯,打开或关闭继电器。
打印声音曲线截图:

选做任务一: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;
  }
}

 

功能展示

效果截图:
 

自选任务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);
}

 

功能展示

自选任务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");
  }
}

 

注意:该源码中使用的license是我的主板对应序列号的license,如果在其他主板上进行演示,需要去SDK官网申请新的license进行编译。

功能展示

本次活动心得体会

Arduino NANO RP2040自带很多传感器和控制器,集成度高,可玩度高,对于原型验证、方案演示是一款不可多得的优秀硬件。软件开发也有很多成熟的lib、SDK、demo,对软件开发也非常友好。
但是Arduino NANO RP2040让人也有些许遗憾,RP2040的好多引脚直接连接到对面芯片,没有引出测试点,例如PDM的两根线,虽然可以勉强用探针点中过孔进行测量,但是实践中还是比较难受和危险的;IMU到RP2040的中断线直连,没有引出测试点;RP2040到Flash的SPI总线,有两根也是直连,没有引出测试点。
IMU是支持作为Sensor Hub工作的,但是对应的引脚却没有预留出来,很可惜。
调试功能不太好用。

 
 

最新回复

写的很深入,内容很夯实,效果很直观,高手高手!   详情 回复 发表于 2024-12-25 15:41
点赞 关注(1)
个人签名尽吾志也而不能至者,可以无悔矣。——王安石
 
 

回复
举报

227

帖子

3

TA的资源

一粒金砂(高级)

沙发
 

写的很深入,内容很夯实,效果很直观,高手高手!

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表