go-serial
go-serial copied to clipboard
Always return 1 byte of data
platform: windows 10

package main
import (
"encoding/binary"
"encoding/hex"
"fmt"
"log"
"time"
"go.bug.st/serial"
)
var testCOM = "COM23"
var step uint8
type ReadPkgCallback func([]byte)
func main() {
var (
err error
)
fmt.Printf("Hello, world.\n")
mode := &serial.Mode{
BaudRate: 115200,
DataBits: 8,
Parity: serial.NoParity,
StopBits: serial.OneStopBit,
}
port, err := serial.Open(testCOM, mode)
if err != nil {
log.Fatal(err)
}
err = port.SetReadTimeout(time.Millisecond * 1000)
if err != nil {
log.Fatal(err)
}
wch := make(chan int, 1)
go func(ch chan int) {
wtick := time.NewTicker(time.Millisecond * 10)
w_loop:
for {
select {
case <-ch:
break w_loop
case <-wtick.C:
port.Write([]byte{0x7F})
}
}
}(wch)
r_fn := func(b []byte) {
log.Printf("recv package: %#v\n", b)
}
go func(fn ReadPkgCallback) {
for {
var (
rb = make([]byte, 1)
head_cnt = 0
)
for {
_, err = port.Read(rb)
// fmt.Printf("r: %02X\n", rb[0])
if head_cnt == 0 {
if rb[0] == 0x46 {
head_cnt = 1
}
} else {
if rb[0] == 0xb9 {
// wch <- 1
break
} else {
head_cnt = 0
}
}
}
rb = make([]byte, 1)
_, err := port.Read(rb)
if err != nil {
return
}
if rb[0] != 0x68 {
continue
}
var len uint16
binary.Read(port, binary.BigEndian, &len)
fmt.Printf("len: %#v\n", len)
rb = make([]byte, len-4)
n, err := port.Read(rb)
fmt.Printf("n: %d\n", n)
fmt.Printf("%s\n", hex.Dump(rb))
fn(rb)
// _, err := port.Read(rb)
// if err != nil {
// }
}
}(r_fn)
for {
}
}
The reason is that Read waits until at least one byte is received:
// Stores data received from the serial port into the provided byte array
// buffer. The function returns the number of bytes read.
//
// The Read function blocks until (at least) one byte is received from <-----
// the serial port or an error occurs.
Read(p []byte) (n int, err error)
As soon as the first byte is received the function will unblock and return that byte. If you want to read a fixed-size string you need to cycle and accumulate until you reach the desired size.