Deploying a model on ESP 32

Question/Issue: I am currently trying to deploy this model onto the ESP Wroom 32
I came across this example GitHub - edgeimpulse/esp32-platformio-edge-impulse-standalone-example: Minimal example code for running an Edge Impulse designed neural network on an ESP32 dev kit using platformio. It is great, however, the context of my project is live activity recognition and this is static. Can you please guide me through the deployment ?

I even tried using the following code to deploy in arduino

// Include the Arduino library here (something like your_project_inference.h)
// In the Arduino IDE see **File > Examples > Your project name - Edge Impulse > Static buffer** to get the exact name
#include <SDP-_6_Class_Dataset_inferencing.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

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

static unsigned long last_interval_ms = 0;
// to classify 1 frame of data you need EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE values
float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
// keep track of where we are in the feature array
size_t feature_ix = 0;

Adafruit_MPU6050 mpu;

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

  if (!mpu.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1)
      ;
  }
  mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
}

void loop() {
  float x, y, z;

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

    // read sensor data in exactly the same way as in the Data Forwarder example
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);

    x = a.acceleration.x;
    y = a.acceleration.y;
    z = a.acceleration.z;

    // fill the features buffer
    features[feature_ix++] = x * CONVERT_G_TO_MS2;
    features[feature_ix++] = y * CONVERT_G_TO_MS2;
    features[feature_ix++] = z * CONVERT_G_TO_MS2;

    // features buffer full? then classify!
    if (feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
      ei_impulse_result_t result;

      // create signal from features frame
      signal_t signal;
      numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);

      // run classifier
      EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
      ei_printf("run_classifier returned: %d\n", res);
      if (res != 0) return;

      // print predictions
      ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
                result.timing.dsp, result.timing.classification, result.timing.anomaly);

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

      // reset features frame
      feature_ix = 0;
    }
  }
}

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);
  }
}

it is completely confusing the activities. For instance it reports walking instead of idle. If possible can you also guide me through the process of selecting the ideal model for my data. I am suspecting that my model is flawed.

Project ID: 214635

Context/Use case:

Hello @gsawalha,

I cannot find your project. Have you deleted it by any chance?

Best,

Louis

apologies here is the new project code 214666. I am currently facing issues with deployment. Although I believe that the accuracy levels are good, it is unfortunately not reporting the right activity upon deployment.

Thanks,

I have not seen anything strange either in your project or in your arduino code.
I generated the output of the data explorer for your project to see if I could spot anything weird but it separates nicely.

Here are a couple of things that you can check:

On the board:

  • Is your sensor properly attached to your board?
  • Is there any other process running that can “break” the loop function, thus creating an inconsistency in your data sampling (interrupt for instance).
  • You can also try to use a timer interrupt instead of the if (millis() > last_interval_ms + INTERVAL_MS)
  • Is it the same sensor that you used to collect the data? Was it configured exactly the same?

On your ML pipeline:

I hope that helps.

Best,

Louis

Hi I just confirmed it is a sensor calibration issue or set up I think. I just do not know how to fix it. Can you help please?
I am using the Adafruit MPU6050
Frequency 62.5 and I ran this code before starting the data forwarder
#include <Adafruit_MPU6050.h>

#include <Adafruit_Sensor.h>

#include <Wire.h>

#define FREQUENCY_HZ 62.5

#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))

// objeto da classe Adafruit_MPU6050

Adafruit_MPU6050 mpu;

static unsigned long last_interval_ms = 0;

void setup() {

Serial.begin(115200);

Serial.println(“Classificador de gestos com TinyML”);

// Try to initialize!

if (!mpu.begin()) {

Serial.println(“Failed to find MPU6050 chip”);

while (1) {

delay(10);

}

}

Serial.println(“MPU6050 Found!”);

mpu.setAccelerometerRange(MPU6050_RANGE_8_G);

Serial.print("Accelerometer range set to: ");

switch (mpu.getAccelerometerRange()) {

case MPU6050_RANGE_2_G:

Serial.println(“±2G”);

break;

case MPU6050_RANGE_4_G:

Serial.println(“±4G”);

break;

case MPU6050_RANGE_8_G:

Serial.println(“±8G”);

break;

case MPU6050_RANGE_16_G:

Serial.println(“±16G”);

break;

}

mpu.setGyroRange(MPU6050_RANGE_500_DEG);

Serial.print("Gyro range set to: ");

switch (mpu.getGyroRange()) {

case MPU6050_RANGE_250_DEG:

Serial.println(“± 250 deg/s”);

break;

case MPU6050_RANGE_500_DEG:

Serial.println(“± 500 deg/s”);

break;

case MPU6050_RANGE_1000_DEG:

Serial.println(“± 1000 deg/s”);

break;

case MPU6050_RANGE_2000_DEG:

Serial.println(“± 2000 deg/s”);

break;

}

mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

Serial.print("Filter bandwidth set to: ");

switch (mpu.getFilterBandwidth()) {

case MPU6050_BAND_260_HZ:

Serial.println(“260 Hz”);

break;

case MPU6050_BAND_184_HZ:

Serial.println(“184 Hz”);

break;

case MPU6050_BAND_94_HZ:

Serial.println(“94 Hz”);

break;

case MPU6050_BAND_44_HZ:

Serial.println(“44 Hz”);

break;

case MPU6050_BAND_21_HZ:

Serial.println(“21 Hz”);

break;

case MPU6050_BAND_10_HZ:

Serial.println(“10 Hz”);

break;

case MPU6050_BAND_5_HZ:

Serial.println(“5 Hz”);

break;

}

Serial.println(“”);

delay(100);

}

void loop() {

sensors_event_t a, g, temp;

if (millis() > last_interval_ms + INTERVAL_MS) {

last_interval_ms = millis();

mpu.getEvent(&a, &g, &temp);

Serial.print(a.acceleration.x);

Serial.print(“,”);

Serial.print(a.acceleration.y);

Serial.print(“,”);

Serial.println(a.acceleration.z);

}

}

I used this code to run the inferencing after redoing the data acquisition, double checking the connections and changing the inference code (here’s a reference to the new project I used 215002). I am still not getting anything to work, it is reporting falling when Idle.
#include <g_sawalha-project-1_inferencing.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

#define FREQUENCY_HZ 62.5
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))

// objeto da classe Adafruit_MPU6050
Adafruit_MPU6050 mpu;

float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
size_t feature_ix = 0;

static unsigned long last_interval_ms = 0;

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

if (!mpu.begin()) {
Serial.println(“Failed to find MPU6050 chip”);
while (1) {
delay(10);
}
}
Serial.println(“MPU6050 Found!”);

mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
Serial.print("Accelerometer range set to: ");
switch (mpu.getAccelerometerRange()) {
case MPU6050_RANGE_2_G:
Serial.println(“±2G”);
break;
case MPU6050_RANGE_4_G:
Serial.println(“±4G”);
break;
case MPU6050_RANGE_8_G:
Serial.println(“±8G”);
break;
case MPU6050_RANGE_16_G:
Serial.println(“±16G”);
break;
}
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
Serial.print("Gyro range set to: ");
switch (mpu.getGyroRange()) {
case MPU6050_RANGE_250_DEG:
Serial.println(“± 250 deg/s”);
break;
case MPU6050_RANGE_500_DEG:
Serial.println(“± 500 deg/s”);
break;
case MPU6050_RANGE_1000_DEG:
Serial.println(“± 1000 deg/s”);
break;
case MPU6050_RANGE_2000_DEG:
Serial.println(“± 2000 deg/s”);
break;
}

mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.print("Filter bandwidth set to: ");
switch (mpu.getFilterBandwidth()) {
case MPU6050_BAND_260_HZ:
Serial.println(“260 Hz”);
break;
case MPU6050_BAND_184_HZ:
Serial.println(“184 Hz”);
break;
case MPU6050_BAND_94_HZ:
Serial.println(“94 Hz”);
break;
case MPU6050_BAND_44_HZ:
Serial.println(“44 Hz”);
break;
case MPU6050_BAND_21_HZ:
Serial.println(“21 Hz”);
break;
case MPU6050_BAND_10_HZ:
Serial.println(“10 Hz”);
break;
case MPU6050_BAND_5_HZ:
Serial.println(“5 Hz”);
break;
}

Serial.println(“”);
delay(100);

Serial.print("Features: ");
Serial.println(EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
Serial.print("Label count: ");
Serial.println(EI_CLASSIFIER_LABEL_COUNT);

}

void loop() {
sensors_event_t a, g, temp;

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

mpu.getEvent(&a, &g, &temp);

features[feature_ix++] = a.acceleration.x;
features[feature_ix++] = a.acceleration.y;
features[feature_ix++] = a.acceleration.z;

if (feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
  Serial.println("Running the inference...");
  signal_t signal;
  ei_impulse_result_t result;
  int err = numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
  if (err != 0) {
    ei_printf("Failed to create signal from buffer (%d)\n", err);
    return;
  }

  EI_IMPULSE_ERROR res = run_classifier(&signal, &result, true);

  if (res != 0) return;

  ei_printf("Predictions ");
  ei_printf("(DSP: %d ms., Classification: %d ms.)",
            result.timing.dsp, result.timing.classification);
  ei_printf(": \n");

  for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
    ei_printf("    %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
  }
  feature_ix = 0;
}

}
}

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);
}
}

Hello @gsawalha,

I am not familiar with that sensor.

I’d suggest you also ping Adafruit on their forum: https://forums.adafruit.com/

Best,

Louis