1
votes

I want to receive data over UART from my ESP2866 using a RX Interrupt so I don't need to poll for data.

The code works fine, I can see the response in the rx_buffer while debugging, but how can I check when my ESP is done sending?

The last characters the ESP sends is \r\n but it also does this a few times during the transmission, so I can't really rely on that.

I know I should somehow check the buffer for a '\0' terminator but the handler stops when the last character is received. So checking for '\0' in the handler doesn't work.

It is probably something simple I'm missing but I hope someone can help me out.

int main(void)
{
  /* USER CODE BEGIN 1 */
    char* msg = "AT+GMR\r\n";
  /* 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();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_USART1_UART_Init();

  /* Initialize interrupts */
  MX_NVIC_Init();
  /* USER CODE BEGIN 2 */

    // Send AT+GMR to ESP module
    HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg) + 1, HAL_MAX_DELAY); 

    // Receive character (1 byte)
    HAL_UART_Receive_IT(&huart1, &rx_data, 1);
  /* USER CODE END 2 */

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


  while (1)
  {

  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY); 

  return ch;
}

GETCHAR_PROTOTYPE
{
  /* Place your implementation of fgetc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    char ch;
    HAL_UART_Receive(&huart2,(uint8_t*)&ch,1, HAL_MAX_DELAY);
  return ch;
}

/**
  * @brief  Rx Transfer completed callback
  * @param  UartHandle: UART handle
  * @note   This example shows a simple way to report end of DMA Rx transfer, and 
  *         you can add your own implementation.
  * @retval None
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{  
    if(huart->Instance == USART1){

        if(rx_index == 0){
            memset(&rx_buffer, 0, sizeof(rx_buffer));
        }

        rx_buffer[rx_index] = rx_data;      

        if(rx_buffer[rx_index] == '\0'){
            printf("%s", rx_buffer);
        }

        rx_index++;

        // Receive next character (1 byte)
        HAL_UART_Receive_IT(&huart1, &rx_data, 1);

    }
}       
1
If you are transmitting text you can terminate with say EOT (value 4). "I know I should somehow check the buffer for a '\0' terminator but the handler stops when the last character is received." You have to transmit the '\0'.Weather Vane
@WeatherVane changing rx_buffer[rx_index] == 4 doesn't work either. Also i can't tell the ESP to send that '\0'?stickfigure4
I don't see why you can't transmit a final 0 or 4. An alternative would be to handle the input whenever a newline is received. It is not easy to see what you are doing because the code posted is incomplete. But if HAL_UART_RxCpltCallback is called from an interrupt handler it is a very bad idea to use printf within it. Typically the interrupt handler should buffer the incoming data, and set a flag for the upper level when there is a complete message ready. If you use a ring buffer the interrupt can continue to receive while the previous buffered input is processed.Weather Vane
@WeatherVane FYI: The ESP expects AT commands and outputs fixed format responses for them, so 4 or 0 cannot be added. Unfortunately there is no command to change the command line termination character. :)Bence Kaulics
@BenceKaulics thank you, so back to my suggestion to respond to the newline, and perhaps reorganise the code.Weather Vane

1 Answers

0
votes

When you consider the size of the char* msg = "AT+GMR\r\n"; it self considered \0 as a character.

So you don't need to add +1 in the Transmit function.