I have a digital caliper that can send measured value over the serial port. This data is formatted like +123.45
and can be sent at any time by the device.
So my program needs to "listen" for the first data input (that always ends with a carriage return) and close the reading directly after this one, before continuing his own work.
Dedicated terminals like CoolTerm and Putty handle these unpredictable inputs perfectly… But I don't see how to do that in Go (even with cgo).
…that doesn't work…
package main
import (
"bufio"
"fmt"
"os"
"syscall"
"unsafe"
)
func main() {
f, err := os.OpenFile("/dev/tty.PL2303-00003014", syscall.O_RDWR+syscall.O_NOCTTY+syscall.O_NDELAY+syscall.O_NONBLOCK, 0666)
if err != nil {
panic(err)
}
defer f.Close()
// Init terminal for 4800 7E2.
t := &syscall.Termios{
// Enable parity checking, strip to 7 bits, CR to NL, outgoing software flow control.
Iflag: syscall.INPCK + syscall.ISTRIP + syscall.ICRNL + syscall.IXON,
// Set 4800 bauds, 7 data bits, even parity, 2 stop bits, DTR.
Cflag: syscall.B4800 + syscall.CS7 + syscall.PARENB + syscall.CSTOPB + syscall.TIOCM_DTR + syscall.CREAD + syscall.CLOCAL + syscall.CSIZE,
Cc: [20]uint8{syscall.VMIN: 1},
Ispeed: syscall.B4800,
Ospeed: syscall.B4800,
}
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.Fd()), uintptr(syscall.F_SETFL), uintptr(unsafe.Pointer(t)))
if errno != 0 {
panic("syscall error: " + errno.Error())
}
// Read until the first new line byte ( is converted to
with the ICRNL flag).
fr := bufio.NewReader(f)
line, err := fr.ReadBytes('
')
if err != nil {
panic(err)
}
fmt.Println(string(line))
}