Help modifying code for seeduino xaio rf52840 sense

Question/Issue:
I have successfully captured data and trained a model using the Seeed Sense. I’m using Accel x, and z and gyro x,y, and z I have loaded fresh data into the sample “Static” that came with the model, and it works. The code samples that came with the library will compile. My problem is the continuous example only uses 3 sensors and the fusion example uses 18. I was able to modify the code for the different IMU library use in the Seeeduino, LSM6DS3.h ( as opposed to the Arduino_LSM9DS1.h) the is in the sample code. I also modified the Sensor count to 6. Lastly, I replaced the call to retrieve the sensor values with the function calls that work for this device and worked successfully for me to collect training data. My code compiles and runs. However it doesn’t appear to run the AI model.

output:
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]
Predictions (DSP: 33 ms., Classification: 1 ms., Anomaly: 1 ms.): anomaly [ 0, 0, 0, 0, 0, 0, 10, ]

this is the output when I am repeating the motions I trained with.

Is it possible to use the Seeeduino with Edge? It still works when running the code I used to train the model.

Thank you!!

Project ID:

Douglas Phillips / Handbell Sim

Context/Use case:
Trying to use Seeeduino XAIO rf53840 sense

Steps Taken:
modified code to use the correct IMU

Expected Outcome:
Collect data continuously and identify motion.

Actual Outcome:
does not detect motions

Reproducibility:

  • [ Always

Environment:

  • Platform: [Seeduino XAIO rf53840 Sense.]
  • **Build Environment Details: Arduino IDE 2.3.2 ,Seeed XIAO BLE Sense - nRF52840
  • **OS Version: Windows 11]
  • Edge Impulse Version (Firmware): Edge Impulse data forwarder v1.27.1
  • To find out Edge Impulse Version:
  • if you have pre-compiled firmware: run edge-impulse-run-impulse --raw and type AT+INFO. Look for Edge Impulse version in the output.
    EI_STUDIO_VERSION_MAJOR 1
    EI_STUDIO_VERSION_MINOR 56
    EI_STUDIO_VERSION_PATCH 14
  • Edge Impulse CLI Version: [e.g., 1.5.0]
  • Project Version: [e.g., 1.0.0]
  • Custom Blocks / Impulse Configuration: [Describe custom blocks used or impulse configuration]
    Logs/Attachments:

Modified Code
/*
#define EI_CLASSIFIER_NN_INPUT_FRAME_SIZE 168
#define EI_CLASSIFIER_RAW_SAMPLE_COUNT 505
#define EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME 6
#define EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE (EI_CLASSIFIER_RAW_SAMPLE_COUNT * EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME) = 3,030
/
/
Includes ---------------------------------------------------------------- */
#include <Handbell_Sim_inferencing.h>
//#include <Arduino_LSM9DS1.h> //Click here to get the library: Arduino_LSM9DS1 - Arduino Reference
#include <LSM6DS3.h>
#include <Wire.h>

/* Constant defines -------------------------------------------------------- */
#define CONVERT_G_TO_MS2 9.80665f
#define MAX_ACCEPTED_RANGE 2.0f // starting 03/2022, models are generated setting range to ±2, but this example use Arudino library which set range to ±4g. If you are using an older model, ignore this value and use 4.0f instead

/* Private variables ------------------------------------------------------- */
static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal
static uint32_t run_inference_every_ms = 200;
static rtos::Thread inference_thread(osPriorityLow);
static float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
static float inference_buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];

/* Forward declaration */
void run_inference_background();

/**

  • @brief Arduino setup function
    */
    LSM6DS3 IMU(I2C_MODE, 0x6A);

void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
// comment out the below line to cancel the wait for USB connection (needed for native USB)
while (!Serial);
Serial.println(“Edge Impulse Inferencing Demo”);

// if (!IMU.begin()) {
//     ei_printf("Failed to initialize IMU!\r\n");
// }
// else {
//     ei_printf("IMU initialized\r\n");
// }

if (IMU.begin() != 0) {
Serial.println(“Device error”);
} else {
Serial.println(“Device OK!”);
}
if (EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME != 6) {
ei_printf(“ERR: EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME should be equal to 6 (the 6 sensor axes)\n”);
return;
}

inference_thread.start(mbed::callback(&run_inference_background));

}

/**

  • @brief Return the sign of the number
  • @param number
  • @return int 1 if positive (or 0) -1 if negative
    */
    float ei_get_sign(float number) {
    return (number >= 0.0) ? 1.0 : -1.0;
    }

/**

  • @brief Run inferencing in the background.
    */
    void run_inference_background()
    {
    // wait until we have a full buffer
    delay((EI_CLASSIFIER_INTERVAL_MS * EI_CLASSIFIER_RAW_SAMPLE_COUNT) + 100);

    // This is a structure that smoothens the output result
    // With the default settings 70% of readings should be the same before classifying.
    ei_classifier_smooth_t smooth;
    ei_classifier_smooth_init(&smooth, 10 /* no. of readings /, 7 / min. readings the same /, 0.8 / min. confidence /, 0.3 / max anomaly */);

    while (1) {
    // copy the buffer
    memcpy(inference_buffer, buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE * sizeof(float));

     // Turn the raw buffer in a signal which we can the classify
     signal_t signal;
     int err = numpy::signal_from_buffer(inference_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 ");
     ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",
         result.timing.dsp, result.timing.classification, result.timing.anomaly);
     ei_printf(": ");
    
     //ei_classifier_smooth_update yields the predicted label
     const char *prediction = ei_classifier_smooth_update(&smooth, &result);
      ei_printf("%s ", prediction);
     //print the cumulative results
     ei_printf(" [ ");
     for (size_t ix = 0; ix < smooth.count_size; ix++) {
         ei_printf("%u", smooth.count[ix]);
         if (ix != smooth.count_size + 1) {
             ei_printf(", ");
         }
         else {
           ei_printf(" ");
         }
     }
    ei_printf("]\n");
    
     delay(run_inference_every_ms);
    

    }

    ei_classifier_smooth_free(&smooth);
    }

/**

  • @brief Get data and run inferencing

  • @param[in] debug Get debug info if true
    */
    void loop()
    {
    while (1) {
    // Determine the next tick (and then sleep later)
    uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);

      // roll the buffer -3 points so we can overwrite the last one
       numpy::roll(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, -6);
    
      // read to the end of the buffer
    
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] = IMU.readFloatAccelX();
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] = IMU.readFloatAccelY();
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] = IMU.readFloatAccelZ();
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 4] = IMU.readFloatGyroX();
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 5] = IMU.readFloatGyroY();
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 6] = IMU.readFloatGyroZ();
      // Serial.print(buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1]);
      // Serial.print('=');
      // Serial.println(IMU.readFloatAccelX());
      
    //   for (int i = 1; i <=6;i++){
    //       Serial.print(i);Serial.print(":");
    //       Serial.print(buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - i] );Serial.print(",");
    //  }
    //   Serial.println("");
      // IMU.readAcceleration(
      //     buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3],
      //     buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2],
      //     buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1]
      // );
      // IMU.readGyroscope(
      //     buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 6],
      //     buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 5],
      //     buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 4]
    
    
      // )
      for (int i = 0; i < 6; i++) {
          if (fabs(buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 6 + i]) > MAX_ACCEPTED_RANGE) {
              buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 6 + i] = ei_get_sign(buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3 + i]) * MAX_ACCEPTED_RANGE;
          }
      }
    
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] *= CONVERT_G_TO_MS2;
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] *= CONVERT_G_TO_MS2;
      buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] *= CONVERT_G_TO_MS2;
    
      // and wait for next tick
       uint64_t time_to_wait = next_tick - micros();
      delay((int)floor((float)time_to_wait / 1000.0f));
      delayMicroseconds(time_to_wait % 1000);
    

    }
    }
    // need to modify this nect part for fusion . Constats found in
    // C:\Users\ctdph\Documents\arduino\libraries\Handbell_Sim_inferencing\model_metadata.h

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