Audio Data Overdracht met Arduino Nano 33 BLE Sense
Onderdelen en benodigdheden
![]() |
Arduino Nano 33 BLE Sense | × | 1 |
Over dit project
Bij Chirp HQ waren we zeer enthousiast toen Arduino een nieuw bord uitbracht met een reeks nieuwe functies, waaronder diverse sensoren, een krachtige processor en – het allerbelangrijkste – een ingebouwde microfoon! Het Arduino-team stuurde ons een pre-release van de Nano 33 BLE Sense, die volledig compatibel is met Chirp. Hierdoor kan de maker-community data verzenden en ontvangen via geluid.
Chirp voegt een uniek transportmechanisme toe aan Arduino-borden. Data-over-sound geeft makers meer connectiviteitsopties. Enkele voordelen:
- Apparaatonafhankelijk: data kan verzonden worden vanuit mobiele apps, webpagina's of zelfs enkel een audiobestand.
- Eén-naar-veel: elk apparaat binnen bereik kan de data in één transactie ontvangen.
- Vrij van friktie: geen koppeling, wachtwoorden of initiële setup vereist.
In deze tutorial laten we zien hoe je de Chirp SDK gebruikt om een RGB-waarde te versturen en de kleur van de ingebouwde LED te veranderen. Chirp werkt zelfs in ruisvolle omgevingen, dankzij jarenlange onderzoek naar robuuste decodering. Lees meer over de voordelen van data-over-sound.
Aan de slag
Stap 1: Chirp-account aanmaken
Meld je aan bij developers.chirp.io. Na registratie ontvang je je app key, secret en audio-configuratie voor je applicatie.
Stap 2: Data ontvangen
De Nano 33 BLE Sense heeft een ingebouwde microfoon. Je hebt alleen de Chirp SDK nodig, beschikbaar via de Library Manager in de Arduino IDE.
- Open
Tools > Manage Libraries. - Zoek naar Chirp SDK en installeer versie 3.3.0 of nieuwer.
- Open het voorbeeld:
File > Examples > ChirpSDK > Nano33SenseReceive. - Kopieer je credentials voor het 16khz-mono-embedded protocol uit developers.chirp.io naar het bestand
credentials.h.
De voorbeeldcode print ontvangen data naar de Serial Monitor. We passen de onReceivedCallback functie aan om de onboard LED te sturen.
LED-pinnen configureren
#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-waarden uit payload halen
void onReceivedCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) {
if (length > 0) {
// Hogere waarden = lagere helderheid, dus aftrekken van 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");
}
}
Test je code door de onderstaande audiobestanden af te spelen – elk moet de LED-kleur veranderen van rood naar groen naar blauw.
Wat komt er nu?
De eerste versie van de Chirp SDK voor Arduino werkt alleen met het hoorbare 16khz-mono-embedded protocol. In de komende maanden zal er een onhoorbare versie verschijnen die werkt bij nahe-ultrasonische frequenties. Hiermee kun je data insluiten in bestaande audio zoals muziek of video's om acties te triggeren.
Er volgen meer tutorials over data-over-sound met Arduino. Deel je projecten met ons via Twitter @chirp of mail naar contact@chirp.io.
Complete code
/**--------------------------------------------------------------------
Voorbeeldcode om data te ontvangen met Arduino Nano 33 Sense.
Maak een developer account aan op https://developers.chirp.io,
en kopieer je key, secret en config string voor het "16khz-mono-embedded"
protocol in de CHIRP defines hieronder.
Dit voorbeeld luistert naar RGB-waarden en verandert de kleur van de
onboard LED.
Circuit: - Arduino Nano 33 BLE board
Copyright © 2011-2019, Asio Ltd. Alle rechten voorbehouden.
-------------------------------------------------------------------*/
#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
// Globale variabelen
static chirp_connect_t *chirp = NULL;
short sampleBuffer[BUFFER_SIZE];
volatile int samplesRead;
// Functiedeclaraties
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, 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 callbacks
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 initialisatie mislukt.");
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 geïnitialiseerd.");
Serial.flush();
}
Productieproces
- Digitale productieteams transformeren met real-time datainzichten
- De Kunst en Proces van LP Platen Productie
- Sensordata integreren in een Raspberry Pi: Een praktische gids
- Maximaliseren van Fabrieksenergie-efficiëntie met Geavanceerde HMI's
- 8 veelvoorkomende datalekkage-typen – voorbeelden uit de praktijk & impact
- State-of-the-art Industrie 4.0 technologie: Real-world innovaties & toepassingen
- Naadloze OT-IT integratie: moderne industriële software koppelt slimme sensoren aan bedrijfssystemen
- IoT in de Edge-era: Groei, data, beveiliging en partnerstrategie
- Industrie 4.0 verhogen: Edge-analytics benutten voor slimmere, snellere productie
- Real-time stadsdata benutten voor slimme stad innovatie
- C++ Char Datatype: Declaratie, ASCII en Conversie‑Technieken
