Error with Edge Impulse Libray using Arduino IDE + STM32F401RE + Accelerometer

Hi guys! How is it going? :smiley:

I’m trying to use STM32F401RE + IKS01A1 with Arduino IDE, to adquire data in real-time and using a while loop to do the inference continuously with Edge Impulse Library.

I have this program in Arduino IDE using the Accelerometer of my module, and I would like to implement Edge Impulse inference in a continuos while loop. I know I need to use several lectures but I don’t know how to proceed, and I’m stuck :(.

Can you help me? :(. This is the code, where I adquire de accelerometer data:

 // Includes.
 #include <LSM6DS0Sensor.h>
 
 #if defined(ARDUINO_SAM_DUE)
 #define DEV_I2C Wire1   //Define which I2C bus is used. Wire1 for the Arduino Due
 #define SerialPort Serial
 #else
 #define DEV_I2C Wire    //Or Wire
 #define SerialPort Serial
 #endif
 
 // Components.
 LSM6DS0Sensor *AccGyr;
 
 void setup() {
   // Led.
   pinMode(13, OUTPUT);
 
   // Initialize serial for output.
   SerialPort.begin(9600);
   
   // Initialize I2C bus.
   DEV_I2C.begin();
 
   // Initlialize components.
   AccGyr = new LSM6DS0Sensor(&DEV_I2C);
   AccGyr->Enable_X();
   AccGyr->Enable_G();
 }
 
 void loop() {
   // Led blinking.
   digitalWrite(13, HIGH);
   delay(250);
   digitalWrite(13, LOW);
   delay(250);
 
   // Read accelerometer and gyroscope.
   int32_t accelerometer[3];
   int32_t gyroscope[3];
   AccGyr->Get_X_Axes(accelerometer);
   AccGyr->Get_G_Axes(gyroscope);
 
   // Output data.
   SerialPort.print("| Acc[mg]: ");
   SerialPort.print(accelerometer[0]);
   SerialPort.print(" ");
   SerialPort.print(accelerometer[1]);
  SerialPort.print(" ");
  SerialPort.print(accelerometer[2]);
   SerialPort.print(" | Gyr[mdps]: ");
   SerialPort.print(gyroscope[0]);
   SerialPort.print(" ");
   SerialPort.print(gyroscope[1]);
   SerialPort.print(" ");
   SerialPort.print(gyroscope[2]);
   SerialPort.println(" |");
 }

I also did this program (I don’t know If I did it well), but I’m getting errors related to Edge Impulse Library when compiling :frowning:

/* Includes ---------------------------------------------------------------- */
#include <juacuegut-project-1_inference.h>

// Includes.
#include <LSM6DS0Sensor.h>

#if defined(ARDUINO_SAM_DUE)
#define DEV_I2C Wire1   //Define which I2C bus is used. Wire1 for the Arduino Due
#define SerialPort Serial
#else
#define DEV_I2C Wire    //Or Wire
#define SerialPort Serial
#endif


/* Constant defines -------------------------------------------------------- */
#define CONVERT_G_TO_MS2    9.80665f

/* Private variables ------------------------------------------------------- */
static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal

// Components.
LSM6DS0Sensor *AccGyr;

/**
* @brief      Arduino setup function
*/
void setup()
{
    // put your setup code here, to run once:
    Serial.begin(115200);
    Serial.println("Edge Impulse Inferencing Demo");
    

    if (EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME != 3) {
        ei_printf("ERR: EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME should be equal to 3 (the 3 sensor axes)\n");
        return;
    }

      // Led.
  pinMode(13, OUTPUT);
  
  // Initialize I2C bus.
  DEV_I2C.begin();

  // Initlialize components.
  AccGyr = new LSM6DS0Sensor(&DEV_I2C);
  AccGyr->Enable_X();
  AccGyr->Enable_G();
}

/**
* @brief      Printf function uses vsnprintf and output using Arduino Serial
*
* @param[in]  format     Variable argument list
*/
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);
   }
}

/**
* @brief      Get data and run inferencing
*
* @param[in]  debug  Get debug info if true
*/
void loop()
{
    ei_printf("\nStarting inferencing in 2 seconds...\n");

    delay(2000);

      // Led blinking.
  digitalWrite(13, HIGH);
  delay(250);
  digitalWrite(13, LOW);
  delay(250);

  // Read accelerometer and gyroscope.
  int32_t accelerometer[3];
  int32_t gyroscope[3];
  AccGyr->Get_X_Axes(accelerometer);
  AccGyr->Get_G_Axes(gyroscope);
  
    ei_printf("Sampling...\n");

    // Allocate a buffer here for the values we'll read from the IMU
    float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };

    for (size_t ix = 0; ix < EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE; ix += 3) {
        // Determine the next tick (and then sleep later)
        uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);

        //IMU.readAcceleration(buffer[ix], buffer[ix + 1], buffer[ix + 2]);

        buffer[ix + 0] = accelerometer[0];
        buffer[ix + 1] = accelerometer[1];
        buffer[ix + 2] = accelerometer[2];


        buffer[ix + 0] *= CONVERT_G_TO_MS2;
        buffer[ix + 1] *= CONVERT_G_TO_MS2;
        buffer[ix + 2] *= CONVERT_G_TO_MS2;

        delayMicroseconds(next_tick - micros());
    }

    // Turn the raw buffer in a signal which we can the classify
    signal_t signal;
    int err = numpy::signal_from_buffer(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
    if (err != 0) {
        ei_printf("Failed to create signal from buffer (%d)\n", err);
        return;
    }

    // Run the classifier
    ei_impulse_result_t result = { 0 };

    err = run_classifier(&signal, &result, debug_nn);
    if (err != EI_IMPULSE_OK) {
        ei_printf("ERR: Failed to run classifier (%d)\n", err);
        return;
    }

    // print the predictions
    ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
        result.timing.dsp, result.timing.classification, result.timing.anomaly);
    for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
        ei_printf("    %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
    }
#if EI_CLASSIFIER_HAS_ANOMALY == 1
    ei_printf("    anomaly score: %.3f\n", result.anomaly);
#endif
}

#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_ACCELEROMETER
#error "Invalid model for current sensor"
#endif 

Errors compiling:

c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::scale(ei::ei_matrix*, float) [clone .part.0]':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy5scaleEPNS_9ei_matrixEf.part.0+0x30): undefined reference to `arm_mat_scale_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::transpose(ei::ei_matrix*)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy9transposeEPNS_9ei_matrixE[_ZN2ei5numpy9transposeEPNS_9ei_matrixE]+0x62): undefined reference to `arm_mat_trans_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::mean(ei::ei_matrix*, ei::ei_matrix*)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4meanEPNS_9ei_matrixES2_[_ZN2ei5numpy4meanEPNS_9ei_matrixES2_]+0x56): undefined reference to `arm_mean_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::rfft(float const*, unsigned int, ei::fft_complex_t*, unsigned int, unsigned int)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj[_ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj]+0xfc): undefined reference to `arm_rfft_fast_init_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj[_ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj]+0x130): undefined reference to `arm_rfft_fast_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::rfft(float const*, unsigned int, float*, unsigned int, unsigned int)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPfjj[_ZN2ei5numpy4rfftEPKfjPfjj]+0xc8): undefined reference to `arm_rfft_fast_init_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPfjj[_ZN2ei5numpy4rfftEPKfjPfjj]+0xfc): undefined reference to `arm_rfft_fast_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPfjj[_ZN2ei5numpy4rfftEPKfjPfjj]+0x128): undefined reference to `arm_rms_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::spectral::feature::spectral_analysis(ei::ei_matrix*, ei::ei_matrix*, float, ei::spectral::filter_t, float, unsigned char, unsigned short, unsigned char, float, ei::ei_matrix*)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei8spectral7feature17spectral_analysisEPNS_9ei_matrixES3_fNS0_8filter_tEfhthfS3_[_ZN2ei8spectral7feature17spectral_analysisEPNS_9ei_matrixES3_fNS0_8filter_tEfhthfS3_]+0x76e): undefined reference to `arm_rms_f32'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compilando para la tarjeta Nucleo-64.

Hi @juacuegut,

Your second program looks good, it’s easier to start with the accelerometer sketch example as you did.

A couple of things I notice:

  • The Get_X/G_Axes functions return int32 but the buffer expects float. You should cast the value to float when assigning to the buffer array.
  • The following code should be put inside the loop, just before assigning the buffer array:
AccGyr->Get_X_Axes(accelerometer);
AccGyr->Get_G_Axes(gyroscope);

Aurelien

1 Like

Thank you for your kind words @aurel! :smiley:

I already did those changes but I’m getting the same errors:

c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::scale(ei::ei_matrix*, float) [clone .part.0]':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy5scaleEPNS_9ei_matrixEf.part.0+0x30): undefined reference to `arm_mat_scale_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::transpose(ei::ei_matrix*)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy9transposeEPNS_9ei_matrixE[_ZN2ei5numpy9transposeEPNS_9ei_matrixE]+0x62): undefined reference to `arm_mat_trans_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::mean(ei::ei_matrix*, ei::ei_matrix*)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4meanEPNS_9ei_matrixES2_[_ZN2ei5numpy4meanEPNS_9ei_matrixES2_]+0x56): undefined reference to `arm_mean_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::rfft(float const*, unsigned int, ei::fft_complex_t*, unsigned int, unsigned int)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj[_ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj]+0xfc): undefined reference to `arm_rfft_fast_init_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj[_ZN2ei5numpy4rfftEPKfjPNS_13fft_complex_tEjj]+0x130): undefined reference to `arm_rfft_fast_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::numpy::rfft(float const*, unsigned int, float*, unsigned int, unsigned int)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPfjj[_ZN2ei5numpy4rfftEPKfjPfjj]+0xc8): undefined reference to `arm_rfft_fast_init_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPfjj[_ZN2ei5numpy4rfftEPKfjPfjj]+0xfc): undefined reference to `arm_rfft_fast_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei5numpy4rfftEPKfjPfjj[_ZN2ei5numpy4rfftEPKfjPfjj]+0x128): undefined reference to `arm_rms_f32'
c:/arduino/portable/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: sketch\nano_ble33_sense_accelerometer_MODIFIED.ino.cpp.o: in function `ei::spectral::feature::spectral_analysis(ei::ei_matrix*, ei::ei_matrix*, float, ei::spectral::filter_t, float, unsigned char, unsigned short, unsigned char, float, ei::ei_matrix*)':
nano_ble33_sense_accelerometer_MODIFIED.ino.cpp:(.text._ZN2ei8spectral7feature17spectral_analysisEPNS_9ei_matrixES3_fNS0_8filter_tEfhthfS3_[_ZN2ei8spectral7feature17spectral_analysisEPNS_9ei_matrixES3_fNS0_8filter_tEfhthfS3_]+0x76e): undefined reference to `arm_rms_f32'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compilando para la tarjeta Nucleo-64.

It looks like I’ve undefined references like arm_mat_scale_f32', arm_mat_trans_f32’, `arm_rfft_fast_init_f32’… And I don’t know how to resolve them :(.

Can you help me guys? :frowning:

Could you set the:

        #define EIDSP_USE_CMSIS_DSP		        1
        #define EIDSP_LOAD_CMSIS_DSP_SOURCES    1

macros?

Thank you for your help @janjongboom. I did those changes, “modified src/edge-impulse-sdk/dsp/config.hpp” and declared the macros that appeared in https://docs.edgeimpulse.com/docs/running-your-impulse-arduino and it compiled!!!

Now I’m using the prebuilt dataset so I’ll try to collect my own :slight_smile:

I’ll be back with news.

Thanks for your help @aurel @janjongboom :smiley:

1 Like