亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

使用 Arduino Nano 33 BLE Sense 实现音频数据传输

组件与物料

Arduino Nano 33 BLE Sense × 1

项目简介

在 Chirp 总部,我们对 Arduino 发布搭载多项新功能的新款开发板感到无比兴奋。这些功能包括丰富的传感器、强大的处理器,以及最重要的——板载麦克风!Arduino 团队慷慨地寄送了一块 Nano 33 Sense 预发布版板卡,它完美兼容 Chirp SDK,让创客社区能够利用声音发送和接收数据。

Chirp 为 Arduino 开发板引入了一种全新的传输机制——声波数据传输,极大地拓展了硬件的连接选项。声波数据传输的主要优势包括:

本教程将演示如何使用 Chirp SDK 发送 RGB 值,以改变板载 LED 的颜色。得益于多年的算法研究,Chirp 即使在嘈杂环境下也能稳健解码。如果你仍有疑虑,不妨亲自试一试——上手比以往更简单。

快速开始

若尚未注册,请前往 developers.chirp.io 创建账号。注册后即可获取应用的 Key、Secret 以及音频配置。

接收数据

Nano 33 Sense 内置麦克风,接收数据仅需安装 Chirp SDK。打开库管理器(Tools > Manage Libraries),搜索“Chirp SDK”并安装 v3.3.0 或更高版本。

随后打开示例代码:File > Examples > ChirpSDK > Nano33SenseReceive。将 16khz-mono-embedded 协议的凭据(从 developers.chirp.io 获取)复制到 credentials.h 文件中。

示例代码默认将接收到的数据打印到串口监视器。我们只需修改 onReceivedCallback 函数,即可让板载 LED 随数据变色。

硬件引脚定义

#define R_LED_PIN 22
#define G_LED_PIN 23
#define B_LED_PIN 24

void setup() {
  pinMode(R_LED_PIN, OUTPUT);
  pinMode(G_LED_PIN, OUTPUT);
  pinMode(B_LED_PIN, OUTPUT);
}

回调函数处理 RGB 数据

void onReceivedCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) {
  if (length > 0) {
    // 高数值对应低亮度,故用 UINT8_MAX 减去载荷值
    analogWrite(R_LED_PIN, UINT8_MAX - payload[0]);
    analogWrite(G_LED_PIN, UINT8_MAX - payload[1]);
    analogWrite(B_LED_PIN, UINT8_MAX - payload[2]);
  } else {
    Serial.println("Decode failed");
  }
}

上传代码后,播放教程提供的音频文件,即可观察 LED 依次变为红、绿、蓝三色。

后续展望

当前版本仅支持可听频段的 16khz-mono-embedded 协议。未来几个月将推出近超声波频段的不可听版本,可将数据嵌入音乐、视频等现有音频中触发动作,而不干扰人耳聆听。我们还将发布更多结合 Arduino 的声波数据传输教程。欢迎在 Twitter @chirp 或邮件 contact@chirp.io 分享你的创意项目。

完整代码

/**--------------------------------------------------------------------
  Arduino Nano 33 Sense 接收数据示例代码
  @file Nano33SenseReceive.ino
  @brief 在 https://developers.chirp.io 创建开发者账号,
         将 "16khz-mono-embedded" 协议的 key、secret、config 填入下方宏定义。
         本示例监听 RGB 值并改变板载 LED 颜色。
  Circuit: - Arduino Nano 33 BLE board
  Copyright © 2011-2019, Asio Ltd. All rights reserved.
  -------------------------------------------------------------------*/
#include <PDM.h>
#include "chirp_connect.h"

#define CHIRP_APP_KEY "YOUR_APP_KEY"
#define CHIRP_APP_SECRET "YOUR_APP_SECRET"
#define CHIRP_APP_CONFIG "YOUR_APP_CONFIG"
#define SAMPLE_RATE 16000
#define BUFFER_SIZE 256
#define R_LED_PIN 22
#define G_LED_PIN 23
#define B_LED_PIN 24

// 全局变量
static chirp_connect_t *chirp = NULL;
short sampleBuffer[BUFFER_SIZE];
volatile int samplesRead;

// 函数声明
void setupChirp(void);
void chirpErrorHandler(chirp_connect_error_code_t code);
void onPDMdata(void);

void setup() {
  Serial.begin(115200);
  // while (!Serial);
  pinMode(R_LED_PIN, OUTPUT);
  pinMode(G_LED_PIN, OUTPUT);
  pinMode(B_LED_PIN, OUTPUT);
  setupChirp();
  PDM.onReceive(onPDMdata);
  PDM.setGain(30);
  if (!PDM.begin(1, SAMPLE_RATE)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }
  analogWrite(R_LED_PIN, UINT8_MAX);
  analogWrite(G_LED_PIN, UINT8_MAX);
  analogWrite(B_LED_PIN, UINT8_MAX);
}

void loop() {
  if (samplesRead) {
    chirp_connect_error_code_t err = chirp_connect_process_shorts_input(chirp, sampleBuffer, samplesRead);
    chirpErrorHandler(err);
    samplesRead = 0;
  }
}

void onPDMdata() {
  int bytesAvailable = PDM.available();
  PDM.read(sampleBuffer, bytesAvailable);
  samplesRead = bytesAvailable / sizeof(short);
}

// Chirp 回调函数
void onReceivingCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) {
  Serial.println("Receiving data...");
  analogWrite(R_LED_PIN, UINT8_MAX);
  analogWrite(G_LED_PIN, UINT8_MAX);
  analogWrite(B_LED_PIN, UINT8_MAX);
}

void onReceivedCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) {
  if (length) {
    analogWrite(R_LED_PIN, UINT8_MAX - payload[0]);
    analogWrite(G_LED_PIN, UINT8_MAX - payload[1]);
    analogWrite(B_LED_PIN, UINT8_MAX - payload[2]);
  } else {
    analogWrite(R_LED_PIN, 0);
    analogWrite(G_LED_PIN, UINT8_MAX);
    analogWrite(B_LED_PIN, UINT8_MAX);
    delay(500);
    analogWrite(R_LED_PIN, UINT8_MAX);
    delay(500);
    analogWrite(R_LED_PIN, 0);
    Serial.println("Decode failed");
  }
}

void chirpErrorHandler(chirp_connect_error_code_t code) {
  if (code != CHIRP_CONNECT_OK) {
    const char *error_string = chirp_connect_error_code_to_string(code);
    Serial.println(error_string);
    exit(42);
  }
}

void setupChirp(void) {
  chirp = new_chirp_connect(CHIRP_APP_KEY, CHIRP_APP_SECRET);
  if (chirp == NULL) {
    Serial.println("Chirp initialisation failed.");
    return;
  }
  chirp_connect_error_code_t err = chirp_connect_set_config(chirp, CHIRP_APP_CONFIG);
  chirpErrorHandler(err);
  char *info = chirp_connect_get_info(chirp);
  Serial.println(info);
  chirp_connect_free(info);
  chirp_connect_callback_set_t callback_set = {
    .on_state_changed = NULL,
    .on_sending = NULL,
    .on_sent = NULL,
    .on_receiving = onReceivingCallback,
    .on_received = onReceivedCallback
  };
  err = chirp_connect_set_callbacks(chirp, callback_set);
  chirpErrorHandler(err);
  err = chirp_connect_set_input_sample_rate(chirp, SAMPLE_RATE);
  chirpErrorHandler(err);
  err = chirp_connect_set_frequency_correction(chirp, 1.0096);
  chirpErrorHandler(err);
  err = chirp_connect_start(chirp);
  chirpErrorHandler(err);
  Serial.println("Chirp SDK initialised.");
  Serial.flush();
}

制造工艺

  1. 实时数据洞察重塑数字化制造团队:从数据饱和到关键参数聚焦
  2. 黑胶唱片LP制作的艺术与工艺
  3. 树莓派传感器数据融合实战:GPS 与 MPU‑9150 IMU 的 I²C 与 UART 接入
  4. 高阶HMI驱动工厂能效跃升:测量、监控、优化全链路
  5. 8大常见数据泄露类型实战剖析:真实案例、影响深度与防御启示
  6. 前沿工业4.0技术:十大实际创新与应用场景解析
  7. OT与IT无缝融合:现代工业软件连接智能传感器至企业系统
  8. 可靠性互联网中的数据驾驭:高效管理策略
  9. 边缘时代的物联网:增长、数据、安全与合作伙伴策略
  10. 提升工业 4.0:利用边缘分析实现更智能、更快速的制造
  11. 利用实时城市数据驱动智慧城市创新
  12. C++ char 类型完全指南:声明、ASCII 码、输入输出与字符串转换