cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f1xx UART slow and when I added another logic it just didn't works

AFidi.1
Associate II

I made a simple program on an ESP32 to send dummy data with something like this

$DUMMYDATA,0,1

I've tried using another ESP32 as a receiver and it works perfectly. My goals is implement the same thing to my STM32F103C8T6. Here's my code for the first attempt.

while (1)
{
HAL_UART_Receive(&huart2, receivedData, sizeof(receivedData), 100);
CDC_Transmit_FS((uint8_t *)receivedData, strlen(receivedData));
}

It works but the data is corrupted

⸮0kTԽ⸮5⸮⸮c	8	⸮⸮ d⸮֩⸮&⸮⸮.⸮Z⸮�?|!Qi;⸮1⸮⸮z\⸮9⸮$DUMMYDATA,1,0

Then I changed the third line to something like this

HAL_UART_Receive(&huart2, receivedData, sizeof(receivedData), HAL_MAX_DELAY);

Now it works perfectly but with downside it just became really slow. Then I tried to add a simple logic to parse the data

  while (1)
  {
	  HAL_UART_Receive(&huart2, receivedData, sizeof(receivedData), HAL_MAX_DELAY);
 
	  strcpy(dataMode, strtok(receivedData, ','));
	  strcpy(latitude, strtok(NULL, ','));
	  strcpy(longitude, strtok(NULL, ','));
 
	  CDC_Transmit_FS((uint8_t *)dataMode, strlen(dataMode));
	  CDC_Transmit_FS((uint8_t *)latitude, strlen(latitude));
	  CDC_Transmit_FS((uint8_t *)longitude, strlen(longitude));
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

And now my STM didn't output anything at all. My questions are

  1. How can I tweak my receiver to receive data faster but still accurate enough?
  2. Why it just didn't do anything at all after I added another logic?

I've attached my project if its useful. Thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
Karl Yamashita
Lead III

I've downloaded your project and noticed several issues. You've set to receive 100 chars so you've have to wait to receive a string of "$DUMMYDATA,0,1" at least 8 times before HAL_UART_Receive() returns so that is why it seems slow before you send the data over USB.

If the string size will always be 14 characters then change the array to 14 instead of 100. Then you need to increase the latitude and longitude by 1 to allow for a null character.

Then you're trying to send all that data over CDC without checking to see if it's Transmit is still busy.

I've posted updated code to get you going.

uint8_t receivedData[14] = {0};
char dataMode[20], longitude[2], latitude[2];
 
  while (1)
  {
	  HAL_UART_Receive(&huart2, receivedData, sizeof(receivedData), HAL_MAX_DELAY);
 
	  strcpy(dataMode, strtok((char*)receivedData, ","));
	  strcpy(latitude, strtok(NULL, ","));
	  strcpy(longitude, strtok(NULL, ","));
 
	  while(CDC_Transmit_FS((uint8_t *)dataMode, strlen(dataMode))== USBD_BUSY);
	  while(CDC_Transmit_FS((uint8_t *)latitude, strlen(latitude))== USBD_BUSY);
	  while(CDC_Transmit_FS((uint8_t *)longitude, strlen(longitude))== USBD_BUSY);
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

View solution in original post

2 REPLIES 2
Karl Yamashita
Lead III

I've downloaded your project and noticed several issues. You've set to receive 100 chars so you've have to wait to receive a string of "$DUMMYDATA,0,1" at least 8 times before HAL_UART_Receive() returns so that is why it seems slow before you send the data over USB.

If the string size will always be 14 characters then change the array to 14 instead of 100. Then you need to increase the latitude and longitude by 1 to allow for a null character.

Then you're trying to send all that data over CDC without checking to see if it's Transmit is still busy.

I've posted updated code to get you going.

uint8_t receivedData[14] = {0};
char dataMode[20], longitude[2], latitude[2];
 
  while (1)
  {
	  HAL_UART_Receive(&huart2, receivedData, sizeof(receivedData), HAL_MAX_DELAY);
 
	  strcpy(dataMode, strtok((char*)receivedData, ","));
	  strcpy(latitude, strtok(NULL, ","));
	  strcpy(longitude, strtok(NULL, ","));
 
	  while(CDC_Transmit_FS((uint8_t *)dataMode, strlen(dataMode))== USBD_BUSY);
	  while(CDC_Transmit_FS((uint8_t *)latitude, strlen(latitude))== USBD_BUSY);
	  while(CDC_Transmit_FS((uint8_t *)longitude, strlen(longitude))== USBD_BUSY);
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
AFidi.1
Associate II

Thank you for your feedback. I've implemented it and it works.