2
\$\begingroup\$

I have to send data using the usart2 in my nucleo64 stm32f446re board. The type of data I have to send is float but until now I always send uint8_t using this code;

 char msg[1]; for(int i = 0 ; i < Nbit*Sb ; i++) { sprintf(msg, "%d ", sigTX[i]); HAL_UART_Transmit(&huart2, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY); } 

Because sigTX is a pointer to float data in an array, I try to change the code using msg[4], in order to have 32 bit, and in HAL_UART_transmit I put (int32 *)msg, in order to send data with sign. This doesn't work, so can someone say to me where is the mistake? Sorry, but I'm new in embedded world.

\$\endgroup\$
6
  • \$\begingroup\$ Do you wanna send the float as text or as number? \$\endgroup\$ Commented Jan 10, 2021 at 9:28
  • \$\begingroup\$ @po.pe Number, if is possible. \$\endgroup\$ Commented Jan 10, 2021 at 9:29
  • \$\begingroup\$ What precision do you need and in what range can your numbers be? Maybe it's easier to send a scaled integer instead. \$\endgroup\$ Commented Jan 10, 2021 at 10:03
  • \$\begingroup\$ @po.pe My numbers are in a range between -1 and 1, but I need 32 bit for each. For example; -0.31, -0.81, -1, ..... \$\endgroup\$ Commented Jan 10, 2021 at 10:09
  • \$\begingroup\$ This has nothing to do with embedded programming, the question would be identical to running the program on any other device like on a PC. First of all, the sprintf converts the 32-bit float to null-terminated text string of multiple characters, and char[1] is not enough to hold more than 1 character so you are writing over other variables. If you want to send the float as 32-bit binary, send 4 bytes from the address of the float. \$\endgroup\$ Commented Jan 10, 2021 at 10:22

3 Answers 3

2
\$\begingroup\$

While the other answers focus on sending one float at a time, and you want to send the whole array of floats anyway, it can be sent with a single call.

Assuming sigTX is a pointer, and you want to send Nbit*Sb amount of floats:

HAL_UART_Transmit(&huart2, (uint8_t *)sigTX, sizeof(float)*Nbit*Sb, HAL_MAX_DELAY); 
\$\endgroup\$
10
  • \$\begingroup\$ I truly can't see the slightest difference to my suggestion. \$\endgroup\$ Commented Jan 10, 2021 at 10:52
  • \$\begingroup\$ True, there is not much difference, except that your example uses a separate float variable, so it sends one float of 4 bytes and OP must use a for loop to transmit out all the floats in the sigTX array, but my example sends out the whole sigTX array in one call. \$\endgroup\$ Commented Jan 10, 2021 at 10:59
  • \$\begingroup\$ Oh I see, OK that is a valid point. I haven't realized sigTX is an array. \$\endgroup\$ Commented Jan 10, 2021 at 11:09
  • \$\begingroup\$ @Justme Does it work even if sigTX is a pointer to an array and not an array? \$\endgroup\$ Commented Jan 10, 2021 at 12:06
  • \$\begingroup\$ @Andrea I don't really understand why you ask this. Did it not work? The transmit function needs a pointer, and in C, an array is a simply pointer to the first element in it. \$\endgroup\$ Commented Jan 10, 2021 at 12:20
0
\$\begingroup\$

The STM UART interface can only send 8 or 16 bit in one step. For that reason the HAL_UART_Transmit can also only take uint8 or uint16 chunks.

If you have to send the 32 bit of a float you can pass each byte of the float and send them as single bytes. The receiver has to interpret them as a float again.


To send the four bytes of the float individually just pass a pointer to the float with a cast to (uint8_t*) and tell the function to send four bytes:

float msg = xy; HAL_UART_Transmit(&huart2, (uint8_t *)msg, sizeof(msg), HAL_MAX_DELAY); 
\$\endgroup\$
2
  • \$\begingroup\$ How can I split 32 bit of a float into 8 ? \$\endgroup\$ Commented Jan 10, 2021 at 9:56
  • \$\begingroup\$ There is no need to split it in any way. The transmit function can be told to send 4 bytes of the float in one go. Even the whole array of floats can be sent in one call. \$\endgroup\$ Commented Jan 10, 2021 at 10:24
0
\$\begingroup\$

As Jusaca said the UART of STM32 devices cannot handle 32 bit data. You will have to split your 32bit float in four 8bit data chunks.

One way to do that would be to memcpy your float into a uint8[4], below the code:

float msg; uint8_t temp[4]; memcpy(temp, &msg, 4); HAL_UART_Transmit(&huart2, temp, 4, HAL_MAX_DELAY); 
\$\endgroup\$
3
  • \$\begingroup\$ It is not necessary to do a memcpy. Just pass the pointer to the float with a cast to (uint8_t*) and give sizeof(float) as message length. \$\endgroup\$ Commented Jan 10, 2021 at 10:39
  • 1
    \$\begingroup\$ Yes, I agree that would work and would be preferable than doing a memcpy. \$\endgroup\$ Commented Jan 10, 2021 at 10:41
  • \$\begingroup\$ No, the preferable way would be to send the whole array of floats in one call. \$\endgroup\$ Commented Jan 10, 2021 at 10:43

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.