ERR: Failed to run DSP process (-1004) when using run_classifier

Question/Issue:
I’m currently doing a gesture recognition using an accelerometer, gyroscope and 4 potentiometers, I followed the data forwarder tutorial and used the arduino library edge impulse documentation
Data forwarder | Edge Impulse Documentation
Arduino library | Edge Impulse Documentation

I changed the code “Classifying data” from the first link and it is currently the following:

#define __STATIC_FORCEINLINE attribute((always_inline)) static inline
#define __SSAT(ARG1, ARG2)
extension
({
int32_t __RES, __ARG1 = (ARG1);
__ASM volatile (“ssat %0, %1, %2” : “=r” (__RES) : “I” (ARG2), “r” (__ARG1) : “cc” );
__RES;
})
#define EIDSP_USE_CMSIS_DSP 1
#define EIDSP_LOAD_CMSIS_DSP_SOURCES 1

#include <tcc_duti_inferencing.h>
#include <Arduino_LSM6DS3.h>

#define CONVERT_G_TO_MS2 9.80665f
#define FREQUENCY_HZ EI_CLASSIFIER_FREQUENCY
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))

// Definição dos pinos dos potenciômetros
#define POT1_PIN A0
#define POT2_PIN A1
#define POT3_PIN A2
#define POT4_PIN A3

static unsigned long last_interval_ms = 0;
// Buffer para armazenar os dados coletados
float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
size_t feature_ix = 0;

int qtddados = 0;

void setup() {
Serial.begin(115200);
Serial.println(“Started”);

// Inicialização do sensor IMU
if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
}
delay(5000);

}

void loop() {
unsigned long start_time = millis(); // Marca o início do loop

float ax, ay, az; // Valores do acelerômetro
float gx, gy, gz; // Valores do giroscópio
int p1, p2, p3, p4; // Valores dos potenciômetros

if (millis() > last_interval_ms + INTERVAL_MS) {
    last_interval_ms = millis();

    // Leitura do acelerômetro
    IMU.readAcceleration(ax, ay, az);
    features[feature_ix++] = ax * CONVERT_G_TO_MS2;
    features[feature_ix++] = ay * CONVERT_G_TO_MS2;
    features[feature_ix++] = az * CONVERT_G_TO_MS2;

    // Leitura do giroscópio
    IMU.readGyroscope(gx, gy, gz);
    features[feature_ix++] = gx;
    features[feature_ix++] = gy;
    features[feature_ix++] = gz;

    // Leitura dos potenciômetros
    p1 = analogRead(POT1_PIN);
    p2 = analogRead(POT2_PIN);
    p3 = analogRead(POT3_PIN);
    p4 = analogRead(POT4_PIN);
    features[feature_ix++] = p1;
    features[feature_ix++] = p2;
    features[feature_ix++] = p3;
    features[feature_ix++] = p4;
    qtddados++;
    Serial.print("Leu os dados: ");
    Serial.println(qtddados);
    Serial.print("feature_ix: ");
    Serial.println(feature_ix);
    
    // Quando o buffer estiver cheio, processa a classificação
    if (feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
        ei_impulse_result_t result;
        Serial.println("Processando");

        // Criação do sinal a partir do buffer
        signal_t signal;
        numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
        Serial.println("Sinal a partir do buffer criado");

        // Executa o classificador
        EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
        Serial.println("Classificador executado");
        if (res != 0) return;
        Serial.println("Sem erros");
        // Determina a classe com maior probabilidade
        float max_value = 0.0f;
        const char* max_label = "";
        for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
            Serial.println("Inicio FOR");
            if (result.classification[ix].value > max_value) {
                Serial.println("Inicio IF");
                max_value = result.classification[ix].value;
                max_label = result.classification[ix].label;
            }
        }

        // Imprime a classe com maior probabilidade
        ei_printf("Class: %s (Confidence: %d%%)\n", max_label, static_cast<int>(max_value * 100));

        // Reinicia o buffer
        feature_ix = 0;
        qtddados = 0;
    }

    unsigned long end_time = millis(); // Marca o final do loop
    Serial.print("Tempo gasto no loop: ");
    Serial.print(end_time - start_time);
    Serial.println(" ms");
}

}

void ei_printf(const char *format, …) {
static char print_buf[1024] = { 0 };

va_list args;
va_start(args, format);
int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
va_end(args);

if (r > 0) {
    Serial.write(print_buf);
}

}

Basically what happens is, it collects the data from all of my sensors and potentiometers (totaling 2450 different data) and runs the loop one time correctly, no errors occur and the class most probable is printed in the serial monitor, however when running the loop a second time it collects the data as it should and has the same amount of data as the first time (2450) but when the code gets to the run_classifier function it returns the error -1004, I’ve read in the forums that the error is because one of the buffers passed into the function is the wrong size, but I don’t know how to solve this.

Project ID:
590102

Hi @laysboas

You need to reset the buffer, you can find some examples on the Arduino forum:

Best

Eoin

I tried some different ways to reset the buffer (memset, serial.Read and Serial.readBytes). The one that made the code act different was Serial.readBytes, I implemented it after the classification result like this:

(...)
            ei_printf("Class: %s (Confidence: %d%%)\n", max_label, static_cast<int>(max_value * 100));
            feature_ix = 0;
            qtddados = 0;

            while (Serial.available() > 0) {
                char temp_buffer[32];
                Serial.readBytes(temp_buffer, sizeof(temp_buffer));
            }
(...)

It kinda worked (I think) but the problem is still there, the code classifies correctly the first time but on the second time the code just stops on “EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);”. It doesn’t return anything, it just gets stuck, nothing gets printed.