go-serial icon indicating copy to clipboard operation
go-serial copied to clipboard

Always return 1 byte of data

Open ma6254 opened this issue 3 years ago • 1 comments

platform: windows 10

image image

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 {
	}
}

ma6254 avatar Jun 21 '22 10:06 ma6254

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.

cmaglie avatar Jul 01 '22 11:07 cmaglie