Hello there everyone,
I have a trained model for audio classification, which works woderfully by itself.
And then I have an I2C set-up between the Nicla Sense ME(master) and Arduino Nano 33 Ble Sense(or Seeed Xiao Sense, tried with both, as slave). Which also works alone.
Here is the code for the I2C working between the 2 devices, a very simple i2c communication:
Master:
#include <Arduino.h>
#include "Nicla_System.h"
#include <Wire.h>
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600);
}
void loop() {
while (Serial.available() > 0) {
char incomingCharacter = Serial.read();
if (incomingCharacter == '1') {
Wire.beginTransmission(8); // transmit to device #8
Wire.write(5); // sends one byte
Wire.endTransmission(); // stop transmitting
Wire.requestFrom(8, 1); // request 1 byte from slave device #8
while (Wire.available()) { // slave may send less than requested
int c = Wire.read(); // receive a byte as character
Serial.print("Slave value : ");
Serial.println(c); // print the character
}
delay(100);
}
}
}
And here for the slave:
#include <Wire.h>
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop() {
}
// function that executes whenever data is received from master
void receiveEvent(int howMany) {
while (Wire.available()){
int x = Wire.read(); // receive byte as an integer
if (x == 5){
Serial.println("Hello World!");
}
}
}
// function that executes whenever data is requested by master
void requestEvent() {
Wire.write(8); // respond with message of 1 byte
}
Again, all of this code works.
Then my trained model had the void loop() edited so that it starts the recording and outputs the highest accuracy label and its accuracy, only after I send a 1 in the serial monitor (I am running record+classify, not continous):
while (Serial.available() > 0) {
char incomingCharacter = Serial.read();
if (incomingCharacter == '1') {
ei_printf("Starting...\n");
delay(350);
ei_printf("Recording...\n");
bool m = microphone_inference_record();
if (!m) {
ei_printf("ERR: Failed to record audio...\n");
return;
}
ei_printf("Recording done\n");
signal_t signal;
signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
signal.get_data = µphone_audio_signal_get_data;
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn);
if (r != EI_IMPULSE_OK) {
ei_printf("ERR: Failed to run classifier (%d)\n", r);
return;
}
// print the predictions
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
if (result.classification[ix].value > 0.5) {
Serial.println("Highest Prediction Classifier is: " + String(result.classification[ix].label) + "\nAccuracy is: " + String(result.classification[ix].value, 2));
}
}
}
}
}
This code works wonderfully as well. Nothing else, with the exception of the shown void loop has been changed.
Then if I try to move to I2C, I have the master the same, but the slave with 2 different methods, like this:
void setup()
{
Wire.begin(8); // join i2c bus with address #8
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
Serial.begin(115200); // start serial for output
}
void loop()
{
}
void receiveEvent(int howMany) {
while (Wire.available()) {
int x = Wire.read(); // receive byte as an integer
Serial.println(x);
if (x == 5) {
ei_printf("Starting...\n");
delay(350);
ei_printf("Recording...\n");
bool m = microphone_inference_record();
if (!m) {
ei_printf("ERR: Failed to record audio...\n");
return;
}
ei_printf("Recording done\n");
signal_t signal;
signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
signal.get_data = µphone_audio_signal_get_data;
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn);
if (r != EI_IMPULSE_OK) {
ei_printf("ERR: Failed to run classifier (%d)\n", r);
return;
}
// print the predictions
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
if (result.classification[ix].value > 0.5) {
Serial.println("Highest Prediction Classifier is: " + String(result.classification[ix].label) + "\nAccuracy is: " + String(result.classification[ix].value, 2));
//Wire.write(int(ix));
}
}
}
}
}
void requestEvent() {
Wire.write(label); // respond with message of 1 byte
}
And also with the following method:
void setup()
{
Wire.begin(8); // join i2c bus with address #8
Serial.begin(115200); // start serial for output
}
void loop()
{
while (Wire.available()) {
int x = Wire.read(); // receive byte as an integer
Serial.println(x);
if (x == 5) {
ei_printf("Starting...\n");
delay(350);
ei_printf("Recording...\n");
bool m = microphone_inference_record();
if (!m) {
ei_printf("ERR: Failed to record audio...\n");
return;
}
ei_printf("Recording done\n");
signal_t signal;
signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
signal.get_data = µphone_audio_signal_get_data;
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn);
if (r != EI_IMPULSE_OK) {
ei_printf("ERR: Failed to run classifier (%d)\n", r);
return;
}
// print the predictions
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
if (result.classification[ix].value > 0.5) {
Serial.println("Highest Prediction Classifier is: " + String(result.classification[ix].label) + "\nAccuracy is: " + String(result.classification[ix].value, 2));
Wire.write(int(ix));
}
}
}
}
}
Neither work, it receives the byte, prints it out, prints that it starts recording and it seems to stop when it needs to start the recording.
Any help would be appreciated!