2024-04-21 02:24 PM - edited 2024-04-21 02:25 PM
Hello everyone,
I’m currently working on a project where I’m using an STM32H7B3I-DK board to communicate with Esp8266 WIFI Module using AT commands. I’ve been able to successfully send commands and receive responses using HAL_UARTEx_RxEventCallback , but I’ve encountered an issue with the AT+CWLAP command.
When I send the AT+CWLAP command, On my Serial Port I receive this :
But in my Rx Buffer the first few characters of the response are missing. Here’s an example of what I’m seeing:
\r\nOK\r\n", '\0' <repeats 30 times>, "Ooredoo 4G_39D94B\",-67,\"c8:ea:f8:39:d9:4b\",11,-1,-1,4,4,7,0)\r\n\r\nOK\r\n", '\0' <repeats 1943 times>
As you can see, the response begins with a series of null characters (\0) and the first +CWLAP: is missing.
Here are some things I’ve already tried to resolve the issue:
Despite these steps, the issue persists. My Code is the following:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
if (huart->Instance == USART2)
{
oldPos = newPos; // Update the last position before copying new data
/* If the data in large and it is about to exceed the buffer size, we have to route it to the start of the buffer
* This is to maintain the circular buffer
* The old data in the main buffer will be overlapped
*/
if (oldPos+Size > MainBuf_SIZE) // If the current position + new data size is greater than the main buffer
{
uint16_t datatocopy = MainBuf_SIZE-oldPos; // find out how much space is left in the main buffer
memcpy ((uint8_t *)MainBuf+oldPos, AT_Response, datatocopy); // copy data in that remaining space
oldPos = 0; // point to the start of the buffer
memcpy ((uint8_t *)MainBuf, (uint8_t *)AT_Response+datatocopy, (Size-datatocopy)); // copy the remaining data
newPos = (Size-datatocopy); // update the position
}
else
{
memcpy ((uint8_t *)MainBuf+oldPos, AT_Response, Size);
newPos = Size+oldPos;
}
/* start the DMA again */
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t *) AT_Response, ATBuf_SIZE-newPos);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
}
}
I would appreciate any help or suggestions on how to resolve this issue. Thank you in advance!
2024-04-21 11:24 PM - edited 2024-04-21 11:30 PM
Hello,
I think this probably has to do with this circular buffer implementation. The missing characters at the beginning of your received response suggest that data might be getting overwritten before it's properly copied into your circular buffer.
I have had something like this in the past. This code below is doing the same thing you want to do. I had a bluetooth module interfaced over UART. This can be a possible solution for you, perhaps?
Important, in my case, I am receiving data byte by byte. I am assuming from your code that you have a data block that is being received.
/**
* @brief This is the UART RxCallback function. We probably don't
* need this function but it is here. Can be deleted later on.
*
* @note This function is called on the Rx Interrupt. Check in *_it.c
*
* huart UART handle structure
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
static uart_handle_data_t data;
HAL_StatusTypeDef ret;
static uint8_t rx_data[1];
if (huart->Instance == USART3){
ret = HAL_UART_Receive_IT(huart, rx_data, 1);
if ((ret == HAL_OK) && (rx_data[0] != '\0')){
data.buffer[data.len++] = rx_data[0];
if ((rx_data[0] == '\n') && (data.len > 3)){
osMessageQueuePut(uart_ble_queue_rx_handle, &data, 0, 0);
data.len = 0;
memset(&data.buffer, '0', sizeof(data.buffer));
}
}
}
}
EDIT: This code is using queues instead of circular buffer for transmitting data to the bluetooth task. The task then checks the queue etc etc. I can give more details/code if you need.
I hope this helps.
2024-04-22 01:56 AM
Hi @bashira, Yes I would like to get more details about your implementation, I want to know where are you calling the Receive function and the uart_handle_data_t definition.
Thanks.
2024-04-22 04:30 AM
hi @Ayoub_Bnina
This is the declaration for the uart_handle_data_t.
/*! Maximum length of the UART send buffer */
#define MAX_BUFFER_LEN 50
/**
* @brief A data struct to hold data for the UART send queue
*
*/
typedef struct{
uint16_t len; //!< length of the data to be sent
uint8_t buffer[MAX_BUFFER_LEN]; //!< actual data to be sent
}uart_handle_data_t;
From my stm32f4xx_it.c
/**
* @brief This function handles USART3 global interrupt.
*/
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
/* USER CODE END USART3_IRQn 1 */
}
This is basically an interrupt tied to the UART (which is interfaced with the BLE module). The code snippet with the queue is the actually callback function.
Hope this helps.
2024-04-22 07:35 PM
Try looking at this project. It queues each message after the data idles. I have yet to see a device with AT commands that stream several messages into one long string. So far I've seen each packet that are sent individually with some idle time, so each packet will get placed into it's own queue buffer.
https://github.com/karlyamashita/Nucleo-G431RB_Three_UART/wiki