cancel
Showing results for 
Search instead for 
Did you mean: 

Custom made ble characteristic updater don't work

AndrasToth
Associate III

Hello everyone!

I just started learning how to use the STM32WB-Chips on the Nucleo-WB55RG and followed this tutorial: 

https://www.youtube.com/watch?v=Zgw3wRpGSRQ&list=PLnMKNibPkDnG9JRe2fbOOpVpWY7E4WbJ-&index=17

After that I tried to make a function (following the steps mentioned in the tutorial above) which I can use in the main.c to send custom data to the PC. However when I call this function in the main loop the advertismenet  disappear and I cannot find the reason why. Can you guys help me with this?

In the app_conf.h I wrote

648  /* USER CODE BEGIN Defines */
649  void ble_updateChar(uint8_t);
650  /* USER CODE END Defines */
...

671  /* USER CODE BEGIN CFG_Task_Id_With_HCI_Cmd_t */
672  CFG_TASK_BLE_UPDATE,
673  /* USER CODE END CFG_Task_Id_With_HCI_Cmd_t */

In the app_ble.c

268  /* USER CODE BEGIN APP_BLE_Init_1 */
269  UTIL_SEQ_RegTask(1<<CFG_TASK_BLE_UPDATE, UTIL_SEQ_RFU, ble_updateChar);
270  UTIL_SEQ_SetTask(1<<CFG_TASK_BLE_UPDATE, CFG_SCH_PRIO_0);
271  /* USER CODE END APP_BLE_Init_1 */

In the custom_app.h

57  /* External variables --------------------------------------------------------*/
58  /* USER CODE BEGIN EV */
59  extern uint8_t ble_flag;
60  extern uint8_t ble_buffer[247];
70  /* USER CODE END EV */
...
71  /* USER CODE BEGIN EF */
72  void ble_updateChar(uint8_t char_identifier);
73  /* USER CODE END EF */

In the custom_app.c

75  /* USER CODE BEGIN PV */
76  uint8_t ble_flag;
77  uint8_t ble_buffer[247];
78  /* USER CODE END PV */
...
177  /* USER CODE BEGIN FD */
178  void ble_updateChar(uint8_t char_identifier){
179
180     if(char_identifier == NOTIFY_CHARACTERISTICS){
181  		if(ble_flag == 1){
182  			Custom_STM_App_Update_Char(CUSTOM_STM_NOTFIY, (uint8_t *)ble_buffer);
183  			ble_flag = 0;
184  		}
185
186     }
187     UTIL_SEQ_SetTask(1<<CFG_TASK_BLE_UPDATE, CFG_SCH_PRIO_0);
188  }
189  /* USER CODE END FD */

 

When I want to send data to the PC I set the ble_flag to 1 and place the data in the ble_buffer in the main.c and call the ble_updateChar() function. Like this:

119  while (1)
120  {
121    /* USER CODE END WHILE */
122    MX_APPE_Process();
123
124    /* USER CODE BEGIN 3 */
125    ble_flag = 1;
126    ble_buffer[0] = 0;
127    ble_updateChar(NOTIFY_CHARACTERISTICS);
127    HAL_Delay(100);
128    ble_flag = 1;
129    ble_buffer[0] = 1;
130    ble_updateChar(NOTIFY_CHARACTERISTICS);
131    HAL_Delay(100);
132
133
134  }
135  /* USER CODE END 3 */

As I said above, if the ble_updateChar() function is called it causes the service to disappear, but if I comment them out the service is there again.

 

I'm thankful for and looking forward to your answers!

 

Best regard,

AndrasToth

1 ACCEPTED SOLUTION

Accepted Solutions
FDumontKeller
Associate III

Hi @AndrasToth

I think there are some things mixed up.


remark: If you want to update the value as soon the Server has something new for the client you should use the a characteristic on notification or indication (CHAR_PROP_NOTIFY / CHAR_PROP_INDICATE). 
On the other hand if you want to give the client data when you received a read command from it, then you should use a characteristic with the read property (CHAR_PROP_READ). 

In your code  you are introducing a task for the sequencer to execute ble_updateChar() as soon as the code starts in APP_BLE_Init()

268  /* USER CODE BEGIN APP_BLE_Init_1 */
269  UTIL_SEQ_RegTask(1<<CFG_TASK_BLE_UPDATE, UTIL_SEQ_RFU, ble_updateChar);
270  UTIL_SEQ_SetTask(1<<CFG_TASK_BLE_UPDATE, CFG_SCH_PRIO_0);
271  /* USER CODE END APP_BLE_Init_1 */

and the function associated with the task introduces again a new task for the execution of the same function.

/* USER CODE BEGIN PV */
76  uint8_t ble_flag;
77  uint8_t ble_buffer[247];
78  /* USER CODE END PV */
...
177  /* USER CODE BEGIN FD */
178  void ble_updateChar(uint8_t char_identifier){
179
180     if(char_identifier == NOTIFY_CHARACTERISTICS){
181  		if(ble_flag == 1){
182  			Custom_STM_App_Update_Char(CUSTOM_STM_NOTFIY, (uint8_t *)ble_buffer);
183  			ble_flag = 0;
184  		}
185
186     }
187     UTIL_SEQ_SetTask(1<<CFG_TASK_BLE_UPDATE, CFG_SCH_PRIO_0);
188  }
189  /* USER CODE END FD */

 

This will result in the sequencer constantly entering the ble_updateChar() in MX_APPE_Proccess() once the BLE stack is ready. If no additional code is in main the application will send Advertising normally since the calling of ble_updateChar() does not do anything given that ble_flag is 0.

But if you put the extra code in main(). The application will try to send something to a non existent client since there has not been any connection established. 

If this is your first time using the Custom_service, you can follow this example of provided by ST: 
https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Connectivity:STM32WB_BLE_STM32CubeMX

And information about how the sequencer for the BLE application can be found here: 
https://www.st.com/resource/en/application_note/an5289-how-to-build-wireless-applications-with-stm32wb-mcus-stmicroelectronics.pdf

 

Hope this helps.

 

View solution in original post

8 REPLIES 8
FDumontKeller
Associate III

Hi @AndrasToth

I think there are some things mixed up.


remark: If you want to update the value as soon the Server has something new for the client you should use the a characteristic on notification or indication (CHAR_PROP_NOTIFY / CHAR_PROP_INDICATE). 
On the other hand if you want to give the client data when you received a read command from it, then you should use a characteristic with the read property (CHAR_PROP_READ). 

In your code  you are introducing a task for the sequencer to execute ble_updateChar() as soon as the code starts in APP_BLE_Init()

268  /* USER CODE BEGIN APP_BLE_Init_1 */
269  UTIL_SEQ_RegTask(1<<CFG_TASK_BLE_UPDATE, UTIL_SEQ_RFU, ble_updateChar);
270  UTIL_SEQ_SetTask(1<<CFG_TASK_BLE_UPDATE, CFG_SCH_PRIO_0);
271  /* USER CODE END APP_BLE_Init_1 */

and the function associated with the task introduces again a new task for the execution of the same function.

/* USER CODE BEGIN PV */
76  uint8_t ble_flag;
77  uint8_t ble_buffer[247];
78  /* USER CODE END PV */
...
177  /* USER CODE BEGIN FD */
178  void ble_updateChar(uint8_t char_identifier){
179
180     if(char_identifier == NOTIFY_CHARACTERISTICS){
181  		if(ble_flag == 1){
182  			Custom_STM_App_Update_Char(CUSTOM_STM_NOTFIY, (uint8_t *)ble_buffer);
183  			ble_flag = 0;
184  		}
185
186     }
187     UTIL_SEQ_SetTask(1<<CFG_TASK_BLE_UPDATE, CFG_SCH_PRIO_0);
188  }
189  /* USER CODE END FD */

 

This will result in the sequencer constantly entering the ble_updateChar() in MX_APPE_Proccess() once the BLE stack is ready. If no additional code is in main the application will send Advertising normally since the calling of ble_updateChar() does not do anything given that ble_flag is 0.

But if you put the extra code in main(). The application will try to send something to a non existent client since there has not been any connection established. 

If this is your first time using the Custom_service, you can follow this example of provided by ST: 
https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Connectivity:STM32WB_BLE_STM32CubeMX

And information about how the sequencer for the BLE application can be found here: 
https://www.st.com/resource/en/application_note/an5289-how-to-build-wireless-applications-with-stm32wb-mcus-stmicroelectronics.pdf

 

Hope this helps.

 

Thank you very much! I removed the parts which uses the sequencer and it started working.

268  /* USER CODE BEGIN APP_BLE_Init_1 */
269  
270  /* USER CODE END APP_BLE_Init_1 */
/* USER CODE BEGIN PV */
76  uint8_t ble_flag;
77  uint8_t ble_buffer[247];
78  /* USER CODE END PV */
...
177  /* USER CODE BEGIN FD */
178  void ble_updateChar(uint8_t char_identifier){
179
180     if(char_identifier == NOTIFY_CHARACTERISTICS){
181  		if(ble_flag == 1){
182  			Custom_STM_App_Update_Char(CUSTOM_STM_NOTFIY, (uint8_t *)ble_buffer);
183  			ble_flag = 0;
184  		}
185     }
186  }
187  /* USER CODE END FD */

However I run into an other problem where the program is running when I'm debugging and after I stopped debugging, but not when I depower and repower the devboard after the debug or I use the run configuration on it. Did you ever run into this kind of problem?

 

Just to understand your problem better: 
the only way you get your application to work is to press the debug option. If you reset the dev board or you use the run option, you do not see any advertising from the server? 

Yes it disappears, if I reset the devboard or use the run option.

did you eliminate the calls to ble_updateChar() in the while(1){} at main? 



No I did not, because I want to use the function to send custom data to PC. However when I do remove them I can see the advertisment again.

Well, it makes sense. The application is trying to send something via Custom_STM_App_Update_Char() to client it is not conencted to. So if you reset the module or flash it without a "stop", the CPU2 gets a reset, no BLE stack is  initialized, and there is no connection with a client. Thus it will get stuck in some kind of error when sending somehting. 



The use of the BLE functionanily in your example is quite messy. If you want to use a notification (which i guess it is the case given that you use the CUSTOM_STM_NOTIFY), i will recommend again to follow the exmaple put before: 

https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Connectivity:STM32WB_BLE_STM32CubeMX

 

there you will get an idea on how the notification get activated by the client to later receive updated values by the server. 

 

Thank you very much for your help I will read through the documentions you suggested and I will try again.