cancel
Showing results for 
Search instead for 
Did you mean: 

UART receive garbage data, though it looks ok on oscilloscope

Ashraf_minime
Associate

I am using stm32f411 MCU to receive data over UART.

The MCU acts as a bridge between two devices. PC & Meter device. both uses UART, but the physical connection is different. 

the connection between the MCU & meter is current mode communication.

Speed is 9600 bps.

I tested it with 2400 & 4800 & both were fine.

When I tested it with 9600, the signal on the receive pin of the stm32 is ok. There are some garbage character in between two messages, but it works fine on 2400 & 4800 baud-rate.

 

The code is very simple, receive data from meter & forward it to pc & vice versa. It does that when a complete message is received.
I added a delay to start receiving only after the sending and there is a small character appears when the MCU & the meter switch the ownership of the current mode bus. The meter reply come after 5ms of switching occurs.

 

I attached snapshot of what is received on the RX pin
The debug data
& snippet from the code for the UART.

void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_EVEN;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */
}


///// on the bottom
else if (uartHandle->Instance == USART2)
  {
    /* USER CODE BEGIN USART2_MspInit 0 */

    /* USER CODE END USART2_MspInit 0 */
    /* USART2 clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    GPIO_InitStruct.Pin = USART2_TX_Pin | USART2_RX_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 10, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
    /* USER CODE BEGIN USART2_MspInit 1 */

    /* USER CODE END USART2_MspInit 1 */
  }
HAL_UARTEx_ReceiveToIdle(&huart6, &received_from_pc, sizeof(received_from_pc), &received_from_pc_len, 10000);
    if (received_from_pc_len > 0)
    {
      /*--------------------------------------------------------------------------------*/
      // HAL_Delay(500);
      HAL_GPIO_WritePin(TX_ENABLE_GPIO_Port, TX_ENABLE_Pin, GPIO_PIN_RESET);
      HAL_Delay(25);
      HAL_UART_Transmit(&huart2, received_from_pc, received_from_pc_len, 3000); // for now.
      HAL_Delay(10);
      HAL_GPIO_WritePin(TX_ENABLE_GPIO_Port, TX_ENABLE_Pin, GPIO_PIN_SET);

      /*--------------------------------------------------------------------------------*/
      // discard garbage invalid characters until we receive a valid start of frame character (0x15, 0x06 or 0x02) due to communication problems
      uint16_t total_rec = 0;
      do
      {
        HAL_UARTEx_ReceiveToIdle(&huart2, &received_from_meter, sizeof(received_from_meter), &received_from_meter_len, 20);
        total_rec += received_from_meter_len;
      } while (received_from_meter_len > 0 && (received_from_meter[0] != 0x15 && received_from_meter[0] != 0x06 && received_from_meter[0] != 0x02 && received_from_meter[0] != '/'));

      if (total_rec > 0)
      {
        HAL_UART_Transmit(&huart6, &received_from_meter, total_rec - 1, 3000);
      }
    }
  }

SDS00013.jpg

 

Receive Data buffer

0xf
0x73
0x7e
0x5b
0x7b
0x6e
0xc
0xc
7 REPLIES 7
mbarg.1
Lead

Very probable: you are experiencing a cache incoherence.

In which section are your data? are you using any dma ? which sections are cached?

Best: always use dma + cache management and wait interrupt to be sure you got alla your data in your desired memory section - according to chip internal topology, there are memory areas preferred for dma operations.

The F411 has no cache.

 

Ozone
Principal III

... and there is a small character appears when the MCU & the meter switch the ownership of the current mode bus. 

I don't understand what you mean here.
There is no "bus ownership" for RS232, it only works as point-to-point connection between two nodes.
Or do you use RS422 / RS485 ?

And for RS232, you could only use hardware flow control to avoid collisions, or ensure within your software that both sides do not try to send simultaneously.

Gyessine
ST Employee

Hello @Ashraf_minime 

Since garbage characters appear between two messages, this issue is likely related to timing or, less likely synchronization issues. These are common causes of this symptom.

When reception starts after the bus switch, the line is not fully released, or the receiver is enabled before the bus is stable.

This issue is more visible at 9600 baud rates, because the UART has less tolerance to timing uncertainty than at lower baud rates, such as 2400 or 4800.

I recommend avoiding relying only on fixed delays. Use UART status flags and wait until the USART is in the correct state before switching the bus direction. This method is more robust than using arbitrary delays.

Also, can you Check whether any UART error flags are set during the switch. In particular, monitor the following:(Framing error, noise error, Overrun error, Parity error)

These flags help confirm whether garbage bytes are caused by a communication transition issue.
BR
Gyessine

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Andrew Neil
Super User

Welcome to the forum.

Please see How to write your question to maximize your chances to find a solution for best results.

In particular, please give more detail about this:

 


@Ashraf_minime wrote:

The MCU acts as a bridge between two devices. PC & Meter device. both uses UART, but the physical connection is different. 

the connection between the MCU & meter is current mode communication.


Please show a schematic.

As @Ozone said, it's not clear how this is supposed to work.

Do you have it working with any other devices?

 


@Ashraf_minime wrote:

I tested it with 2400 & 4800 & both were fine.

When I tested it with 9600, the signal on the receive pin of the stm32 is ok. There are some garbage character in between two messages, but it works fine on 2400 & 4800 baud-rate.


Are you sure the 9600 baud rate is correct? (Although a wrong baud rate would tend to make all comms garbage)

As @Gyessine said, if it fails at higher speed that's likely a timing issue; eg, at the low speed your code can only just keep up - and at 9600 it no longer can.

Arbitrary delays - or "blind delays" - are, indeed, a root of many bugs.

 

PS:

Also not sure what is going on in the posted code with you re-writing your own HAL_UARTEx_ReceiveToIdle() function?

That's a function which is (or should be) provided by the ST STM32CubeF4 Firmware Pack.:

AndrewNeil_0-1779097865254.png

 

And why are you calling it recursively?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

@Ozone wrote:

There is no "bus ownership" for RS232, it only works as point-to-point connection between two nodes..


It sounds like the OP is not using RS232 - "current controlled bus" sounds like the kind of thing used in vending machines for sharing a UART connection...

 

Again, @Ashraf_minime you need to give more details about this.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

> It sounds like the OP is not using RS232 - "current controlled bus" sounds like the kind of thing used in vending machines for sharing a UART connection...

There seems quite a bit of important information about the issue missing.
And since many posters equate "UART" with RS232, I started with this assumption ...