0

I want my PC to receive float value from the microcontroller so as to plot graph based on the value. I already can let microcontroller to receive value from PC. I am using union decode the float into bytes.

My union in both microcontroller and PC socket(I connect my PC to microcontroller through bluetooth, HC-06 and use HC-06 to connect to my stm32f103 through uart)

union
{
    float data;
    struct
    {
        uint8_t bytes[4];
    };
}Float[250];

How I transmit bytes from STM32F103 to PC: I first put my value in an array and then put the elements inside the union bytes before sending. (The value is keep updating, I tried to send the whole array before but seems failed).

for(int i = 0; i < 250; i++)
        {
            Float[i].F = data[i];
        }

        for(int i = 0; i < 250; i++)
        {
            for(int j = 0; j < 4; j++)
            {
                HAL_UART_Transmit(&huart1, (uint8_t* )&Float[i].bytes[j], 1, HAL_MAX_DELAY);

                while(USART1->SR != USART_SR_TC){};
            }
        }
        HAL_UART_Transmit(&huart2, (uint8_t*)"Transmitted to PC\n", 18, HAL_MAX_DELAY);

        value = 0;
        memset(data, 0, 250);
        counter = 0;

In my PC, i receive the data through rfcomm

status = recv(s, buffer, 1000, 0);

Then decode the bytes into floats:

for(int i = 0; i < 250; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            Float[i].bytes[j] = buffer[j + rcv_counter];
        }
        rcv_counter += 4;
        
    }

However, when i received the bytes send from microcontroller and decode them, i got all zero... I am not sure what is the reason. I also glad people provide some other way to do this. . My main goal is just to transmit float values from microconttroller to PC through uart. Thx very much.

Just to update my progress:

Now I can receive true float value from stm32f103 only once, if I continue requesting stm32f103 to send value, it will send only zero, I not so sure why is this happening.

float test[5] = {1.0, 5.6, 4.5, 2.3, 8.9}; // float value to be send
HAL_UART_Transmit(&huart1, (uint8_t* )test, sizeof(test), HAL_MAX_DELAY); // Transmit from stm32f103 to PC

union
{
    float data;
    struct
    {
        uint8_t bytes[4];
    };
}Float[5]; // Union to decode bytes

if(recv(s, buffer, 20, 0) >= 0)
            {
                cout << "Message received from bluepill" << endl;
          

                for(int i = 0; i < 5; i++)
                {
                    for(int j = 0; j < 4; j++)
                    {
                        Float[i].bytes[j] = buffer[j + rcv_counter];
                    }
                    rcv_counter += 4;
                    
                }
                for(int i = 0; i < 5; i++)
                {
                    cout << Float[i].data << endl;
                }
            } // Way to receive 5 float value and print to console

When i try this, i can only success one time, start from second time, i keep receiving 0, thx for helping

wps
  • 39
  • 5
  • Can you successfully send a string and receive it on the PC? – Codo Mar 12 '22 at 10:10
  • Most of the code on the microcontroller is not needed. You can simply call `HAL_UART_Transmit(&huart1, data, sizeof(data), HAL_MAX_DELAY);` (assuming `data` is an array of `float`). – Codo Mar 12 '22 at 10:12
  • seems i can only receive the valid value once... when i receive the value second time, i got rubbish value – wps Mar 12 '22 at 15:59
  • Sending multi-byte binary values without any message framing is doomed to eventually lose proper alignment. E.G. see https://stackoverflow.com/questions/16177947/identification-of-packets-in-a-byte-stream/16180135#16180135 – sawdust Mar 13 '22 at 02:42

1 Answers1

0

Create a TX-Buffer:

#define TXBUFSIZE nn
#define FARRAYSIZE mm
uint8_t TXBuffer[TXBUFSIZE] = {0};
float myArray[FARRAYSIZE] = {0,};

where nn is the number of bytes you need to send. If you want to send 250 float values in one package this would be 250 * sizeof(float)

fill the buffer in a while loop:

uint16_t size = FARRAYSIZE * sizeof(float);
uint16_t i = size;  
uint8_t *pSrc = (uint8_t*)myArray;
uint8_t *pDst = TXBuffer;

while(i--) *pDst++ = *pSrc++;

HAL_UART_Transmit(&huart2, TXBuffer, size, HAL_MAX_DELAY);

or you could simply typecast the float array into a byte array and send it out:

uint16_t size = FARRAYSIZE * sizeof(float);
uint8_t* pSrc = (uint8_t*)myArray;
HAL_UART_Transmit(&huart2, TXBuffer, size, HAL_MAX_DELAY);

Then you could omit the creation of a separate TxBuffer and save memory usage. Alas my recommendation would be to use HAL_UART_Transmit_DMA(...) for such long byte streams. In this case I'd strongly recommend to use a separate TX buffer, because then you can change the values in the original float array, while the DMA uses the TX Buffer to send out your data.

Chris_B
  • 359
  • 5
  • 13