ESP32 I2S dma buffer malloc failed after ble init

Thread Starter

Huyyuh

Joined Dec 27, 2021
4
Hello, I have ESP32 project that read data from INM441 microphone, after some processing ESP32 will send pattern to another ESP32.
I have test BLE code and I2S read INNP441 separately and successfully. However, when I put them together, I get this error

Error:
Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5856
entry 0x400806a8
Starting Arduino BLE Client application...
BLE Advertised Device found: Name: ESP32-BLE-Server, Address: 9c:9c:1f:e3:95:ce, serviceUUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, txPower: 3
E (759) I2S: Error malloc dma buffer
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:1796 (vQueueDelete)- assert failed!
abort() was called at PC 0x40090018 on core 1

ELF file SHA256: 0000000000000000

Backtrace: 0x4008ede8:0x3ffd7ac0 0x4008f065:0x3ffd7ae0 0x40090018:0x3ffd7b00 0x401681a9:0x3ffd7b20 0x4016829b:0x3ffd7b40 0x40169d39:0x3ffd7b70 0x4016a4e9:0x3ffd7bd0 0x400d3104:0x3ffd7c00 0x400dd376:0x3ffd7c70 0x4009011a:0x3ffd7c90
I attached my project here, please help me. Thanks in advance.
 

Attachments

Thread Starter

Huyyuh

Joined Dec 27, 2021
4
Hello MrSalts
Here is my ble api c++ file:
ble_client_api.cpp:
/* To use serial in function */
#include <Arduino.h>
#include "ble_client_api.h"

boolean  doConnect = false;
boolean  connected = false;
boolean  doScan = false;



void ble_init()
{

  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("ESP32-BLE-Client");

  /* Retrieve a Scanner and set the callback we want to use to be informed when we
     have detected a new device.  Specify that we want active scanning and start the
     scan to run for 5 seconds. */
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);
}

static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
                            uint8_t* pData, size_t length, bool isNotify)
{
  Serial.print("Notify callback for characteristic ");
  Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
  Serial.print(" of data length ");
  Serial.println(length);
  Serial.print("data: ");
  Serial.println((char*)pData);
}

class MyClientCallback : public BLEClientCallbacks
{
  void onConnect(BLEClient* pclient)
  {
   
  }

  void onDisconnect(BLEClient* pclient)
  {
    connected = false;
    Serial.println("onDisconnect");
  }
};

/* Start connection to the BLE Server */
bool connectToServer()
{
  Serial.print("Forming a connection to ");
  Serial.println(myDevice->getAddress().toString().c_str());
   
  BLEClient*  pClient  = BLEDevice::createClient();
  Serial.println(" - Created client");

  pClient->setClientCallbacks(new MyClientCallback());

    /* Connect to the remote BLE Server */
  pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
  Serial.println(" - Connected to server");

    /* Obtain a reference to the service we are after in the remote BLE server */
  BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
  if (pRemoteService == nullptr)
  {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    pClient->disconnect();
    return false;
  }
  Serial.println(" - Found our service");


  /* Obtain a reference to the characteristic in the service of the remote BLE server */
  pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
  if (pRemoteCharacteristic == nullptr)
  {
    Serial.print("Failed to find our characteristic UUID: ");
    Serial.println(charUUID.toString().c_str());
    pClient->disconnect();
    return false;
  }
  Serial.println(" - Found our characteristic");

  /* Read the value of the characteristic */
  /* Initial value is 'Hello, World!' */
  if(pRemoteCharacteristic->canRead())
  {
    std::string value = pRemoteCharacteristic->readValue();
    Serial.print("The characteristic value was: ");
    Serial.println(value.c_str());
  }

  if(pRemoteCharacteristic->canNotify())
  {
    pRemoteCharacteristic->registerForNotify(notifyCallback);

  }

    connected = true;
    return true;
}


void MyAdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice advertisedDevice)
{
  Serial.print("BLE Advertised Device found: ");
  Serial.println(advertisedDevice.toString().c_str());

  /* We have found a device, let us now see if it contains the service we are looking for. */
  if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID))
  {
    BLEDevice::getScan()->stop();
    myDevice = new BLEAdvertisedDevice(advertisedDevice);
    doConnect = true;
    doScan = true;
  }
};

void SendMess(String mess) {
    pRemoteCharacteristic->writeValue(mess.c_str(), mess.length());
}
Here is ble api header file
ble_client_api.h:
#ifndef BLE_CLIENT_API_H_
#define BLE_CLIENT_API_H_

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

#include "BLEDevice.h"

extern boolean doConnect;
extern boolean connected;
extern boolean doScan;

/* Specify the Service UUID of Server */
static BLEUUID serviceUUID(SERVICE_UUID);
/* Specify the Characteristic UUID of Server */
static BLEUUID    charUUID(CHARACTERISTIC_UUID);


static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;


void ble_init();

static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
                            uint8_t* pData, size_t length, bool isNotify);
bool connectToServer();

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
  void onResult(BLEAdvertisedDevice advertisedDevice);
};

void SendMess(String mess);
#endif
Here is my .ino file which have i2s init function:
ino file:
#include "freertos/FreeRTOS.h"
#include <Voice_Recognition_inferencing.h>
//#include <LiquidCrystal_I2C.h>

#include <driver/i2s.h>
#include "ble_client_api.h"

#include "model_params.h"

//LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);

const i2s_port_t I2S_PORT = I2S_NUM_0;
esp_err_t err;

int lastRec = 0;

int16_t sampleBuffer[SAMPLES_SIZE];
int16_t features[FEATURES_SIZE];

static void i2s_init(void){
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = I2S_SAMPLE_RATE,
    .bits_per_sample = i2s_bits_per_sample_t(I2S_SAMPLE_BITS),
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    .intr_alloc_flags = 0,
    .dma_buf_count = 64,
    .dma_buf_len = 1024,
    .use_apll = 1
  };

  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);

  const i2s_pin_config_t pin_config = {
    .bck_io_num = I2S_SCK,
    .ws_io_num = I2S_WS,
    .data_out_num = -1,
    .data_in_num = I2S_SD
  };

  i2s_set_pin(I2S_NUM_0, &pin_config);
}

int I2SRead()
{
  size_t bytesRead;

  Serial.println(" *** Recording Start ***");
  int count = 0;
  lastRec = millis();
  while(1){
    i2s_read(I2S_PORT, (void*) sampleBuffer, 4, &bytesRead, portMAX_DELAY);
    if(*sampleBuffer < (-40) || millis() - lastRec >= 6000){
      for(int i = 0;i < 16000; i++){
        i2s_read(I2S_PORT, (void*) sampleBuffer, 4, &bytesRead, portMAX_DELAY);
        features[i] = sampleBuffer[0];
       }
       break;
    }
  }
  Serial.println(" *** RECORDING ENDED *** ");
  return bytesRead;
}

int raw_get_data(size_t offset, size_t length, float *out_ptr) {
    return numpy::int16_to_float(features + offset, out_ptr, length);
}


void setup() {
  Serial.begin(115200);
  ble_init();
  i2s_init();
//  lcd_init();
//  lcd_backlight();
  Serial.println("Start inferencing");
}

void loop() {
  ei_printf("Edge Imppulss standalone inferencing (Arduino)\n");

  int byteRead = I2SRead();

  ei_impulse_result_t result = { 0 };

  signal_t signal;

  signal.total_length = 16000;
  signal.get_data = &raw_get_data;

  // Invoke the impulse
  EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
  ei_printf("run_classifier returned: %d\n", res);

  if (res != 0) return;

  // print the prediction
  ei_printf("Predictions ");
  ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",
      result.timing.dsp, result.timing.classification, result.timing.anomaly);
  ei_printf(": \n");
  ei_printf("[");
  // Send command when score is higher 0.5
  for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
    // ei_classifier_inferencing_categories[3] is stop command
    if (strcmp(result.classification[ix].label, ei_classifier_inferencing_categories[3]) &&
        (result.classification[ix].value > 0.5)) {
          ei_printf("Do Something here when here stop");
          if (connected) {
            SendMess(result.classification[ix].label);
          }
    }
  }
}
 

Thread Starter

Huyyuh

Joined Dec 27, 2021
4
Hello, I found that when I compile INMP441 code and ble code together, the code size become bigger which isn't enough size if set
.dma_buf_count = 64,
.dma_buf_len = 1024,
I tried reduce the number of dma buf and it work.
 
Top