tarm / serial

BSD 3-Clause "New" or "Revised" License
1.62k stars 452 forks source link

lost data via bufio.Read #122

Closed xh-78 closed 1 year ago

xh-78 commented 3 years ago

I am using ubuntu, when I use bufio to read from serial, it seems lost some data. But it's ok to use the raw Read. It's very strange.Bellow is my code.


func main() {
    c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 2000000}
    s, err := serial.OpenPort(c)
    if err != nil {
        log.Fatal(err)
    }
    for {
        if false {
            // this branch will lost data
            var n int
            buf := make([]byte, 128)
            br := bufio.NewReader(s)                                                                                                                                                                                                                           
            n, err = br.Read(buf)                                                                                                                                                                                                                              
            fmt.Print(string(buf[:n]))                                                                                                                                                                                                                         
        } else {  
           // this branch is ok                                                                                                                                                                                                                                             
            var n int                                                                                                                                                                                                                                          
            buf := make([]byte, 128)                                                                                                                                                                                                                           
            n, err = s.Read(buf)                                                                                                                                                                                                                               
            if err != nil {                                                                                                                                                                                                                                    
                log.Fatal(err)                                                                                                                                                                                                                                 
            }                                                                                                                                                                                                                                                  
            fmt.Printf(string(buf[:n]))                                                                                                                                                                                                                        
        }                                                                                                                                                                                                                                                      
    }                                                                                                                                                                                                                                                          
} 
orestonce commented 1 year ago

The bufio.Reader reads more bytes into memory than you expect, so in a for loop, you must only reuse one bufio.Reader instance. Try the code below:

func main() {
    c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 2000000}
    s, err := serial.OpenPort(c)
    if err != nil {
        log.Fatal(err)
    }
  br := bufio.NewReader(s)  
    for {
        if false {
            // this branch will lost data
            var n int
            buf := make([]byte, 128)                                                                                                                                                                                                                         
            n, err = br.Read(buf)                                                                                                                                                                                                                              
            fmt.Print(string(buf[:n]))                                                                                                                                                                                                                         
        } else {  
           // this branch is ok                                                                                                                                                                                                                                             
            var n int                                                                                                                                                                                                                                          
            buf := make([]byte, 128)                                                                                                                                                                                                                           
            n, err = s.Read(buf)                                                                                                                                                                                                                               
            if err != nil {                                                                                                                                                                                                                                    
                log.Fatal(err)                                                                                                                                                                                                                                 
            }                                                                                                                                                                                                                                                  
            fmt.Printf(string(buf[:n]))                                                                                                                                                                                                                        
        }                                                                                                                                                                                                                                                      
    }                                                                                                                                                                                                                                                          
} 
xh-78 commented 1 year ago

Thanks for your remainder. It's due to my misuse of bufio.Reader