2023-11-06 11:50 PM
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
2023-11-09 08:14 AM
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:
As for the USB_CDC_ACM, I will look for information and help you once I know more.
Best Regards,
Julian
2023-11-12 11:23 PM
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_____________________*/
2023-11-13 06:09 AM
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:
Then look at the code attached to add it in your project.
Best regards,
Julian
2023-11-14 12:05 AM
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?
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?
Thanks for your help!
Best Regards
2023-11-14 12:54 AM
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:
Then for the usb_device.h, please go to https://github.com/STMicroelectronics/stm32_mw_usb_device and get:
Then add them to your drivers.
Best regards,
Julian
2023-11-23 12:29 AM
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:
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);