Arm Mbed OS support forum

How to empty scanf buffer

I have an issue where I am trying to perform a number of functionality tests on some devices. My “test jig” communicates with the DUT (Device Under Test) via UART, using the scanf function.

Assuming the devices work as intended, there are no issues. However, one part of the test puts the DUT into sleep mode and my jig wakes it back up. If the DUT has a hardware problem and it doesn’t wake out of sleep, then my program hangs when performing the scanf, as it just sits and waits to receive data that isn’t coming.

I have tried to do an if(DUT.readable()), but as it retains info from the previous string that was sent, it sees the device as readable (this is what I believe is happening at least).

I have tried to clear the buffer using the following that I found online:

while (DUT.readable()) {
        DUT.getc();
    }

but this still doesn’t work and it still attempts to read a string that will never be coming. As far as I can see, there is no way to do a timeout on the scanf, so I wanted to do a check to see if anything was available, then skip if not, but I cannot seem to clear the buffer properly. The incoming string ends with \r\n if this is useful information.

Does anyone have a way to reliably clear this buffer, or perhaps any other solutions?

For reference, my microcontroller is the STM32F091RC, and I am using the online compiler

Ahoj,

I am not sure if I understood it correctly but… Clearing input buffer in C/C++. It seems the sync() can be an equivalent.

Or maybe you can try something like below, without the scanf directly.

        Timer timer;
        timer.start();
        // char buffer
        bool complete = false;
        while(1){
            if(DUT.readable()){
                char c = DUT.getc();  
                // something with c variable
                // probably store c to a buffer      
                if(c == '\n'){ // EOF
                    complete = true;                 
                    break; // break loop after EOL
                }
            }
            if(timer.read_ms() > 3000){
                timer.stop();
                break;    // break loop after timeout
            }
        }
        if(complete) {
            // process the buffer with sscanf
        }else{
            // error handler
        }

BR, Jan

Hi @JohnnyK, I gave your code snippet a go, and wasn’t able to get it working. It just fails to read anything.

I have also tried using sync() and that doesn’t seem to work either. It still sees it as readable somehow!

I’m sorry I didn’t help you.
For me It seems to be ok.

#include "mbed.h" // MbedOS 5.15.5
#define DEBUG 1
DigitalOut led(LED1);
Serial DUT(USBTX,USBRX);

bool myRead(char* outBuff, int timeOut){
    Timer timer;
    debug_if(DEBUG, "Ready for input!\n");
    bool complete = false;
    int i = 0;
    timer.start();
    while(1){
        if(DUT.readable()){
            char c = DUT.getc();  
                // something with c variable
                // probably store c to a buffer 
                outBuff[i] = c;  
                i++;
            if(c == '\n'){ // EOF
                complete = true;               
                break; // break loop after EOL
            }
        }
        if(timer.read_ms() > timeOut){
            timer.stop();
            break;    // break loop after timeout
        }
    }
    if(complete) {
        // process the buffer with sscanf
        debug_if(DEBUG, "Reading complete!\n");
    }else{
        // error handler
        debug_if(DEBUG, "Time-out!\n");
    }
    return complete;
}

int main()
{
    debug_if(DEBUG, "TEST\n");
    while(1){
        char buffer[50]= "";
        if(myRead(buffer, 3000)){
            printf("Input: %s",buffer);
        };
        led =! led;
    }
}

BR, Jan