Reading Float terminal inputs using BufferedSerial

Hi Guys,

I am just after some advice about the best way to read floating point inputs (from terminal) using the BufferedSerial library. Its been a while since Ive used serial in a project… last time was propably MBED OS 3 :thinking:

many thanks,

Andy

Hello,

you probably need a delimiter after your float number, then read and concatenate incoming data (memcpy - size will be number of bytes returned by BufferedSerial::read(...) ) until the delimiter is encountered. Then just atof or sscanf.

BR, Jan

I am not too sure what you mean by the delimiter and concatenating the incoming data. I am sorry if this seems like a fairly simple thing to implement, serial communications isnt my strong suit. To add a little more context to what I am trying to achieve; the user should be able to input a float such as 0.56 (probably no more than 3 dp) followed by pressing enter to confirm completion of input. Then, a variable such as float input should be set to 0.56.

I am at this point:

#include "mbed.h"
#include <cstdio>
#include <stdio.h>      /* printf, fgets */
#include <stdlib.h>     /* atof */

BufferedSerial pc(USBTX, USBRX);
char *input = new char[4];
char mess[] = "\nHello World\n";
float n;

// main() runs in its own thread in the OS
int main(){
    pc.set_baud(9600);
    pc.set_format(8, BufferedSerial::None, 1); //8-N-1

    while(1) {
        pc.write(mess, sizeof(mess));
        pc.read(input, sizeof(input));
        n = atof(input);
        printf("N = %.2f", n);
    }
}

However this provides the following output:

Hello World

Hello World

Hello World

Hello World

Hello World

Hello World

Hello World

Hello World
N = 3.00N = 0.00N = 0.00N = 2.00N = 5.00N = 1.00N = 4.00N = 2.00

Note that eight inputs are required before the code then dumps all the inputted values at once as individual values. In this case the inputted value should be 3.025142. This behaviour seems to suggest that each input increments the while loop without reaching the printf statement. In other words there seems to be a blocking condition.

With STD it is easy, take a look to c++ scanf example https://cplusplus.com/reference/cstdio/scanf/

I usually read input char by char until a custom end character (just ! for example) is not arrived, the delimiter.

You need to collect data from uart, be sure data in buffer are in correct format and length and then you can convert data from buffer to floats. That is necessary because Un/Buffered Serial::read can return different length every time.
As an example. You send 6 digits from PC terminal to Mbed. Mbed can read it in one read call (all 6) or in two separate (2 and 4 digits).

The behavior of the output what you saw, was caused by your code.

  • There are two instances of BufferedSerial API in the game. One is for STDIO console (printf) and the second for your object pc. This is just a note no real reason
  • The main reason is your printf does not contain \n and so it does not know when exactly you want to print out the data. When you add \n to printf, then you will see the output how you expected.

BR, Jan