Can i use Edge Impulse to collect data, train a model and deploy it on an Arduino Nano 33 BLE Sense

@Middleware & OS @everyone Hello guys, can I use Edge Impulse to collect data, train a model, and deploy it on an Arduino Nano 33 BLE Sense for anomaly detection? I'm having issues with deployment. Here's my code 👇
Solution:
i recommend reduce your model size. also use the Arduino IDE's memory usage reporting feature to get a detailed of how memory is being used in your sketch.
Jump to solution
13 Replies
Enthernet Code
Enthernet Code5mo ago
#include <EdgeImpulse.h>
#include <Arduino_LSM9DS1.h> // Include the library for the accelerometer

#define THRESHOLD 0.5 // Define the threshold for anomaly detection

// Function to initialize the Edge Impulse model
void initializeModel() {
// Initialize the Edge Impulse model
if (ei_impulse_init() != EI_IMPULSE_OK) {
Serial.println("Failed to initialize Edge Impulse model");
while (1); // Stop execution if initialization fails
}
}

void setup() {
// Start serial communication
Serial.begin(9600);

// Initialize Edge Impulse model
initializeModel();

// Initialize the accelerometer
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}

// Set built-in LED pin as output
pinMode(LED_BUILTIN, OUTPUT);
}

void collectData(ei::signal_t* signal) {
#include <EdgeImpulse.h>
#include <Arduino_LSM9DS1.h> // Include the library for the accelerometer

#define THRESHOLD 0.5 // Define the threshold for anomaly detection

// Function to initialize the Edge Impulse model
void initializeModel() {
// Initialize the Edge Impulse model
if (ei_impulse_init() != EI_IMPULSE_OK) {
Serial.println("Failed to initialize Edge Impulse model");
while (1); // Stop execution if initialization fails
}
}

void setup() {
// Start serial communication
Serial.begin(9600);

// Initialize Edge Impulse model
initializeModel();

// Initialize the accelerometer
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}

// Set built-in LED pin as output
pinMode(LED_BUILTIN, OUTPUT);
}

void collectData(ei::signal_t* signal) {
Enthernet Code
Enthernet Code5mo ago
float x, y, z;
static float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
static int feature_index = 0;

// Read data from the accelerometer
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);

// Fill the feature array with the collected data
features[feature_index++] = x;
features[feature_index++] = y;
features[feature_index++] = z;

// Reset the index if it exceeds the frame size
if (feature_index >= EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
feature_index = 0;
}
}

// Assign the features array to the signal data
signal->total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
signal->get_data = [](size_t offset, size_t length, float *out_ptr) -> int {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 0;
};
}

float runInference() {
ei_impulse_result_t result = { 0 };

// Run the Edge Impulse model and get the result
if (ei_run_impulse(&result) != EI_IMPULSE_OK) {
Serial.println("Failed to run Edge Impulse model");
return 0.0;
}

// Return the anomaly score from the result
return result.anomaly;
}

void loop() {
ei::signal_t signal;

// Collect data
collectData(&signal);

// Run anomaly detection
float anomalyScore = runInference();

// Check if the score is above a threshold indicating an anomaly
if (anomalyScore > THRESHOLD) {
// Handle anomaly (e.g., turn on an LED, send a notification)
Serial.println("Anomaly detected!");
digitalWrite(LED_BUILTIN, HIGH); // Turn on the built-in LED
} else {
digitalWrite(LED_BUILTIN, LOW); // Turn off the built-in LED
}

// Small delay to prevent excessive looping
delay(1000);
}
float x, y, z;
static float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
static int feature_index = 0;

// Read data from the accelerometer
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);

// Fill the feature array with the collected data
features[feature_index++] = x;
features[feature_index++] = y;
features[feature_index++] = z;

// Reset the index if it exceeds the frame size
if (feature_index >= EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
feature_index = 0;
}
}

// Assign the features array to the signal data
signal->total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
signal->get_data = [](size_t offset, size_t length, float *out_ptr) -> int {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 0;
};
}

float runInference() {
ei_impulse_result_t result = { 0 };

// Run the Edge Impulse model and get the result
if (ei_run_impulse(&result) != EI_IMPULSE_OK) {
Serial.println("Failed to run Edge Impulse model");
return 0.0;
}

// Return the anomaly score from the result
return result.anomaly;
}

void loop() {
ei::signal_t signal;

// Collect data
collectData(&signal);

// Run anomaly detection
float anomalyScore = runInference();

// Check if the score is above a threshold indicating an anomaly
if (anomalyScore > THRESHOLD) {
// Handle anomaly (e.g., turn on an LED, send a notification)
Serial.println("Anomaly detected!");
digitalWrite(LED_BUILTIN, HIGH); // Turn on the built-in LED
} else {
digitalWrite(LED_BUILTIN, LOW); // Turn off the built-in LED
}

// Small delay to prevent excessive looping
delay(1000);
}
Dtynin
Dtynin5mo ago
@Enthernet Code Edge Impulse is perfect for your Nano's anomaly detection! While your code looks good, you need to ensure a smooth deployment by verifying you have the correct Edge Impulse library (edge-impulse-arduino-sdk) for your Nano, double-check how the library defines ei_impulse_init() and ei_run_impulse() (import correct headers), and make sure collectData properly formats the data during collection.
Boss lady
Boss lady5mo ago
Yea, @Enthernet Code after applying this changes and modifications your code should look like
#include <Arduino_LSM9DS1.h> // Include the library for the accelerometer
#include <edge-impulse-sdk/classifier/ei_run_classifier.h> // Include Edge Impulse SDK

#define THRESHOLD 0.5 // Define the threshold for anomaly detection

// Function to initialize the Edge Impulse model
void initializeModel() {
// Initialize the Edge Impulse model
if (ei_impulse_init() != EI_IMPULSE_OK) {
Serial.println("Failed to initialize Edge Impulse model");
while (1); // Stop execution if initialization fails
}
}

void setup() {
// Start serial communication
Serial.begin(9600);

// Initialize Edge Impulse model
initializeModel();

// Initialize the accelerometer
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}

// Set built-in LED pin as output
pinMode(LED_BUILTIN, OUTPUT);
}

void collectData(ei::signal_t* signal) {
float x, y, z;
static float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
static int feature_index = 0;

// Read data from the accelerometer
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);

// Fill the feature array with the collected data
features[feature_index++] = x;
features[feature_index++] = y;
features[feature_index++] = z;

// Reset the index if it exceeds the frame size
if (feature_index >= EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
feature_index = 0;
}

#include <Arduino_LSM9DS1.h> // Include the library for the accelerometer
#include <edge-impulse-sdk/classifier/ei_run_classifier.h> // Include Edge Impulse SDK

#define THRESHOLD 0.5 // Define the threshold for anomaly detection

// Function to initialize the Edge Impulse model
void initializeModel() {
// Initialize the Edge Impulse model
if (ei_impulse_init() != EI_IMPULSE_OK) {
Serial.println("Failed to initialize Edge Impulse model");
while (1); // Stop execution if initialization fails
}
}

void setup() {
// Start serial communication
Serial.begin(9600);

// Initialize Edge Impulse model
initializeModel();

// Initialize the accelerometer
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}

// Set built-in LED pin as output
pinMode(LED_BUILTIN, OUTPUT);
}

void collectData(ei::signal_t* signal) {
float x, y, z;
static float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
static int feature_index = 0;

// Read data from the accelerometer
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);

// Fill the feature array with the collected data
features[feature_index++] = x;
features[feature_index++] = y;
features[feature_index++] = z;

// Reset the index if it exceeds the frame size
if (feature_index >= EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
feature_index = 0;
}

Boss lady
Boss lady5mo ago
}

// Assign the features array to the signal data
signal->total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
signal->get_data = [](size_t offset, size_t length, float *out_ptr) -> int {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 0;
};
}

float runInference() {
ei_impulse_result_t result = { 0 };

// Run the Edge Impulse model and get the result
if (ei_run_impulse(&result) != EI_IMPULSE_OK) {
Serial.println("Failed to run Edge Impulse model");
return 0.0;
}

// Return the anomaly score from the result
return result.anomaly;
}

void loop() {
ei::signal_t signal;

// Collect data
collectData(&signal);

// Run anomaly detection
float anomalyScore = runInference();

// Check if the score is above a threshold indicating an anomaly
if (anomalyScore > THRESHOLD) {
// Handle anomaly (e.g., turn on an LED, send a notification)
Serial.println("Anomaly detected!");
digitalWrite(LED_BUILTIN, HIGH); // Turn on the built-in LED
} else {
digitalWrite(LED_BUILTIN, LOW); // Turn off the built-in LED
}

// Small delay to prevent excessive looping
delay(1000);
}
}

// Assign the features array to the signal data
signal->total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
signal->get_data = [](size_t offset, size_t length, float *out_ptr) -> int {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 0;
};
}

float runInference() {
ei_impulse_result_t result = { 0 };

// Run the Edge Impulse model and get the result
if (ei_run_impulse(&result) != EI_IMPULSE_OK) {
Serial.println("Failed to run Edge Impulse model");
return 0.0;
}

// Return the anomaly score from the result
return result.anomaly;
}

void loop() {
ei::signal_t signal;

// Collect data
collectData(&signal);

// Run anomaly detection
float anomalyScore = runInference();

// Check if the score is above a threshold indicating an anomaly
if (anomalyScore > THRESHOLD) {
// Handle anomaly (e.g., turn on an LED, send a notification)
Serial.println("Anomaly detected!");
digitalWrite(LED_BUILTIN, HIGH); // Turn on the built-in LED
} else {
digitalWrite(LED_BUILTIN, LOW); // Turn off the built-in LED
}

// Small delay to prevent excessive looping
delay(1000);
}
wafa_ath
wafa_ath5mo ago
Are you seeing any specific error messages ?
Enthernet Code
Enthernet Code5mo ago
Failed to run Edge Impulse model
wafa_ath
wafa_ath5mo ago
maybe there is not enough memory available for the model to run. Can you provide the available memory before and after initializing the model?
Enthernet Code
Enthernet Code5mo ago
the available memory before running the code is 20200 bytes, and after initializing the model, it drops to 1500 bytes.
wafa_ath
wafa_ath5mo ago
it is likely that the model is consuming too much memory, and dosen't let enough space for the rest of the program
Enthernet Code
Enthernet Code5mo ago
Okay, do u suggest switching model or find a device with a much higher memory space
Solution
wafa_ath
wafa_ath5mo ago
i recommend reduce your model size. also use the Arduino IDE's memory usage reporting feature to get a detailed of how memory is being used in your sketch.
Enthernet Code
Enthernet Code5mo ago
Okay I would do this and give you my feedback, thanks 👍
Want results from more Discord servers?
Add your server