Error- "rtos", "inference_thread", "mbed", "osPriorityLow"

I am using nano_ble33_sense_accelerometer_continuos example to modify and upload to wio terminal, but I am getting errors on the following keywords “rtos”, “inference_thread”, “mbed”, “osPriorityLow”. Can someone help me which libraries I need to import or include any files?
Thanks!

Hello @f20190094,

Can you please copy/paste the full error output and describe how you are compiling?

This is my code

#include <testing_inferencing.h>
// #include <Arduino_LSM9DS1.h>
#include"LIS3DHTR.h" //include accelerometer library
LIS3DHTR<TwoWire> lis; //Initialize accelerometer

/* Constant defines -------------------------------------------------------- */
#define CONVERT_G_TO_MS2    9.80665f

/* Private variables ------------------------------------------------------- */
static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal
static uint32_t run_inference_every_ms = 200;
static rtos::Thread inference_thread(osPriorityLow);
static float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
static float inference_buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];

/* Forward declaration */
void run_inference_background();

/**
* @brief      Arduino setup function
*/
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
	lis.begin(Wire1); //Start accelerometer 
Serial.println("Edge Impulse Inferencing Demo");

/*if (!IMU.begin()) {
ei_printf("Failed to initialize IMU!\r\n");
}
else {
ei_printf("IMU initialized\r\n");
}*/
	lis.setOutputDataRate(LIS3DHTR_DATARATE_200HZ); //Data output rate (5Hz up to 5kHz)
	lis.setFullScaleRange(LIS3DHTR_RANGE_8G);	

if (EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME != 3) {
ei_printf("ERR: EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME should be equal to 3 (the 3 sensor axes)\n");
return;
}

inference_thread.start(mbed::callback(&run_inference_background));
}

/**
* @brief      Printf function uses vsnprintf and output using Arduino Serial
*
* @param[in]  format     Variable argument list
*/
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);
   }
}

/**
 * @brief      Run inferencing in the background.
 */
void run_inference_background()
{
// wait until we have a full buffer
delay((EI_CLASSIFIER_INTERVAL_MS * EI_CLASSIFIER_RAW_SAMPLE_COUNT) + 100);

// This is a structure that smoothens the output result
// With the default settings 70% of readings should be the same before classifying.
ei_classifier_smooth_t smooth;
ei_classifier_smooth_init(&smooth, 10 /* no. of readings */, 7 /* min. readings the same */, 0.8 /* min. confidence */, 0.3 /* max anomaly */);

while (1) {
// copy the buffer
memcpy(inference_buffer, buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE * sizeof(float));

// Turn the raw buffer in a signal which we can the classify
signal_t signal;
int err = numpy::signal_from_buffer(inference_buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
if (err != 0) {
    ei_printf("Failed to create signal from buffer (%d)\n", err);
    return;
}

// Run the classifier
ei_impulse_result_t result = { 0 };

err = run_classifier(&signal, &result, debug_nn);
if (err != EI_IMPULSE_OK) {
    ei_printf("ERR: Failed to run classifier (%d)\n", err);
    return;
}

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

// ei_classifier_smooth_update yields the predicted label
const char *prediction = ei_classifier_smooth_update(&smooth, &result);
ei_printf("%s ", prediction);
// print the cumulative results
ei_printf(" [ ");
for (size_t ix = 0; ix < smooth.count_size; ix++) {
    ei_printf("%u", smooth.count[ix]);
    if (ix != smooth.count_size + 1) {
        ei_printf(", ");
    }
    else {
      ei_printf(" ");
    }
}
ei_printf("]\n");

delay(run_inference_every_ms);
}

ei_classifier_smooth_free(&smooth);
}

/**
* @brief      Get data and run inferencing
*
* @param[in]  debug  Get debug info if true
*/
void loop()
{
while (1) {
// Determine the next tick (and then sleep later)
uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);

// roll the buffer -3 points so we can overwrite the last one
numpy::roll(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, -3);

// read to the end of the buffer
/*IMU.readAcceleration(
    buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3],
    buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2],
    buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1]
);*/
		buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] = lis.getAccelerationX();
buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] = lis.getAccelerationY();
		buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] = lis.getAccelerationZ();

buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] *= CONVERT_G_TO_MS2;
buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] *= CONVERT_G_TO_MS2;
buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] *= CONVERT_G_TO_MS2;

// and wait for next tick
uint64_t time_to_wait = next_tick - micros();
delay((int)floor((float)time_to_wait / 1000.0f));
delayMicroseconds(time_to_wait % 1000);
}
}

#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_ACCELEROMETER
#error "Invalid model for current sensor"
#endif

And this is the error

C:\Users\Aryan\AppData\Local\Temp\.arduinoIDE-unsaved2022124-17740-kuu5up.c9qh\static_buffer\static_buffer.ino:35:8: error: 'rtos' does not name a type; did you mean 'ltoa'?
 static rtos::Thread inference_thread(osPriorityLow);
        ^~~~
        ltoa
C:\Users\Aryan\AppData\Local\Temp\.arduinoIDE-unsaved2022124-17740-kuu5up.c9qh\static_buffer\static_buffer.ino: In function 'void setup()':
C:\Users\Aryan\AppData\Local\Temp\.arduinoIDE-unsaved2022124-17740-kuu5up.c9qh\static_buffer\static_buffer.ino:66:5: error: 'inference_thread' was not declared in this scope
     inference_thread.start(mbed::callback(&run_inference_background));
     ^~~~~~~~~~~~~~~~
C:\Users\Aryan\AppData\Local\Temp\.arduinoIDE-unsaved2022124-17740-kuu5up.c9qh\static_buffer\static_buffer.ino:66:5: note: suggested alternative: 'inference_buffer'
     inference_thread.start(mbed::callback(&run_inference_background));
     ^~~~~~~~~~~~~~~~
     inference_buffer
C:\Users\Aryan\AppData\Local\Temp\.arduinoIDE-unsaved2022124-17740-kuu5up.c9qh\static_buffer\static_buffer.ino:66:28: error: 'mbed' has not been declared
     inference_thread.start(mbed::callback(&run_inference_background));
                            ^~~~
Multiple libraries were found for "Adafruit_ZeroDMA.h"
 Used: C:\Users\Aryan\AppData\Local\Arduino15\packages\Seeeduino\hardware\samd\1.8.2\libraries\Adafruit_ZeroDMA
 Not used: C:\Users\Aryan\Documents\Arduino\libraries\Adafruit_Zero_DMA_Library
Compilation error: exit status 1}

I copy pasted my code in static_buffer file in examples -> testing_inferencing. And compiled the same.

Hi there!
So, Wio Terminal does not use mbedOS, relying instead on FreeRTOS. You can have a look at working example of continuous inference with explanation for Wio Terminal here:


Cheers, hope that helped!
1 Like

I used the method which you mentioned. But it doesn’t display the predictions on the serial monitor, and I have noticed that serial monitor only prints things that are inside loop(). is there a way around it? pardon me as I am new to IoT technology.

So, I’ve noticed that links to Github repository for that project were cahnged, here is the right link (I also updated the article):


WioTerminal_EI_People_Counting_Continious.ino prints out results on Serial monitor and controls LCD screen backlit, based on the results of inference.
1 Like

I compared my code with the code given in your link. I didn’t find any fault in my code. But it is showing this error

Failed to allocate TFLite arena (error code 1)

ERR: Failed to run classifier (-6)

Fatal Error

I also ran the this code which worked fine and this is also continuos and similar to my code. can you please please look at my code. I don’t even know what’s wrong.

#include <Fall_detection_3spec_inferencing.h>

#include <Seeed_Arduino_FreeRTOS.h>

#include"LIS3DHTR.h" //include accelerometer library

LIS3DHTR<TwoWire> lis; //Initialize accelerometer

#define ERROR_LED_LIGHTUP_STATE HIGH

#define CONVERT_G_TO_MS2    9.80665f

/* Private variables ------------------------------------------------------- */

static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal

static uint32_t run_inference_every_ms = 200;

static float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = {0};

static float inference_buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];

uint8_t axis_num = 1;

TaskHandle_t Handle_aTask;

TaskHandle_t Handle_bTask;

/**

* @brief      Arduino setup function

*/

void setup()

{

    // put your setup code here, to run once:

    Serial.begin(115200);

    lis.begin(Wire1); //Start accelerometer

    Serial.println("Edge Impulse Inferencing Demo");

    lis.setOutputDataRate(LIS3DHTR_DATARATE_200HZ); //Data output rate (5Hz up to 5kHz)

    lis.setFullScaleRange(LIS3DHTR_RANGE_8G);

    if (EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME != 3) {

        ei_printf("ERR: EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME should be equal to (%d) (the (%d) sensor axes)\n", axis_num, axis_num);

        return;

    }

    vSetErrorLed(LED_BUILTIN, ERROR_LED_LIGHTUP_STATE);

    

    // Create the threads that will be managed by the rtos

    // Sets the stack size and priority of each task

    // Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks

    xTaskCreate(run_inference_background,"Inference", 512, NULL, tskIDLE_PRIORITY + 2, &Handle_aTask);

    xTaskCreate(read_data, "Data collection", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_bTask);

    // Start the RTOS, this function will never return and will schedule the tasks.

    vTaskStartScheduler();

}

/**

* @brief      Printf function uses vsnprintf and output using Arduino Serial

*

* @param[in]  format     Variable argument list

*/

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

   }

}

/**

 * @brief      Run inferencing in the background.

 */

static void run_inference_background(void* pvParameters)

{

    // wait until we have a full buffer

    delay((EI_CLASSIFIER_INTERVAL_MS * EI_CLASSIFIER_RAW_SAMPLE_COUNT) + 100);

    // This is a structure that smoothens the output result

    // With the default settings 70% of readings should be the same before classifying.

    ei_classifier_smooth_t smooth;

    ei_classifier_smooth_init(&smooth, 10 /* no. of readings */, 7 /* min. readings the same */, 0.8 /* min. confidence */, 0.3 /* max anomaly */);

    while (1) {

        // copy the buffer

        memcpy(inference_buffer, buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE * sizeof(float));

        // Turn the raw buffer in a signal which we can the classify

        signal_t signal;

        int err = numpy::signal_from_buffer(inference_buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);

        if (err != 0) {

            ei_printf("Failed to create signal from buffer (%d)\n", err);

            return;

        }

        // Run the classifier

        ei_impulse_result_t result = { 0 };

        err = run_classifier(&signal, &result, debug_nn);

        if (err != EI_IMPULSE_OK) {

            ei_printf("ERR: Failed to run classifier (%d)\n", err);

            return;

        }

        // print the predictions

        ei_printf("Predictions ");

        ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",

            result.timing.dsp, result.timing.classification, result.timing.anomaly);

        ei_printf(": ");

        // ei_classifier_smooth_update yields the predicted label

        const char *prediction = ei_classifier_smooth_update(&smooth, &result);

        ei_printf("%s ", prediction);

        // print the cumulative results

        ei_printf(" [ ");

        for (size_t ix = 0; ix < smooth.count_size; ix++) {

            ei_printf("%u", smooth.count[ix]);

            if (ix != smooth.count_size + 1) {

                ei_printf(", ");

            }

            else {

              ei_printf(" ");

            }

        }

        ei_printf("]\n");

        delay(run_inference_every_ms);

    }

    ei_classifier_smooth_free(&smooth);

}

/**

* @brief      Get data and run inferencing

*

* @param[in]  debug  Get debug info if true

*/

static void read_data(void* pvParameters)

{

    while (1) {

        // Determine the next tick (and then sleep later)

        uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);

        // roll the buffer -3 points so we can overwrite the last one

        numpy::roll(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, -axis_num);

        //buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] = analogRead(WIO_LIGHT);

        buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] = lis.getAccelerationX();

        buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] = lis.getAccelerationY();

    buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] = lis.getAccelerationZ();

        buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] *= CONVERT_G_TO_MS2;

        buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] *= CONVERT_G_TO_MS2;

        buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] *= CONVERT_G_TO_MS2;

        // and wait for next tick

        uint64_t time_to_wait = next_tick - micros();

        delay((int)floor((float)time_to_wait / 1000.0f));

        delayMicroseconds(time_to_wait % 1000);

    }

}

void loop()

{

  //nothing, all the work is done in two threads

}

This is the project link

Hi there!
It seems that

Failed to allocate TFLite arena (error code 1)

just means that there is not enough RAM for the model. Are you using EON compiled model? What is the architecture?
Another little thing, that I’d recommend would be using

lis.getAcceleration(&buffer[ix], &buffer[ix + 1], &buffer[ix + 2]);

function to get the data from accelerometer in one step. You’ll need to adapt the above line to names of your variables of course.