cancel
Showing results for 
Search instead for 
Did you mean: 

how can i print the values via n-Class Classification library

AkaPaDa_18
Associate III

Hello,
I am a beginner
I downloaded the STM32-NANOEDGE-DATALOGGER firmware via the github link.
This STM32-NANOEDGE-DATALOGGER is used in NaoedgeAIStudio and is streaming data via UART (VCOM port) from STLink.
but I see that the example is only given for an AD (Anomaly Detection) project and I'd like to know how to modify it for an n-Class project?

Also, is it possible to add the USB_CDC_ACM  class to activate the VCOM port on the STWIN.box without the STLink?

If so, how do I do it?

Board used: STWIN.box

6 REPLIES 6
Julian E.
ST Employee

Hello,

To use the AD example for N-class, you first need import the compiled files of your project.

Then you have to delete the learning part and replace the AD function by the N-class function.

You can have a look at this documentation, and especially to the hello word example:  https://wiki.st.com/stm32mcu/wiki/AI:NanoEdge_AI_Library_for_n-class_classification_(nCC)

Additionally, you can take a look at this N-class classification tutorial:

https://wiki.st.com/stm32mcu/wiki/AI:How_to_create_a_multi-state_vibrations_classifier_using_NanoEdge_AI_studio

 

As for the USB_CDC_ACM, I will look for information and help you once I know more.

 

Best Regards,

Julian


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

hello,
thanks for your reply. i read the differents tutorials and i tried to write this following code line for my application. The main part is in bold.

I have not error after compiling but i'm a doubt yet. please can you check that?
Thanks in advance

Code :

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdio.h>
#include "iis3dwb_reg.h"
#include "cycle_dwt.h"
#include "NanoEdgeAI.h"

#include "knowledge.h" /*___________n_class______*/

/* USER CODE BEGIN PD */
/************************************************************ NEAI algorithm defines begin
/************************************************************ Global settings part ************************************************************/
#ifndef AXIS
#define AXIS 3 /* Axis should be defined between 1 and 3 */
#endif
#ifndef SAMPLES
#define SAMPLES 1000 /* Should be between 8 & 4096 */
#endif
#define FIFO_WATERMARK 256 /* Definition of the FIFO watermark to the half of FIFO full size */
#define FIFO_FULL_SIZE 512 /* FIFO full size */
#define FIFO_WORD 7 /* FIFO word size composed of 1 byte which is identification tag & 6 bytes of fixed data */
/************************************************************ Sensor type part ************************************************************/
/************************************************************ Sensors configuration part ************************************************************/
#ifndef ACCELEROMETER_ODR
#define ACCELEROMETER_ODR IIS3DWB_XL_ODR_26k7Hz /* Only one ODR is available with this sensor IIS3DWB_XL_ODR_26k7Hz */
#endif
#ifndef ACCELEROMETER_FS
#define ACCELEROMETER_FS IIS3DWB_2g /* Should be between IIS3DWB_2g and IIS3DWB_16g */
#endif
/************************************************************ Datalogger / NEAI mode part ************************************************************/
#ifndef NEAI_MODE
#define NEAI_MODE 1 /* 0: Datalogger mode, 1: NEAI functions mode */
#endif
#if (NEAI_MODE == 1)
#ifndef NEAI_LEARN_NB
#define NEAI_LEARN_NB 100 /* Number of buffers to be learn by the NEAI library */
#endif
#endif

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

SPI_HandleTypeDef hspi2;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
uint8_t neai_similarity = 0, neai_state = 0;
volatile uint8_t drdy = 0;
uint16_t data_left = (uint16_t) SAMPLES, neai_buffer_ptr = 0, num = 0, neai_cnt = 0;
float neai_time = 0.0;
static float neai_buffer[AXIS * SAMPLES] = {0.0};
static iis3dwb_fifo_out_raw_t fifo_data[FIFO_FULL_SIZE];
stmdev_ctx_t dev_ctx;
iis3dwb_fifo_status_t fifo_status;
iis3dwb_pin_int1_route_t int1_route;

/*________________n_class_____________________*/
/* pour n-classification*/

uint16_t id_class = 0;
static float output_class_buffer[CLASS_NUMBER];
const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name
"unknown",
"Nominal",
"Balourd",
};

/*________________n_class_____________________*/
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void SystemPower_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len);
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len);
static void iis3dwb_initialize(void);
static void iis3dwb_get_buffer_from_fifo(uint16_t nb);
static float iis3dwb_convert_accel_data_to_mg(int16_t accel_raw_data);

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{


/* USER CODE BEGIN 1 */
uint16_t newClass = 0; /*________________n_class_____________________*/


/* Initialize mems driver interface */
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.handle = &hspi2;

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* Configure the System Power */
SystemPower_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI2_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
KIN1_InitCycleCounter();
KIN1_EnableCycleCounter();
iis3dwb_initialize();
if (NEAI_MODE) {
neai_state = neai_classification_init(knowledge); /*________________n_class_____________________*/

printf("Initialize NEAI library. NEAI init return: %d.\n", neai_state);
}

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (drdy) {
/* Reset data ready variable */
drdy = 0;
/* Read watermark flag */
iis3dwb_fifo_status_get(&dev_ctx, &fifo_status);
if (fifo_status.fifo_th) {
num = fifo_status.fifo_level;
if (data_left > num) {
data_left -= num;
}
else {
num = data_left;
data_left = 0;
}
iis3dwb_get_buffer_from_fifo(num);
if (data_left == 0) {
/* Stop FIFO mode, set it in BYPASS mode */
iis3dwb_fifo_mode_set(&dev_ctx, IIS3DWB_BYPASS_MODE);

#if NEAI_MODE
uint32_t cycles_cnt = 0;

/*________________n_class_____________________*/

/* ############################## Partie Mode n-class #######################################################*/
/*ici*/
KIN1_ResetCycleCounter();
neai_state = neai_classification(neai_buffer, output_class_buffer, &newClass);
cycles_cnt = KIN1_GetCycleCounter();
neai_time = (cycles_cnt * 1000000.0) / HAL_RCC_GetSysClockFreq();
if (id2class[0]){
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
}
else {
if (id2class[1]){
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
}
else {
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
}
}

printf("\nClass found: %s. NEAI learn return: %d.\n", id2class[ newClass ], neai_state);
#else
for (uint16_t i = 0; i < AXIS * SAMPLES; i++) {
printf("%.3f ", neai_buffer[i]);
}
printf("\n");
/*ici*/
/*________________n_class_____________________*/

Hello, 

You use the functions as they should, so it seems good for me.

 

Concerning the USB CDC:

First, you need to configure USB_OTG_FS in Device_Only, see below:

Screenshot from 2023-11-13 14-39-15.png

Screenshot from 2023-11-13 14-39-05.png

Then look at the code attached to add it in your project.

 

Best regards,

Julian


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Hello @Julian E. , thank you again for your reply
So I opened the .ioc of my project to complete with USB_OTG_FS as shown on the image. But I can't check the following boxes. Is it normal?

AkaPaDa_18_1-1699949047824.png

Then i generated le C code i realized that there is no file name "usb_device.h" like identified in the file attached in your message.

So are you open the same project from this link on image below ? or a new project?

AkaPaDa_18_0-1699948988727.png

Thanks for your help!

Best Regards

Hello, 

First, yes, it is normal that you cannot check the following boxes. You can click on PA11 and PA12 and change the Maximum output speed to very high:

JulianE_0-1699951887696.png

 

Then for the usb_device.h, please go to https://github.com/STMicroelectronics/stm32_mw_usb_device and get:

  • Core
  • Class/CDC

Then add them to your drivers.

 

Best regards,

Julian


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Hello @Julian E. ,

Thanks for your help, but it's very difficult for me!!! so I've abandoned the project to add the USB_CDC_ACM class to activate the VCOM port on the STWIN.box.

Now I'm trying to figure out how the 1_class library works. In the Emulator tab of the NanoedgeAI Studio software, I can see that the sensor indicates that the input pattern is detected as an outlier (outside the class considered), as shown in the following image:

AkaPaDa_18_1-1700728067648.png

But when embedded on microcontrollers, according to my code the orange LED should be flashing, but it's the green LED. I can't figure it out. Is my code correct? How can I retrieve the function output, which should be 0 for belongs to the class or 1 for outside of the class?

Thanks for your help.

A part of my code :

/*________________1_class_____________________*/

neai_state = neai_oneclass_init(knowledge);

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

if (drdy) {

/* Reset data ready variable */

drdy = 0;

/* Read watermark flag */

iis3dwb_fifo_status_get(&dev_ctx, &fifo_status);

if (fifo_status.fifo_th) {

num = fifo_status.fifo_level;

if (data_left > num) {

data_left -= num;

}

else {

num = data_left;

data_left = 0;

}

iis3dwb_get_buffer_from_fifo(num);

if (data_left == 0) {

/* Stop FIFO mode, set it in BYPASS mode */

iis3dwb_fifo_mode_set(&dev_ctx, IIS3DWB_BYPASS_MODE);

 

#if NEAI_MODE

uint32_t cycles_cnt = 0;

 

/* ############################## Partie Mode 1-class #######################################################*/

/*ici*/

KIN1_ResetCycleCounter();

neai_similarity = neai_oneclass(neai_buffer, &oneclass_result);

cycles_cnt = KIN1_GetCycleCounter();

if (neai_similarity == 0)

{

/*HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);*/

printf("Regular");

HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);

HAL_Delay(1000);

 

/*HAL_GPIO_WriteMultipleStatePin(LED1_GPIO_Port, LED1_Pin, LED2_Pin);*/

}

if(neai_similarity == 1){

/*

HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);

HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); */

printf("Abnormal");

HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);

HAL_Delay(1000);

 

}

neai_time = (cycles_cnt * 1000000.0) / HAL_RCC_GetSysClockFreq();

 

printf("\n");

printf("NEAI learn return: %d.\n", neai_similarity);