一、硬件介绍
1、产品特点
Arduino Nano 33 BLE Rev2,利用了nRF52840微控制器的先进功能。这款32位Arm® Cortex®-M4 CPU 64 MHz与MicroPython的兼容性增强了板子的灵活性,该开发板的突出特点是其蓝牙低功耗(BLE)功能,使其能够轻松与其他蓝牙低功耗设备进行通信。Nano 33 BLE Rev2设计具备多功能性,配备了内置的9轴惯性测量单元、提供位置、方向和加速度的精确测量等。
微控制器 | nRF52840 | - |
---|---|---|
USB连接器 | Micro USB | - |
管脚 | LED引脚 | IO13 |
- | 通用数字I/O 引脚 | 14个 |
- | 模拟输入引脚 | 8个 |
- | PWM 引脚 | 所有数字I/O 引脚 (4 at once) |
- | 外部中断 | 所有数字I/O 引脚 |
连接 | Bluetooth® | u-blox® NINA-B306 |
传感器 | IMU | BMI270 (三轴加速度计+三轴陀螺仪) BMM150 (三轴磁力计) |
麦克风 | MP34DT06JTR | |
手势检测、接近检测、数字环境光感(ALS)和色感(RGBC) | APDS9960 | |
气压 | LPS22HB | |
温湿度 | HS3003 | |
通信 | UART | RX/TX |
- | I2C | A4 (SDA), A5 (SCL) |
- | SPI | D11 (COPI), D12 (CIPO), D13 (SCK). Use any GPIO for Chip Select (CS) |
供电 | 输入 / 输出电压 | 3.3 V |
- | 输入电压(标准) | 5-18 V |
- | 每个I/O引脚的电流 | 10 mA |
nRF52840 | 时钟速度 | 64 MHz |
- | 存储 | 256 KB SRAM、1 MB flash |
尺寸 | 重量 | 0.32g |
- | 宽度 | 18 mm |
- | 长度 | 45 mm |
2、功能引脚示意图 / 原理图
板载LED灯
IO13 引脚控制
原理图:
5V引脚仅在满足以下两个条件时可用:标记为VUSB的两个焊盘上制作焊接桥 / 通过USB端口为 Nano 33 BLE Sense Rev2 供电;如果从VIN引脚给电路板供电,不会得到任何稳定的5V,即使你做焊接桥,5V引脚也不会输出。
二、项目功能实现思想
【室内空气质量语音检测蓝牙调光台灯】
实现效果:
通过板载麦克风识别相关语音指令,可获取当前室内的温湿度、气压等信息输出到串口上,以及声控打开 / 关闭LED;
并且通过蓝牙功能,通过手机连接开发板,发送相关指令实现PWM调节LED亮度等功能;
实物效果搭建如下:
系统框图如下:
运行流程图如下:
三、功能实现主要步骤
主要相关代码
1、LED控制部分
int Ble_Data; //接收到的蓝牙数据
int led = D2; //LED引脚
void Led_Init(void){
pinMode(led, OUTPUT);
digitalWrite(led,LOW);
}
2、温湿度获取部分
#include <Arduino_HS300x.h>
void HS300x_Init(void){
if (!HS300x.begin()) {
Serial.println("温湿度传感器初始化失败!");
while (1);
}
}
void HS300x_Get(void){
float temperature = HS300x.readTemperature(); //温度
float humidity = HS300x.readHumidity(); //湿度
Serial.print("温度 = ");
Serial.print(temperature);
Serial.println(" °C");
Serial.print("湿度 = ");
Serial.print(humidity);
Serial.println(" %");
Serial.println();
}
3、气压、海拔高度获取部分
#include <Arduino_LPS22HB.h>
void LPS22HB_Init(void){
if (!BARO.begin()) {
Serial.println("气压传感器初始化失败!");
while (1);
}
}
void LPS22HB_Get(void){
float pressure = BARO.readPressure(); //获取气压
float altitude = 44330 * ( 1 - pow(pressure/101.325, 1/5.255) ); //获取海拔高度
Serial.print("当前大气压 = ");
Serial.print(pressure);
Serial.println(" Kpa");
Serial.print("当前海拔高度 = ");
Serial.print(altitude);
Serial.println(" m");
}
4、语音识别部分
唤醒词:
100 Hi Arduino
命令词:
10000 打开LED
10001 关闭LED
10002 获取室内空气质量
#include <Arduino.h>
#include <DSpotterSDK_MakerHL.h>
#include "CybLicense_1750150084.h"
#define DSPOTTER_LICENSE g_lpdwLicense
#if defined(TARGET_ARDUINO_NANO33BLE) || defined(TARGET_PORTENTA_H7) || defined(TARGET_NICLA_VISION)
#include "Model_1750150084.h"
#endif
#define DSPOTTER_MODEL g_lpdwModel
static DSpotterSDKHL g_oDSpotterSDKHL;
// 回调处理函数
void VRCallback(int nFlag, int nID, int nScore, int nSG, int nEnergy)
{
if (nFlag==DSpotterSDKHL::InitSuccess) // 初始化成功
{
//ToDo
}
else if (nFlag==DSpotterSDKHL::GetResult) // 获取识别结果
{
//ToDo 处理代码
switch(nID)
{
case 100:
Serial.println(F("Arduino 已唤醒!"));
// Add your own code here
break;
case 10000:
Serial.println(F("LED已打开"));
digitalWrite(led,HIGH);
break;
case 10001:
Serial.println(F("LED已关闭"));
digitalWrite(led,LOW);
break;
case 10002:
HS300x_Get();
LPS22HB_Get();
Ble_Init();
delay(800);
break;
default:
break;
}
}
else if (nFlag==DSpotterSDKHL::ChangeStage) // 命令 / 指令状态切换
{
switch(nID)
{
case DSpotterSDKHL::TriggerStage: //唤醒词
//To Do
break;
case DSpotterSDKHL::CommandStage: //指令词
//To Do
break;
default:
break;
}
}
else if (nFlag==DSpotterSDKHL::GetError) //错误处理
{
if (nID == DSpotterSDKHL::LicenseFailed)
{
}
g_oDSpotterSDKHL.Release();// 释放SDK资源
while(1);
}
}
void voiceControl_Init(void){
DSpotterSDKHL::ShowDebugInfo(true);
if (g_oDSpotterSDKHL.Init(DSPOTTER_LICENSE, sizeof(DSPOTTER_LICENSE), DSPOTTER_MODEL, VRCallback) != DSpotterSDKHL::Success)
return;
}
void setup()
{
voiceControl_Init();
}
void loop()
{
g_oDSpotterSDKHL.DoVR();
}
5、蓝牙控制部分
#include <ArduinoBLE.h>
void Ble_Init(void){
pinMode(LED_BUILTIN, OUTPUT); //初始板载LED
digitalWrite(LED_BUILTIN, LOW);
if (!BLE.begin()) {
Serial.println("蓝牙启动失败!");
while (1);
}
// 蓝牙设备名称
BLE.setLocalName("Nano 33 BLE Sense V2");
BLE.setAdvertisedService(ledService);
ledService.addCharacteristic(bleCharacteristic);
BLE.addService(ledService);
// 初始值
bleCharacteristic.writeValue(0);
BLE.advertise();
}
void Ble_Get(void){
BLEDevice central = BLE.central();
// 连接成功
if (central) {
digitalWrite(LED_BUILTIN, HIGH); //打开板载LED
while (central.connected()) {
if (bleCharacteristic.written()) {
int data = bleCharacteristic.value();
if(data>=0 && data<=100){
Ble_Data = map(data, 0, 100, 0, 255); // 蓝牙值 0~100 映射到PWM 0~255;
analogWrite(led,Ble_Data);
}
}
}
//断开连接时 关闭所有LED
Serial.print(F("断开连接"));
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(led, LOW);
}
}
完整代码
#include <Arduino.h>
#include <DSpotterSDK_MakerHL.h>
#include "CybLicense_1750150084.h"
#include <Arduino_LPS22HB.h>
#include <Arduino_HS300x.h>
#include <ArduinoBLE.h>
#define DSPOTTER_LICENSE g_lpdwLicense
#if defined(TARGET_ARDUINO_NANO33BLE) || defined(TARGET_PORTENTA_H7) || defined(TARGET_NICLA_VISION)
#include "Model_1750150084.h"
#endif
#define DSPOTTER_MODEL g_lpdwModel
static DSpotterSDKHL g_oDSpotterSDKHL;
int led = D2; //LED引脚
BLEService ledService("180A");
BLEByteCharacteristic bleCharacteristic("2A57", BLERead | BLEWrite);
// 回调处理函数
void VRCallback(int nFlag, int nID, int nScore, int nSG, int nEnergy)
{
if (nFlag==DSpotterSDKHL::InitSuccess) // 初始化成功
{
//ToDo
}
else if (nFlag==DSpotterSDKHL::GetResult) // 获取识别结果
{
//ToDo 处理代码
switch(nID)
{
case 100:
Serial.println(F("Arduino 已唤醒!"));
// Add your own code here
break;
case 10000:
Serial.println(F("LED已打开"));
digitalWrite(led,HIGH);
break;
case 10001:
Serial.println(F("LED已关闭"));
digitalWrite(led,LOW);
break;
case 10002:
HS300x_Get();
LPS22HB_Get();
Ble_Init();
delay(800);
break;
default:
break;
}
}
else if (nFlag==DSpotterSDKHL::ChangeStage) // 命令 / 指令状态切换
{
switch(nID)
{
case DSpotterSDKHL::TriggerStage: //唤醒词
//To Do
break;
case DSpotterSDKHL::CommandStage: //指令词
//To Do
break;
default:
break;
}
}
else if (nFlag==DSpotterSDKHL::GetError) //错误处理
{
if (nID == DSpotterSDKHL::LicenseFailed)
{
}
g_oDSpotterSDKHL.Release();// 释放SDK资源
while(1);
}
}
void Led_Init(void){
pinMode(led, OUTPUT);
digitalWrite(led,LOW);
pinMode(LED_BUILTIN, OUTPUT); //初始板载LED
digitalWrite(LED_BUILTIN, LOW);
}
void voiceControl_Init(void){
DSpotterSDKHL::ShowDebugInfo(true);
if (g_oDSpotterSDKHL.Init(DSPOTTER_LICENSE, sizeof(DSPOTTER_LICENSE), DSPOTTER_MODEL, VRCallback) != DSpotterSDKHL::Success)
return;
}
void HS300x_Init(void){
if (!HS300x.begin()) {
Serial.println("温湿度传感器初始化失败!");
while (1);
}
}
void LPS22HB_Init(void){
if (!BARO.begin()) {
Serial.println("气压传感器初始化失败!");
while (1);
}
}
void Ble_Init(void){
if (!BLE.begin()) {
Serial.println("蓝牙启动失败!");
while (1);
}
// 蓝牙设备名称
BLE.setLocalName("Nano 33 BLE Sense V2");
BLE.setAdvertisedService(ledService);
ledService.addCharacteristic(bleCharacteristic);
BLE.addService(ledService);
// 初始值
bleCharacteristic.writeValue(0);
BLE.advertise();
}
void HS300x_Get(void){
float temperature = HS300x.readTemperature(); //温度
float humidity = HS300x.readHumidity(); //湿度
Serial.print("温度 = ");
Serial.print(temperature);
Serial.println(" °C");
Serial.print("湿度 = ");
Serial.print(humidity);
Serial.println(" %");
}
void LPS22HB_Get(void){
float pressure = BARO.readPressure(); //获取气压
float altitude = 44330 * ( 1 - pow(pressure/101.325, 1/5.255) ); //获取海拔高度
Serial.print("当前大气压 = ");
Serial.print(pressure);
Serial.println(" Kpa");
Serial.print("当前海拔高度 = ");
Serial.print(altitude);
Serial.println(" m");
}
void Ble_Get(void){
BLEDevice central = BLE.central();
// 连接成功
if (central) {
digitalWrite(LED_BUILTIN, HIGH); //打开板载LED
while (central.connected()) {
if (bleCharacteristic.written()) {
int data = bleCharacteristic.value();
if(data>=0 && data<=100){
int Ble_Data = map(data, 0, 100, 0, 255); // 蓝牙值 0~100 映射到PWM 0~255;
analogWrite(led,Ble_Data);
}
}
}
//断开连接时 关闭所有LED
Serial.print(F("断开连接"));
digitalWrite(LED_BUILTIN, LOW);
analogWrite(led,LOW);
}
}
void setup()
{
Serial.begin(9600);
while(!Serial);
voiceControl_Init();
Led_Init();
HS300x_Init();
LPS22HB_Init();
}
void loop()
{
g_oDSpotterSDKHL.DoVR();
Ble_Get();
}
四、实现现象
ARDUINO NANO 33 BLE SENSE V2