cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 Buffer printing HAL_UART_Transmit

davidec
Associate III

Good morning everyone, after collecting some data and storing it in various buffers, I am trying to write them to the serial port for further processing. I am experiencing issues as I can see that something is being written to the serial port, but not all the samples in the buffer are being printed. Any suggestions?

 

  while (1)

  {

  HAL_UART_Receive (&huart2, UART1_rxBuffer, 1, 5000); //receive and store string

 

  if(UART1_rxBuffer[0] == 115){

  HAL_UART_Transmit(&huart2, UART1_rxBuffer, 1, 100); //print received string

  if(flag == 1){ //check add finished

  for(c=0;c<ADC_BUF_SIZE/2;c++){

  sprintf(str, "%hu",(uint16_t*)buf1[c]); // conversion in str of value

  HAL_UART_Transmit(&huart2, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);

 

  HAL_Delay(10);

  }

  HAL_UART_Transmit(&huart2,(uint8_t *)space,strlen(space),10); // string = “— — — — ;”

  UART1_rxBuffer[0]=0; // start flag clear

  flag = 0; // conversion adc clear

  }

  }

 

  }

16 REPLIES 16
TDK
Guru

Check to ensure you can shift out data at least as fast as it's coming in. If you ADC capture rate is above what you can send out, you will lose data.

If you're unsure how to do that, give more information on your capture rate.

> ADC_BUF_SIZE/2

Curious that you're only going up to half of the buffer. Could be correct, might not be. It's impossible to say without seeing more code.

> (uint16_t*)buf1[c]

Careful of order of operations here. You probably want ((uint16_t*)buf1)[c].

If you feel a post has answered your question, please click "Accept as Solution".
davidec
Associate III

I have modified the ADC clock to 72 MHz. Once the data is sampled (as indicated by the flag), it enters the while loop and should print the values stored in the buffer. The reason ADC_BUF_SIZE/2 is used is that I am storing the data in a 32-bit buffer and then splitting the values into two variables.

I am debugging and the values are written correctly but the problem is that I do not see them on the serial and if I do see them it is sporadic

Karl Yamashita
Lead III

Use code formatting so it is easier to read the code 

Screenshot 2023-10-23 091035.png

 

while (1)
{
	HAL_UART_Receive(&huart2, UART1_rxBuffer, 1, 5000); //receive and store string
	if (UART1_rxBuffer[0] == 115) {
		HAL_UART_Transmit(&huart2, UART1_rxBuffer, 1, 100); //print received string
		if (flag == 1) { //check add finished
			for (c = 0; c < ADC_BUF_SIZE / 2; c++) {
				sprintf(str, "%hu", (uint16_t*) buf1[c]); // conversion in str of value
				HAL_UART_Transmit(&huart2, (uint8_t*) str, strlen(str),
						HAL_MAX_DELAY);
				HAL_Delay(10);
			}
			HAL_UART_Transmit(&huart2, (uint8_t*) space, strlen(space), 10); // string = “— — — — ;”
			UART1_rxBuffer[0] = 0; // start flag clear
			flag = 0; // conversion adc clear

		}
	}
}

 

What do you see in your buf1 and what is being printed?

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.
davidec
Associate III

in buf1 I see the values I would like and I also see the counter running in debug, the problem is that in order to analyse the data I have to print them out on the serial, but the values are printed out sometimes or not at all.

Would seem like it should mostly work. Might need to clear the UART of overrun, or other errors, and it's not going to receiver and transmit concurrently with blocking functions.

I'd probably write to a buffer, and service with an interrupt until empty. Not a fan of the HAL implementation.

Would likely separate the numbers output so each is distinguishable. Also side effect of sprintf() is to report the string length.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

This doesn't indicate your sampling rate.

But the issue is likely that your UART interface has a lower bandwidth than your ADC capture rate.

Perhaps show all of your code.

If you feel a post has answered your question, please click "Accept as Solution".
davidec
Associate III

the strange thing is that the buffers are full and do not update (what I want) but I cannot write to the serial. I don't think the problem is the adc because I use it and then it continues on its own without updating the variables I want. Maybe I'm doing something wrong on the serial. Anyway I'm sampling at 2.4 Msps in simultaneous dual mode.
Another thing I submit is that the firmware loads it with usb while to see the serial port I have to use a TTL converter. This is strange to me because coming from teensy and arduino i never had these problems.

You've mentioned you have a 32 bit buffer which I assume is buf1? So does that mean there are 2 ADC (16bit) values saved in each index? If so, and I assume you want to print each 16bit value one at time with a 10ms delay, you'll need to send the lower 16bits, then the upper 16 bits by bit shifting .

for(c=0;c<ADC_BUF_SIZE;c++)
{

    sprintf(str, "%hu",(uint16_t*)buf1[c]); // conversion in str of value

    HAL_UART_Transmit(&huart2, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);

    HAL_Delay(10);

    sprintf(str, "%hu",(uint16_t*)(buf1[c] >> 16)); 

    HAL_UART_Transmit(&huart2, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);

    HAL_Delay(10);

}

 

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.