1

using WiringPi library for serial communication on Raspberrypi the function serialPutchar(int fd, unsigned char c) and serialGetchar (int fd) works fine to send and receive integer value but does not show floating points

sender side

int main ()
{
int fd ;
int count ;
float val;

if ((fd = serialOpen ("/dev/ttyAMA0", 9600)) < 0)
{
fprintf (stderr, "Unable to open serial device: %s\n", strerror 
(errno)) ;
return 1 ;
}

if (wiringPiSetup () == -1)
{
fprintf (stdout, "Unable to start wiringPi: %s\n", strerror 
(errno)) ;
return 1 ;
}
for (count = 0 ; count < 256 ; ){
val=4.1;
fflush (stdout) ;
serialPutchar(fd,val);
++count ;
delay (500) ;
}
printf ("\n");
return 0;}

Receiver side

 int main ()
 {
 int fd ;

 if ((fd = serialOpen ("/dev/ttyUSB0", 9600)) < 0)
 {
fprintf (stderr, "Unable to open serial device: %s\n", strerror 
(errno)) ;
return 1 ;
}
if (wiringPiSetup () == -1)
{
fprintf (stdout, "Unable to start wiringPi: %s\n", strerror 
(errno)) ;
return 1 ;
}
while(true)

{

  printf ("%f", serialGetchar (fd)) ;
  fflush (stdout) ;
  printf ("\n") ;
}

return 0 ;
}

i expected the output to be 4.100000 but the actual output is 0.000000

Any help to send and receive floating point numbers will be appreciated Thanks in advance

jeeth
  • 23
  • 4
  • 3
    If you want a solution in C++ then please don't add the C tag. C and C++ are two *very* different languages, with different rules and semantics and constructs. With that said, the code you show could be plain C, there's nothing in the code that requires a C++ compiler. – Some programmer dude Aug 01 '19 at 12:16
  • If you just print a single character, I'd prefer `putchar('\n')` over `printf("\n")`; result is the same, put the former is more efficient. – Aconcagua Aug 01 '19 at 12:18
  • 3
    why would **one** character be 4.1?? – Antti Haapala -- Слава Україні Aug 01 '19 at 12:20
  • 1
    You need to convert the float to a byte array on the sending side, and send that, and do the opposite process on the receiving side. – 500 - Internal Server Error Aug 01 '19 at 12:22
  • What do you think happens to your float if you assign it to an unsigned char? Then what is the return type of `serialGetchar`? Pretty sure it is `unsigned char`. Printing such with `%f` format specifier invokes undefined behaviour. So anything might happen... You'd need to cast to double (not [float](https://en.cppreference.com/w/cpp/io/c/fprintf)) before! (Just to avoid the UB, transmission still won't work...) – Aconcagua Aug 01 '19 at 12:22

2 Answers2

4

What you need to do is break the float into bytes and then send/receive them one by one. Note: The following code assumes sender and receiver using same endian system.

//Sender
float f = 4.1;
int i = 0;
for (; i < sizeof(float); ++i)
    serialPutchar(fd, ((char*)& f)[i]);


// receiver
float f;
int i = 0;
for (; i < sizeof(float); ++i)
    ((char*)& f)[i]) = serialGetchar(fd);
nivpeled
  • 1,810
  • 5
  • 17
  • 3
    Apart from size, both ends must use the same binary representation as well. Pretty likely that both use IEEE754, but that's not mandated anywhere. – Aconcagua Aug 01 '19 at 12:53
  • Note that _in general_ endian of integers need not match endian of `float`. Yet if sender/receiver are matched systems, endian and FP format are of neglible concern. – chux - Reinstate Monica Aug 01 '19 at 13:28
0

A float needs to send data as multiple bytes, not just one call of serialPutchar() which sends only 1.

When receiving multiple bytes over a serial channel, it is easy for a byte to be dropped or for the receiver to begin in mid-stream. I recommend employing framing the data, in some fashion to cope.

Example: Send as text with sentinels

// Sender
char buf[30];
snprintf(buf, sizeof buf, "<%a>", some_float);
serialPutString(fd, buf);

// Receive
while (serialGerChar(fd) != '<') {
  ;
}
char buf[30*2];
for (i=0; i<sizeof buf - 1; i++) {
  buf[i] = serialGetChar(fd);
  if (buf[i] == '>') {
    break;
  }
}
buf[i] = '\0';
f = strtod(buf, &endptr);
// additional checks possible here.

Robust code does not assume incoming data is well formed and check for various problem like incomplete, excessive, non-numeric text.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256