Arm Mbed and Pelion Device Management support forum

Scanf taking int value from serial: succeeds every second time

Dear serial mbed Gurus,

Why does this scanf work every second time on my nucleo F401RE?

I’m trying to send values in text via serial (from a python program) to the nucleo mbed. The mbed recognizes every second value sent – which is not very helpful. Perhaps an end of line character is not being flushed from the buffer or something, but at this stage
I find myself trying random things, because I just don’t understand what is going on.

The mbed code:

#include "mbed.h"

Serial pc(USBTX, USBRX, 115200); // tx, rx

int grabvalue(void){
    char c, ch;
    char buffer[28];
    int i, num, ii;
    
    pc.printf("\n\nSeeking a value in the format, with tag: VALUE: int\n");
    
    num = pc.scanf(" VALUE: %2d", &ii);
    pc.printf("\nNumber of values parsed (1 expected):%d\n", num);
    
    if(num==1){
        pc.printf("Data Parsed:%d\n", ii);
        if(pc.readable()){ //clear the port to the next newline
            while(getchar() !=  '\n'){continue; } 
            pc.printf("cleared to line end.\n");
        } 
    } else {
        pc.printf("Incorrect input or format: Clearing serial to new line. \n");
        if(pc.readable()){
            while(getchar() !=  '\n'){continue; } 
            
        } else {
            pc.printf("Nothing further to clear \n");
        }
        
        return -1;
    }
    
    pc.printf("Leaving grabvalue\r\n");  
    
    return 0;
}




int main() {
    int success = -1;
    
    pc.printf("\n\nRESTART_________________________________________________\n");   
    pc.printf("Entering loops\n");
    while(1) {
         if(pc.readable()){ // anything on serial will trigger an attempt to re-sync time.
                pc.printf("Read value");
                success = grabvalue();
             //wait_us(50000);
              
            if (success != 0) {
                    pc.printf("Failed grabvalue\n");
                } else {
                     pc.printf("grabvalue worked (main loop)\n");
            }
         
         }  
        
       
    }
}

The python code sending the data and collecting responses:

import serial
from time import sleep
import datetime

           

ser = serial.Serial(port="COM4",       
            baudrate=115200,
            #baudrate=460800,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            bytesize=serial.EIGHTBITS,
            timeout=1)

sleep(2.0) #give the mbed time to establish

tot = ser.inWaiting()
ser.inWaiting()
print(ser.read_until(terminator = b'zzz', size = tot))

for i in range(10, 20):
    
    ##form the string
    msg = "VALUE: "+ str(i)+"\n"
    ser.write(str.encode(msg,"ASCII"))
    sleep(0.2)
    
    ser.inWaiting()
    tot = ser.inWaiting()
    #ser.inWaiting()
    print(ser.read_until(terminator = b'zzz', size = tot))


ser.close()

The output from this, which indicates every second value is being accepted (main problem), and also that the preamble sent by the mbed is also not being received.

b’’ b’Read value\n\nSeeking a value in the format, with tag: VALUE:
int\n’ b’\nNumber of values parsed (1 expected):1\nData
Parsed:11\nLeaving grabvalue\r\ngrabvalue worked (main loop)\n’ b’Read
value\n\nSeeking a value in the format, with tag: VALUE: int\n’
b’\nNumber of values parsed (1 expected):1\nData Parsed:13\nLeaving
grabvalue\r\ngrabvalue worked (main loop)\n’ b’Read value\n\nSeeking a
value in the format, with tag: VALUE: int\n’ b’\nNumber of values
parsed (1 expected):1\nData Parsed:15\nLeaving grabvalue\r\ngrabvalue
worked (main loop)\n’ b’Read value\n\nSeeking a value in the format,
with tag: VALUE: int\n’ b’\nNumber of values parsed (1
expected):1\nData Parsed:17\nLeaving grabvalue\r\ngrabvalue worked
(main loop)\n’ b’Read value\n\nSeeking a value in the format, with
tag: VALUE: int\n’ b’\nNumber of values parsed (1 expected):1\nData
Parsed:19\nLeaving grabvalue\r\ngrabvalue worked (main loop)\n’

For some of you this may be an obvious problem, and I would greatly appreciate your advice.

Thanks for your help.

Ahoj,

I tested that only with terminal but from my point of view it is occur because all even messages (10, 12, 14,16…) are consumed as a trigger for if(pc.readable()) from the while loop in your main.
It looks like the the problem is occur because the scanf is not called immediately after pc.readable() for a reason.
When you will try to commented out the pc.printf("\n\nSeeking a value in the format, with tag: VALUE: int\n"); on the line 10 and pc.printf("Read value"); on the line 48, it works normal for me.

BR, Jan

Fantastic obserations.

These were a big help to me.

Thanks very much

Matt