STM32L476 (Disco)

@Rink I’ll take a look tomorrow on my L476!

Ok Sir ,
If you need my CubeIDE file then I will give you my project files…but this demo is very important for me .
After some changes , Right now my code give me same ans as studio , but this works only on static buffer , if i give real time sensor data on this buffer then its can’t provide right ans .

@Rink, I thought I had a L476 laying around, but I didn’t :slight_smile: Anyway, this is a demo on the DISCO-L475VG in STM32CubeIDE:

Includes

/* Includes ------------------------------------------------------------------*/
#include <edge-impulse-sdk/classifier/ei_run_classifier.h>
#include "main.h"
#include "stm32l475e_iot01_accelero.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

using namespace ei;

/* USER CODE END Includes */

Code

  /* USER CODE BEGIN 2 */
  ACCELERO_StatusTypeDef s = BSP_ACCELERO_Init();
  ei_printf("Accelerometer init result %d\n", s);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1) {
	  float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };

	  for (size_t ix = 0; ix < EI_CLASSIFIER_RAW_SAMPLE_COUNT; ix++) {
		  uint64_t next_tick = ei_read_timer_us() + (EI_CLASSIFIER_INTERVAL_MS * 1000);

		  int16_t accel_data[3] = { 0 };
		  BSP_ACCELERO_AccGetXYZ(accel_data);

		  features[(ix * EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME) + 0] = static_cast<float>(accel_data[0]) / 100.0f;
		  features[(ix * EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME) + 1] = static_cast<float>(accel_data[1]) / 100.0f;
		  features[(ix * EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME) + 2] = static_cast<float>(accel_data[2]) / 100.0f;

		  // busy-loop until next tick
		  while (ei_read_timer_us() < next_tick);
	  }

	  ei_impulse_result_t result;
	  signal_t signal;
	  numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);

      EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
      ei_printf("run_classifier returned: %d\n", res);

      ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
          result.timing.dsp, result.timing.classification, result.timing.anomaly);

      // print the predictions
      ei_printf("[");
      for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
          ei_printf("%.5f", result.classification[ix].value);
  #if EI_CLASSIFIER_HAS_ANOMALY == 1
          ei_printf(", ");
  #else
          if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) {
              ei_printf(", ");
          }
  #endif
      }
  #if EI_CLASSIFIER_HAS_ANOMALY == 1
      ei_printf("%.3f", result.anomaly);
  #endif
      ei_printf("]\n\n\n");
  }
  /* USER CODE END 3 */

Ok sir ,
thanks for your help
I will try this demo on my setup .

Hey sir ,
I was trying to run you code on my system but still its gets same result which is not correct. Screenshot_2020-10-05_10-25-58

Screenshot_2020-10-05_10-30-11
Hey , Sir
I was thinking , Can I use a standard C++ file on My setup(stm32L4 + lis2dw12)?
Because this is just for testing purposes, Our company final goal is that edge impulse use in a Nordic microcontroller. So How can I use Standard C++ library . Please give me some details or sample code something , I also try your Mbed OS code which is given in GitHub , but still there is so many linking error I got .

@Rink you can but if the model does not work properly on the STM32Cube.AI export it won’t work in the normal C++ export either. Given that your results are always the same I’m still suspecting the buffer to not be filled correctly.

So How can I use Standard C++ library

For STM32Cube.IDE see Need help with porting (STM32 Nucleo)

I also try your Mbed OS code which is given in GitHub , but still there is so many linking error I got .

https://github.com/edgeimpulse/example-standalone-inferencing-mbed? This works out-of-the-box for me on the https://os.mbed.com/platforms/ST-Discovery-L476VG/, compiling with GCC ARM 9 - what linker errors do you see?

janjongboom:~/repos/example-standalone-inferencing-mbed (master) $ mbed compile -t GCC_ARM -m disco_l476vg
[mbed] Working path "/Users/janjongboom/repos/example-standalone-inferencing-mbed" (program)
[Warning] @,: Compiler version mismatch: Have 9.3.1; expected version >= 6.0.0 and < 7.0.0
Building project example-standalone-inferencing-mbed (DISCO_L476VG, GCC_ARM)
Scan: example-standalone-inferencing-mbed
Link: example-standalone-inferencing-mbed
Elf2Bin: example-standalone-inferencing-mbed
| Module                                |      .text |    .data |      .bss |
|---------------------------------------|------------|----------|-----------|
| [fill]                                |    146(+0) |   14(+0) |    27(+0) |
| [lib]/c.a                             |  33532(+0) | 2472(+0) |    89(+0) |
| [lib]/gcc.a                           |   7196(+0) |    0(+0) |     0(+0) |
| [lib]/m.a                             |   9976(+0) |    1(+0) |     0(+0) |
| [lib]/misc                            |    188(+0) |    4(+0) |    28(+0) |
| [lib]/nosys.a                         |     32(+0) |    0(+0) |     0(+0) |
| [lib]/stdc++.a                        |   5208(+0) |    8(+0) |    44(+0) |
| edge-impulse-sdk/CMSIS                |  15784(+0) |    0(+0) |     0(+0) |
| edge-impulse-sdk/dsp                  |   3226(+0) |    0(+0) |     0(+0) |
| edge-impulse-sdk/porting              |     74(+0) |    0(+0) |     0(+0) |
| edge-impulse-sdk/tensorflow           |  15444(+0) |  192(+0) |     0(+0) |
| mbed-os/components                    |     36(+0) |    0(+0) |     4(+0) |
| mbed-os/drivers                       |    174(+0) |    0(+0) |     0(+0) |
| mbed-os/hal                           |   1726(+0) |    8(+0) |   130(+0) |
| mbed-os/platform                      |   4482(+0) |  260(+0) |   408(+0) |
| mbed-os/rtos                          |   6854(+0) |  168(+0) | 10324(+0) |
| mbed-os/targets                       |  11050(+0) |    8(+0) |   966(+0) |
| source/main.o                         |   9100(+0) |   65(+0) |     4(+0) |
| tflite-model/trained_model_compiled.o |   1288(+0) |  744(+0) |  2832(+0) |
| Subtotals                             | 125516(+0) | 3944(+0) | 14856(+0) |
Total Static RAM memory (data + bss): 18800(+0) bytes
Total Flash memory (text + data): 129460(+0) bytes

Image: ./BUILD/DISCO_L476VG/GCC_ARM/example-standalone-inferencing-mbed.bin

sir , I Checked my buffer fill with proper data or not , even I also print it.
See this in picture , I printed my buffer data and result … my data continues changes but result cant , and this time I used c++ library instead of Cube-AI.

Hi Rink,

The buffer should contain 600 values. If only 3 are filled that would explain the same results as mentioned by Jan.

Aurelien

1 Like

sir , actually the buffer have 600 values , but just print first three value for showing variation .

void lis2dw12_read_data_single(void)
{
stmdev_ctx_t dev_ctx;
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;

platform_delay(BOOT_TIME);
lis2dw12_device_id_get(&dev_ctx, &whoamI);
if (whoamI != LIS2DW12_ID)
{
printf(“Device not respond\r\n”);
}

lis2dw12_reset_set(&dev_ctx, PROPERTY_ENABLE);
do
{
lis2dw12_reset_get(&dev_ctx, &rst);
} while (rst);

lis2dw12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);

lis2dw12_int_notification_set(&dev_ctx, LIS2DW12_INT_LATCHED);
lis2dw12_pin_polarity_set(&dev_ctx, LIS2DW12_ACTIVE_LOW);

lis2dw12_pin_int1_route_get(&dev_ctx, &ctrl4_int1_pad);
ctrl4_int1_pad.int1_drdy = PROPERTY_ENABLE;
lis2dw12_pin_int1_route_set(&dev_ctx, &ctrl4_int1_pad);

lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);

lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);
lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_10);

lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_12bit);
lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_SET_SW_TRIG);

memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
lis2dw12_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
acceleration_mg[0] = lis2dw12_from_fs2_lp1_to_mg(data_raw_acceleration[0]);
acceleration_mg[1] = lis2dw12_from_fs2_lp1_to_mg(data_raw_acceleration[1]);
acceleration_mg[2] = lis2dw12_from_fs2_lp1_to_mg(data_raw_acceleration[2]);

lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_SET_SW_TRIG);
for(int i =0 ; i< 600 ; )
{
features[i++] = acceleration_mg[0];
features[i++] = acceleration_mg[1];
features[i++] = acceleration_mg[2];
HAL_Delay(10);
}
/* sprintf((char *)p_buf,"%f %f %f \r\n",features[0],features[1],features[2]);
HAL_UART_Transmit(&huart2, (uint8_t )p_buf, sizeof(p_buf),1000);/
}

this is my sensor code , you can see I
fill my features buffer with 600 data values

Hi @Rink,

You’re not reading from the accelerometer in the loop. You should call lis2dw12_acceleration_raw_get every time to get the new values. Now you’re writing the same value over and over.

see it is inside my int main() function , I put my in while(1) so every time they get updated value even i also checked it

@Rink, it is not:

memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
lis2dw12_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
acceleration_mg[0] = lis2dw12_from_fs2_lp1_to_mg(data_raw_acceleration[0]);
acceleration_mg[1] = lis2dw12_from_fs2_lp1_to_mg(data_raw_acceleration[1]);
acceleration_mg[2] = lis2dw12_from_fs2_lp1_to_mg(data_raw_acceleration[2]);

lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_SET_SW_TRIG);
for(int i =0 ; i< 600 ; )
{
// SHOULD READ FROM ACCELEROMETER HERE

features[i++] = acceleration_mg[0];
features[i++] = acceleration_mg[1];
features[i++] = acceleration_mg[2];
HAL_Delay(10);
}

Here you read the accelerometer once and then keep writing those same values. You should update the acceleration_mg array every time you hit this loop.

1 Like

hey @janjongboom thanks a lot for helpping me …finally it works … I realize my mistakes
You are right …every time fill same x,y,z data in buffer , I had small change in my code and then it works :slight_smile: :smiley:

2 Likes

@Rink, great! Glad to be able to help!

1 Like

Hello sir ,
How can i link all the library(stranded cpp) components (folders) with CMakeList.txt file , can you give me some direction something , I am Working on nrf52840 with Zephyr , and programming with linux terminal.

Hey @Rink, add a CMake rule that finds all .h, .cc, .c, and .cpp files, and then exclude the edge-impulse-sdk/porting, utensor and ei_run_classifier_c.* files. See:

For an example.

Hello Sir,
as you say ,
CMake rule that finds all .h , .cc , .c , and .cpp files, and then exclude the edge-impulse-sdk/porting , utensor and ei_run_classifier_c.* files.
I done it , after this I build my code but there are so many errors .
And porting folder file error also ,
so give me some solution , I am working on nrf52840 Dk board , and conding in zephyr os

I was not change any files or folder in your standard sdk just deleting porting , utensor and ei_run_classifier_c.* nothing else .

@Rink here’s an end-to-end example with a Zephyr project: https://docs.edgeimpulse.com/docs/running-your-impulse-locally-zephyr

1 Like

thanks a lot sir its works well …

1 Like