ChirpOfficial
Published © GPL3+

Send Data with Sound

Control your Arduino using data-over-sound.

BeginnerFull instructions provided17,906
Send Data with Sound

Things used in this project

Hardware components

Nano 33 BLE Sense
Arduino Nano 33 BLE Sense
×1

Story

Read more

Code

Chirp RGB values to Nano 33 Sense

C/C++
Send RGB values using Chirp to change the colour of the on board LED. You can use our attached sound clips on this tutorial to try it out, or do it yourself by sending an array of 3 bytes.
/**--------------------------------------------------------------------

    Example code to receive data using Arduino Nano 33 Sense board.

    @file Nano33SenseReceive.ino

    @brief Create a developer account at https://developers.chirp.io,
    and copy and paste your key, secret and config string for the
    "16khz-mono-embedded" protocol into the chirp defines below.

    This example will start listening for RGB values and change the        colour of the on board 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

// Global variables ---------------------------------------------------

static chirp_connect_t *chirp = NULL;
short sampleBuffer[BUFFER_SIZE];
volatile int samplesRead;

// Function definitions -----------------------------------------------

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 --------------------------------------------------------------

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)
  {
    // High values mean lower brightness, so we
    // subtract from 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
  {
    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();
}

Credits

ChirpOfficial

ChirpOfficial

5 projects • 38 followers
We produce a suite of cross-platform, developer friendly SDKs which take data, convert into sound, and nearby devices convert back into data

Comments