用声音发送数据
组件和用品
| × | 1 |
关于这个项目
在 Chirp 总部,听到 Arduino 将发布具有大量新功能的新板的公告,我们感到非常兴奋。这些功能包括范围广泛的传感器、强大的处理器以及最重要的 - 板载麦克风! Arduino 的好心人向我们发送了预发布的新型 Nano 33 Sense 板,该板与 Chirp 完全兼容,允许创客社区使用声音发送和接收数据。
Chirp 为 Arduino 板添加了一个完全独特的传输机制,声音数据的附加功能意味着黑客有更多的连接选项触手可及。声音数据的一些优点包括:
- 设备不可知:数据可以从移动应用、网页,甚至仅通过音频文件发送
- 一对多:听力范围内的任何设备都能够通过一次简单的交易接收数据
- 无摩擦:不需要任何配对、密码或初始设置
在本教程中,我们将演示如何使用 Chirp SDK 发送 RGB 值来更改板载 LED 的颜色。
Chirp 甚至可以在嘈杂的地方工作,这要归功于我们多年来一直致力于使解码器对背景声音具有鲁棒性的研究。在此处阅读有关使用声音数据的好处的更多信息。
如果您仍然持怀疑态度,请自己尝试一下。
开始使用 Chirp 比以往任何时候都容易...
开始使用
如果您还没有这样做,则需要在 developer.chirp.io 上注册 Chirp。注册后,您可以获得应用密钥、机密和音频配置。
接收数据
由于 Nano 33 Sense 随附一个板载麦克风,因此您使用 Chirp 接收数据所需的只是直接从库管理器中获得的 Chirp SDK。
只需打开库管理器,然后搜索 Chirp SDK。安装 v3.3.0 或更高版本,您就可以开始编码了。
工具> 管理库
您可以打开我们的示例代码开始。
File> Examples> ChirpSDK> Nano33SenseReceive
您需要复制并粘贴 16khz-mono-embedded 的凭据 从developers.chirp.io 到credentials.h 文件的协议。
示例代码将简单地将任何接收到的数据打印到串行监视器。但是,我们可以通过编辑 onReceivedCallback
轻松更改行为以点亮板载 LED 功能。
在您的设置函数中,我们必须首先设置连接到 LED 的 GPIO 引脚作为输出
#define R_LED_PIN 22#define G_LED_PIN 23#define B_LED_PIN 24void setup() { pinMode(R_LED_PIN, OUTPUT); pinMode(G_LED_PIN,输出); pinMode(B_LED_PIN, OUTPUT);}
为了驱动 LED,我们需要从数据负载中提取 RGB 值。
void onReceivedCallback(void *chirp, uint8_t *payload, size_t length,{ if (length> 0) { // 高值意味着较低的亮度,所以我们 // 从 UINT8_MAX 中减去 analogWrite(R_LED_PIN, UINT8_MAX - payload [0]);analogWrite(B_LED_PIN, UINT8_MAX - payload[2]); } else { Serial.println(“解码失败”); }}
您现在可以通过播放下面的音频文件来测试您的代码,每个文件都应将 LED 颜色从红色变为绿色再到蓝色。
下一步是什么?
用于 Arduino 的 Chirp SDK 的第一次迭代仅在可听的 16khz-mono-embedded 上运行 协议。在接下来的几个月里,我们将发布一个可以在接近超声波频率下工作的听不见版本。有了它,您将能够以人类听不到的频率发送数据,例如,您可以将啁啾数据嵌入现有音频(如歌曲或视频)中以触发操作。
我们还将跟进更多关于如何通过 Arduino 使用声音数据的教程。通过在 twitter @chirp 上标记我们或通过 [email protected] 与我们联系,让我们知道您在自己的 Arduino 项目中在哪里使用了 Chirp。
代码
- 将 RGB 值线性调至 Nano 33 Sense
Chirp RGB 值到 Nano 33 SenseC/C++
使用 Chirp 发送 RGB 值以更改板载 LED 的颜色。您可以使用我们在本教程中附带的声音片段来尝试一下,或者通过发送 3 个字节的数组来自己尝试。/**----------------- -------------------------------------------------- - 使用 Arduino Nano 33 Sense 板接收数据的示例代码。 @file Nano33SenseReceive.ino @brief 在 https://developers.chirp.io 创建一个开发者帐户,然后将“16khz-mono-embedded”协议的密钥、秘密和配置字符串复制并粘贴到下面的 chirp 定义中。此示例将开始侦听 RGB 值并更改板载 LED 的颜色。电路: - Arduino Nano 33 BLE 板 版权所有 © 2011-2019, Asio Ltd. 保留所有权利。 -------------------------------------------------- -----------------*/#include#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);// Main ---------------------------------- -----------------------------void setup(){ Serial.begin(115200);// while (!Serial); pinMode(R_LED_PIN,输出); pinMode(G_LED_PIN,输出); pinMode(B_LED_PIN,输出);设置啁啾(); PDM.onReceive(onPDMdata); PDM.setGain(30); if (!PDM.begin(1, SAMPLE_RATE)) { Serial.println("无法启动 PDM!");而 (1);模拟写入(R_LED_PIN,UINT8_MAX);模拟写入(G_LED_PIN,UINT8_MAX);模拟写入(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);样本读取 =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("接收数据...");模拟写入(R_LED_PIN,UINT8_MAX);模拟写入(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) { // 高值意味着较低的亮度,所以我们 // 从 UINT8_MAX 中减去analogWrite(R_LED_PIN, UINT8_MAX - 有效载荷[0]);模拟写入(G_LED_PIN,UINT8_MAX - 有效载荷[1]);模拟写入(B_LED_PIN,UINT8_MAX - 有效载荷[2]); } else { 模拟写入(R_LED_PIN, 0);模拟写入(G_LED_PIN,UINT8_MAX);模拟写入(B_LED_PIN,UINT8_MAX);延迟(500);模拟写入(R_LED_PIN,UINT8_MAX);延迟(500);模拟写入(R_LED_PIN,0); Serial.println("解码失败"); }}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);退出(42); }}void setupChirp(void){ chirp =new_chirp_connect(CHIRP_APP_KEY, CHIRP_APP_SECRET); if (chirp ==NULL) { Serial.println("chirp 初始化失败。");返回; } 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(信息); chirp_connect_free(信息); chirp_connect_callback_set_t callback_set ={ .on_state_changed =NULL, .on_sending =NULL, .on_sent =NULL, .on_receiving =onReceivingCallback, .on_received =onReceivedCallback };错误 =chirp_connect_set_callbacks(chirp, callback_set); chirpErrorHandler(err);错误 =chirp_connect_set_input_sample_rate(chirp, SAMPLE_RATE); chirpErrorHandler(err);错误 =chirp_connect_set_frequency_correction(chirp, 1.0096); chirpErrorHandler(err);错误 =chirp_connect_start(chirp); chirpErrorHandler(err); Serial.println("Chirp SDK 初始化。"); Serial.flush();}
制造工艺