bugst / go-serial

A cross-platform serial library for go-lang.
BSD 3-Clause "New" or "Revised" License
620 stars 189 forks source link

Read from port blocks forever when data is received #43

Closed Aukstkalnis closed 4 years ago

Aukstkalnis commented 6 years ago

Device constantly sends data to host. Upon reading first time, text is read that device never sends and second read blocks forever. But if I use "github.com/tarm/serial", everything works ok. My OS is windows 10 x64. My code:

package main

import (
    "fmt"
    "log"
    "regexp"

    serial "go.bug.st/serial.v1"
)

func main() {
    config := serial.Mode{BaudRate: 115200, DataBits: 8, Parity: serial.NoParity, StopBits: serial.OneStopBit}
    p, err := serial.Open("COM8", &config)
    if err != nil {
        log.Fatal(err)
    }
    buf := make([]byte, 512)
    totalBuf := make([]byte, 0, 5000)
    var n int
    var foundLineIndex int
    search, err := regexp.Compile("([0-9\\.]*)/([0-9\\.]*)")
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Start scaning")
    for {
        log.Println("read data")
        n, err = p.Read(buf)
        if err != nil {
            log.Println("Error! Failed to read:", err)
            continue
        }
        // log.Println(buf[:n])
        for i, v := range buf[:n] {
            if v == '\r' {
                log.Println("Found line end")
                foundLineIndex = i + 1
            }
        }
        if foundLineIndex > 0 {
            totalBuf = append(totalBuf, buf[:foundLineIndex]...)
            result := search.FindAllSubmatch(totalBuf, -1)
            fmt.Println(result)
            if foundLineIndex < n {
                totalBuf = append(totalBuf[:0], buf[foundLineIndex:n]...)
                fmt.Println("there are leftovers")
            }
        } else {
            totalBuf = append(totalBuf, buf[:n]...)
        }
    }
}
cmaglie commented 6 years ago

Hi @Aukstkalnis sorry for the long delay answering this one.

May you provide a way to reproduce the problem? May you log the output of the read? something like:

  n, err = p.Read(buf)
  fmt.Printf("READ (%d)> %+v\n", n, buf[:n])

May you describe your application in a little more detail? in particular what kind of data is the device sending through the serial port?

Aukstkalnis commented 6 years ago

Well, in device I read 2000 ADC values to buffer and send them to PC when it is full in format '%.2f/%.2f '...'\r'. I can't take log now because I do not have time at for now. Communication is done via FTDI. I looked at USB communication and there are bytes coming from device, but software do not read them :/ To reproduce the problem I think you need some FTDI device that you can program to send 2k float values in format '%.2f/%.2f '...'\r' each 4s and see what happens. Maybe that this has to do something with USB devices...

cmaglie commented 4 years ago

Hi @Aukstkalnis without an example to reproduce the problem I'm lost...

I'm closing the issue since a lot of time has passed and I guess you have found a workaround by yourself in the meantime.

BTW If you're still interested don't hesitate to open a new issue but, please, provide a program that helps to reproduce the problem, this is a very fundamental piece of information to get the issue properly fixed.