BasedHardware / omi

AI wearables
https://omi.me
MIT License
3.61k stars 444 forks source link

Add a Firmware Setup for Arduino-based Prototyping and Testing #69

Closed felyu closed 5 months ago

felyu commented 6 months ago

Hi everyone!

I'm a big fan of the Friends project, but as a beginner, I've found the current firmware setup to be quite challenging. Therefore, I've taken the initiative to simplify things by rewriting the code into a straightforward .ino file.

Setup: This code utilizes the mic.h (please download the ZIP file from the existing project as the current release is non-functional.) and ArduinoBLE libraries.

To set up the Seeed nRF52 mbed-enabled Boards library (more details here):

Go to File > Preferences, and add the following URL to "Additional Boards Manager URLs": https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
Navigate to Tools > Board > Boards Manager..., type "seeed nrf52" in the search box, select the latest version of Seeed nRF52 mbed-enabled, and install it.

If you encounter a Permission Denied issue, you can find a fix here.

Please note that it's not fully functional yet. I attempted to replicate the original code, but when running the Python script to generate audio recordings, it doesn't work. I suspect there are some issues with the sampling rate, samples, buf_size, etc., but I'm struggling to grasp how to fix this on my own.

To Do:

The code :

#include <ArduinoBLE.h>
#include <mic.h>

#define SAMPLES 400
mic_config_t mic_config = {
  .channel_cnt = 1,
  .sampling_rate = 16000,
  .buf_size = 1600,
  .debug_pin = LED_BUILTIN
};
NRF52840_ADC_Class Mic(&mic_config);

int16_t recording_buf[SAMPLES];
volatile static bool record_ready = false;

#define SERVICE_UUID "19B10000-E8F2-537E-4F6C-D104768A1214"
#define CHARACTERISTIC_UUID_AUDIO "19B10001-E8F2-537E-4F6C-D104768A1214"

BLEService audioService(SERVICE_UUID);
BLECharacteristic audioDataCharacteristic(CHARACTERISTIC_UUID_AUDIO, BLERead | BLENotify, sizeof(recording_buf), true);

void setup() {
  Serial.begin(115200);
  while (!Serial);

  Mic.set_callback(audio_rec_callback);

  if (!Mic.begin()) {
    Serial.println("Mic initialization failed");
    while (1);
  }

  if (!BLE.begin()) {
    Serial.println("Failed to start BLE!");
    while (1);
  }

  BLE.setLocalName("Friend");
  BLE.setDeviceName("Friend");
  BLE.setAdvertisedService(audioService);

  audioService.addCharacteristic(audioDataCharacteristic);
  BLE.addService(audioService);

  BLE.advertise();
  Serial.println("BLE Peripheral is now advertising");
}

void loop() {
  BLEDevice central = BLE.central();

  if (central) {
    Serial.println("Connected to central device");

    while (central.connected()) {
      if (record_ready) {
        audioDataCharacteristic.writeValue((uint8_t*)recording_buf, sizeof(recording_buf));
        record_ready = false;
      }
    }
    Serial.println("Disconnected from central device");
  }
}

static void audio_rec_callback(uint16_t *buf, uint32_t buf_len) {
  // Convert uint16_t buffer to int16_t buffer
  for (int i = 0; i < SAMPLES; i++) {
    recording_buf[i] = (int16_t)buf[i];
  }
  record_ready = true;
}
eng1n88r commented 6 months ago

Initial firmware version has similar implementation. You could take a look here (should be in a deleted file). You will find there usage of LEDs and IMU. Regard battery service usage check examples in the arduino IDE there should be a few image

after-ephemera commented 5 months ago

@felyu I'm going to close this for now since there are no pending issues. If you'd like to open a PR with the arduino code somewhere you think it might be useful please do.

francip commented 5 months ago

@felyu Inhave my Arduino Nano RP2040 implementation in https://github.com/francip/frienduino. Feel free to use it, or fix it (my audio streaming has some problems) any way you want. (I should put MIT license)