How to transfer number like float and int thorugh hardware serial(Tx,Rx,UART)?

I saw some posts online but they didn’t exactly solved my question, or at least not in an easy manner.

Suppose one wanted to send a number to another board through Tx Rx pin.
However, the Serial.write() function did not support int or float by default, since they occupy 2bytes and 4bytes by default. I saw someone mentioned highByte() and lowByte(), but they only work for int, and could not treat float easily.

I tried to use the command such as
Serial.write( 1, sizeof(int)); but the software returned error.

Is there a uniform way to send data through hardware serial?

For a float, you can convert to a string (null terminated character array), send and convert back at the other end. Use dtostrf() to convert float to string and atof() to convert back.

Use itoa() to convert an int to a string and atoi() to convert string to int.

This library may be of interest. I have never used it but have seen it mentioned in posts pertaining to serial communication.

And a good tutorial on receiving serial data that i found very helpful is the serial input basics tutorial.

You can send the constituent bytes of a float like this (there are a few ways, this is one):

float
    fVal;
unsigned char
    *puchPtr;
char
    szTmp[10];

//simulated receive buffer
unsigned char
    rxBuffer[4] = { 0x25, 0x52, 0x9a, 0x44 };

float
    fFloat;
    
void setup() 
{
    char
        ch;
        
    Serial.begin(115200);

    //----- Part 1: Send a float
    fVal = 1234.567;
    puchPtr = (unsigned char *)&fVal;

    Serial.println( "\nSent float: " );
    //show an ASCII version of bytes that will be sent
    for( int i=0; i<sizeof( float ); i++ )
    {
        sprintf( szTmp, "%02X ", *(puchPtr+i) );
        Serial.print( szTmp );
        
    }//for
    
    Serial.println();
    
    //write actual binary float
    Serial.write( (unsigned char *)puchPtr, sizeof( float ) );    
    Serial.print( "\n\n" );

    //----- Part 2: Receive float and print it
    memcpy( (void *)&fFloat, (unsigned char *)rxBuffer, sizeof( float ) );
    
    Serial.println( "Received float: " );
    Serial.print( fFloat, 3 );
    Serial.println();    
    
}//setup

void loop() 
{

}//loop

Part 2 shows how you can convert the received 4 bytes back into a float at the other end.

Unions are good for this too…

“Is there a uniform way to send data through hardware serial?”

Just send the number as a text character representation, like “123.45”, then convert it to a number on the receiving end.

I thought about that.
However, suppose that

unsigned int code =200100;

Serial.write((const char*) & code , 2);

At receiving end I tried

unsigned int number_1=0;

number_1=Serial1.read()<<8|Serial1.read();

or that

byte temp1=Serial1.read();
byte temp2=Serial1.read();

number_1=( number_1 << 8 ) +temp2;
number_1=( number_1 << 8 ) +temp1;

etc.(all the possible combination) none of them returned me the correct number.

P_A: However, suppose that

unsigned int code =200100;

What's the largest value an unsigned integer can hold?

1. Given number is:

unsigned int code =200100;

Let us note that the entered number is always stored in memory locations as ‘natural binary’. Accordingly, 200100 will be saved as: 0011 0000 1101 1010 0100 (0x30DA4 in hex base). It is larger than 16-bit; so, the int type variable code will not hold the number. We need to declare it as:

unsigned long int code = 200100;  //long type variable hold 32-bit data
==> unsigned long code = 200100;  // 0x30DA4; int is understood.

2. Now, decide as to which representation (200100 or 0x30DA4) to send to the destination using UART Port. Let us agree that we want to send this image 200100; where, every digit will be sent in its 8-bit ASCII format according to following Table (Fig-1). The code is:

Serial.print(code, DEC);  //0x32, 0x30, 0x30, 0x31, 0x30, 0x30 reach at receiver


Figure-1:

3. At the receiver, let us collect the ASCII represented codes and convert them back to this image 200100 and the decimal represented literal number: 200100.

4. Codes:
Transmit Codes:(tested)

#include<SoftwareSerial.h>
SoftwareSerial SUART(6, 7); //SRX = DPin-6, STX = Dpin-7
unsigned long code = 200100; //0x030DA4
void setup() 
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop() 
{
  Serial.println(code, DEC);
  SUART.print(code, DEC); //
  delay(1000);
}

Receive Codes:(tested)

#include<SoftwareSerial.h>
SoftwareSerial SUART(6, 7); //SRX = DPin-6, STX = Dpin-7
char code[7]="";

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  byte n = SUART.available();
  if ( n == 6)
  {
    for (int i = 0; i < 6; i++)
    {
      code[i] = SUART.read();
    }
    code[6] = '\0';
    Serial.println(code);
    unsigned long code1 = atol(code);
    Serial.println(code1, DEC);
    memset(code, 0, 7);
  }
}

5. //-------------Sending 200100 (0x030DA4) as binary number-------------
**(1)**TX Codes

#include<SoftwareSerial.h>
SoftwareSerial SUART(6, 7); //SRX = DPin-6, STX = Dpin-7
unsigned long code = 200100; //0x030DA4

union  ////Convert the given number into bytes using the following union structure.
{
  unsigned long x;
  byte myData[4];
}data;

void setup() 
{
  Serial.begin(9600);
  SUART.begin(9600);
  data.x = 200100;
}

void loop() 
{
  Serial.println(data.x, DEC);
  SUART.write(data.myData, sizeof(data.myData));
  delay(1000);
}

(2)RX Codes:

#include<SoftwareSerial.h>
SoftwareSerial SUART(6, 7); //SRX = DPin-6, STX = Dpin-7

union
{
  unsigned long x;
  byte myData[4];
}data;

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  byte n = SUART.available();
  if ( n == 4)
  {
    for (int i = 0; i < 4; i++)
    {
      data.myData[i] = SUART.read();
    }
    Serial.println(data.x, DEC);  
  }
}

6. //------- sending float x = 12.73 using UART Port-------------------------------------------
The steps very similar to that of sending/receiving integer numbers shown above except that you have to use atof() function.

The simplest way to send numbers is using Serial.print()

...R