Hello community! Hoping someone can help me figure this one out…
Background:
I’m working on a project that uses an ODrive brushless motor controller with Edge Impulse (on an Arduino Nano 33 BLE Sense). The main code is based on this guide for classifying data on the Arduino. The main difference is that instead of 3 accelerometer axes I’m using input velocity, measured velocity, and current draw from the ODrive.
The problem:
My code is getting stuck when the features
buffer length reaches 258. Every time. I used the Arduino’s LED_BUILTIN
to see if the code is entering the classification if
block, and it’s not! The EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE
is 300 (confirmed with Serial.print()
), so the fact that it’s stopping at 258 has me stumped!
Here is the code, with a comment where it is getting stuck:
/* Includes ---------------------------------------------------------------- */
#include <odrive_inferencing.h>
#include <HardwareSerial.h>
#include <ODriveArduino.h>
#include <Wire.h>
#include <Arduino.h>
// Printing with stream operator helper functions
template<class T> inline Print& operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
template<> inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }
HardwareSerial& odrive_serial = Serial1;
ODriveArduino odrive(odrive_serial);
#define FREQUENCY_HZ EI_CLASSIFIER_FREQUENCY
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
static unsigned long last_interval_ms = 0;
size_t feature_ix = 0;
static float features[] = {};
int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 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);
}
}
void setup()
{
// Debug LED
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
Serial.begin(115200);
while (!Serial);
odrive_serial.begin(115200);
while (!odrive_serial);
}
void loop() {
// Initialize parameter variables
float input_vel, meas_vel, current;
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
// Get parameter values
input_vel = odrive.GetInputVel(0);
meas_vel = odrive.GetSensorlessVelocityEstimate(0);
current = odrive.GetIbus();
// Fill the features buffer
features[feature_ix++] = input_vel;
features[feature_ix++] = meas_vel;
features[feature_ix++] = current;
// Check length of feature buffer
Serial.println(feature_ix);
// CODE GETTING STUCK HERE WHEN feature_ix REACHES 258
// Features buffer full? then classify!
if (feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
// Toggle LED to see if entering 'if' block
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
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);
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;
}
}
}
Here is the Edge Impulse project for reference (am still adding more data so ignore the accuracy ;)).
Thanks in advance for any ideas!
Edit: Perhaps worth noting that I had originally designed the project to use two axes (input / measured velocity) and eventually changed it to three. The odrive_inferencing.h
library being imported into the project is definitely the most up-to-date version, but maybe there’s some vestigal parameter that snuck in from the two-axis version of the project?