Trying to implement the Machine learning in Arduino Nano BLE sense Rev 2 using the tensor flow library but getting error

I have tried to Implement the gesture classification model in Arduino Nano 33 BLE sense rev 2 board using. For reference I have followed the due procedure mentioned in the official website. But after acquiring the accelerometer data from the sensor and train it the due procedure I have faced a problem while compiling it in the last step. I have paste the code below and the error I am getting.

The tensor flow lite library is also giving me the problem as I was not getting the library from the official site but I found it in an github repository and intalled it from there.

Please help with the error:

#include <TensorFlowLite_ESP32.h>

#include <Arduino_BMI270_BMM150.h>


//#include <TensorFlowLite.h>

#include <tensorflow/lite/micro/all_ops_resolver.h>
#include <tensorflow/lite/micro/micro_error_reporter.h>
#include <tensorflow/lite/micro/micro_interpreter.h>
#include <tensorflow/lite/schema/schema_generated.h>
#include <tensorflow/lite/micro/system_setup.h>
//#include <tensorflow/lite/version.h>

#include "model.h"

const float accelerationThreshold = 2.5; // threshold of significant in G's
const int numSamples = 119;

int samplesRead = numSamples;

// global variables used for TensorFlow Lite (Micro)
tflite::MicroErrorReporter tflErrorReporter;

// pull in all the TFLM ops, you can remove this line and
// only pull in the TFLM ops you need, if would like to reduce
// the compiled size of the sketch.
tflite::AllOpsResolver tflOpsResolver;

const tflite::Model* tflModel = nullptr;
tflite::MicroInterpreter* tflInterpreter = nullptr;
TfLiteTensor* tflInputTensor = nullptr;
TfLiteTensor* tflOutputTensor = nullptr;

// Create a static memory buffer for TFLM, the size may need to
// be adjusted based on the model you are using
constexpr int tensorArenaSize = 8 * 1024;
byte tensorArena[tensorArenaSize] __attribute__((aligned(16)));

// array to map gesture index to a name
const char* GESTURES[] = {
  "punch",
  "flex"
};

#define NUM_GESTURES (sizeof(GESTURES) / sizeof(GESTURES[0]))

void setup() {
  Serial.begin(9600);
  while (!Serial);

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

  // print out the samples rates of the IMUs
  Serial.print("Accelerometer sample rate = ");
  Serial.print(IMU.accelerationSampleRate());
  Serial.println(" Hz");
  Serial.print("Gyroscope sample rate = ");
  Serial.print(IMU.gyroscopeSampleRate());
  Serial.println(" Hz");

  Serial.println();

  // get the TFL representation of the model byte array
  tflModel = tflite::GetModel(model);
  if (tflModel->version() != TFLITE_SCHEMA_VERSION) {
    Serial.println("Model schema mismatch!");
    while (1);
  }

  // Create an interpreter to run the model
  tflInterpreter = new tflite::MicroInterpreter(tflModel, tflOpsResolver, tensorArena, tensorArenaSize, &tflErrorReporter);

  // Allocate memory for the model's input and output tensors
  tflInterpreter->AllocateTensors();

  // Get pointers for the model's input and output tensors
  tflInputTensor = tflInterpreter->input(0);
  tflOutputTensor = tflInterpreter->output(0);
}

void loop() {
  float xAcc, yAcc, zAcc, xGyro, yGyro, zGyro;

  // wait for significant motion
  while (samplesRead == numSamples) {
    if (IMU.accelerationAvailable()) {
      // read the acceleration data
      IMU.readAcceleration(xAcc, yAcc, zAcc);

      // sum up the absolutes
      float aSum = fabs(xAcc) + fabs(yAcc) + fabs(zAcc);

      // check if it's above the threshold
      if (aSum >= accelerationThreshold) {
        // reset the sample read count
        samplesRead = 0;
        break;
      }
    }
  }

  // check if the all the required samples have been read since
  // the last time the significant motion was detected
  while (samplesRead < numSamples) {
    // check if new acceleration AND gyroscope data is available
    if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
      // read the acceleration and gyroscope data
      IMU.readAcceleration(xAcc, yAcc, zAcc);
      IMU.readGyroscope(xGyro, yGyro, zGyro);

      // normalize the IMU data between 0 to 1 and store in the model's
      // input tensor
      tflInputTensor->data.f[samplesRead * 6 + 0] = (xAcc + 4.0) / 8.0;
      tflInputTensor->data.f[samplesRead * 6 + 1] = (yAcc + 4.0) / 8.0;
      tflInputTensor->data.f[samplesRead * 6 + 2] = (zAcc + 4.0) / 8.0;
      tflInputTensor->data.f[samplesRead * 6 + 3] = (xGyro + 2000.0) / 4000.0;
      tflInputTensor->data.f[samplesRead * 6 + 4] = (yGyro + 2000.0) / 4000.0;
      tflInputTensor->data.f[samplesRead * 6 + 5] = (zGyro + 2000.0) / 4000.0;

      samplesRead++;

      if (samplesRead == numSamples) {
        // Run inferencing
        TfLiteStatus invokeStatus = tflInterpreter->Invoke();
        if (invokeStatus != kTfLiteOk) {
          Serial.println("Invoke failed!");
          while (1);
          return;
        }

        // Loop through the output tensor values from the model
        for (int i = 0; i < NUM_GESTURES; i++) {
          Serial.print(GESTURES[i]);
          Serial.print(": ");
          Serial.println(tflOutputTensor->data.f[i], 6);
        }
        Serial.println();
      }
    }
  }
}/*
  IMU Capture

  This example uses the on-board IMU to start reading acceleration and gyroscope
  data from on-board IMU and prints it to the Serial Monitor for one second
  when the significant motion is detected.

  You can also use the Serial Plotter to graph the data.

  The circuit:
  - Arduino Nano 33 BLE or Arduino Nano 33 BLE Sense board.

  Created by Don Coleman, Sandeep Mistry
  Modified by Dominic Pajak, Sandeep Mistry

  This example code is in the public domain.
*/

#include <Arduino_BMI270_BMM150.h>

const float accelerationThreshold = 2.5; // threshold of significant in G's
const int numSamples = 119;

int samplesRead = numSamples;

void setup() {
  Serial.begin(9600);
  while (!Serial);

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

  // print the header
  Serial.println("xAcc,yAcc,zAcc,gX,gY,gZ");
}

void loop() {
  float xAcc, yAcc, zAcc, xGyro, yGyro, zGyro;

  // wait for significant motion
  while (samplesRead == numSamples) {
    if (IMU.accelerationAvailable()) {
      // read the acceleration data
      IMU.readAcceleration(xAcc, yAcc, zAcc);

      // sum up the absolutes
      float aSum = fabs(xAcc) + fabs(yAcc) + fabs(zAcc);

      // check if it's above the threshold
      if (aSum >= accelerationThreshold) {
        // reset the sample read count
        samplesRead = 0;
        break;
      }
    }
  }

  // check if the all the required samples have been read since
  // the last time the significant motion was detected
  while (samplesRead < numSamples) {
    // check if both new acceleration and gyroscope data is
    // available
    if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
      // read the acceleration and gyroscope data
      IMU.readAcceleration(xAcc, yAcc, zAcc);
      IMU.readGyroscope(xGyro, yGyro, zGyro);

      samplesRead++;

      // print the data in CSV format
      Serial.print(xAcc, 3);
      Serial.print(',');
      Serial.print(yAcc, 3);
      Serial.print(',');
      Serial.print(zAcc, 3);
      Serial.print(',');
      Serial.print(xGyro, 3);
      Serial.print(',');
      Serial.print(yGyro, 3);
      Serial.print(',');
      Serial.print(zGyro, 3);
      Serial.println();

      if (samplesRead == numSamples) {
        // add an empty line if it's the last sample
        Serial.println();
      }
    }
  }
}

The error I am getting is :slight_smile:

C:\Users\AP\Documents\Arduino\IMU_Capture\IMU_Capture.ino:15:10: fatal error: model.h: No such file or directory
#include "model.h"
^~~~~~~~~
compilation terminated.
exit status 1

Compilation error: model.h: No such file or directory

And how wold you interpret the error message you read?

Well it is because of the main code is unable to include the model.h file but I have keep both the main file and the model.h file into the same folder as described in the documentation.

If "model.h" is not in the same folder as your *.ino it won't work.

It is in the same folder and the name is also same as model.h still the same error is there.

I strongly doubt that. Most likely the file is called "model.h.ino" and you don't know that because you have not configured your M$ to show you the file extensions.

Ok thank you for the help. I have changed the folder and the execution seems ok because that error is not anymore but now I am having a new issue which is showing like:

C:\Users\AP\Documents\Arduino\libraries\TensorFlowLite_ESP32\src\bus\i2c_bus.c:19:10: fatal error: freertos/FreeRTOS.h: No such file or directory
#include "freertos/FreeRTOS.h"
^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1

Compilation error: exit status 1

I am not able to understand this error. If anyone can help me please feel free to reply.

The tutorial you use is from 2019 - so outdated at best. Use the library manager and install "TensorFlowLite_ESP32", then try any of the examples.

The tutorials published in the documentation section of the Arduino website are outdated and refer to an obsolete version of the TensorFlow Lite Micro library.

The library mentioned in the tutorial and available on the linked GitHub repository has not been synchronized with the source tflite-micro repository since 2022.

Between 2019, when the tutorials were created, and 2022, that repository was updated but the version number remained at 2.4.0-ALPHA, so it is no longer the same library for which the sketches were written.

The original 2.4.0-ALPHA library can be downloaded from another link and allows the sketch to compile correctly.
The initial project for porting TensorFlow Lite Micro to Arduino is currently not maintained.

For this reason, we have created a new "porting" project to Arduino by creating a new version of the TensorFlow Lite Micro library, called Chirale_TensorFlowLite, which can be installed via the Arduino IDE's library manager.
This library is the updated version of the Arduino_TensorFlowLite library and, like it, does not contain APIs in the typical simplified Arduino style.

To enable a simpler and more intuitive use of TensorFlowLite, we have defined another library, called ArduTFLite, which can be installed from the Arduino IDE, offering simple and direct APIs in the Arduino style.

This library includes an updated and clearer version of the IMU_Classifier sketch as an example.

These new libraries works on all mbed_nano, mbed_giga, mbed_portenta, mbed_nicla and esp32_nano boards.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.