From eb5d58799445b06ffad9f5f164b3579e79fdd314 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 4 Feb 2021 00:50:39 +0100 Subject: [PATCH] Implement read and checksum --- main.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 7e7fb97..2d290c8 100644 --- a/main.go +++ b/main.go @@ -1,24 +1,85 @@ package main import ( + "bytes" "flag" + "io" "log" "os" "os/signal" "syscall" "time" + "unicode" "github.com/tarm/serial" ) -func readSerial(s *serial.Port, interval *time.Duration) { +func readSerial(s *serial.Port, c chan []byte) { + var unread bytes.Buffer + buf := make([]byte, 128) + for { + n, err := s.Read(buf) + if err != nil { + log.Fatal(err) + } + + unread.Write(buf[:n]) + + for { + line, err := unread.ReadBytes('\n') + if err == io.EOF { + if _, err = unread.Write(line); err != nil { + log.Println(err) + } + break + } else if err != nil { + log.Println(err) + break + } + + c <- bytes.TrimRightFunc(line, func(r rune) bool { + return unicode.IsSpace(r) || unicode.IsControl(r) + }) + } + } +} + +func computeChecksum(area []byte) (checksum byte) { + for _, c := range area { + checksum += c + } + + checksum = (checksum & 0x3F) + 0x20 + + return +} + +func treatLines(c chan []byte) { + for { + line := <-c + + if len(line) <= 1 { + continue + } + + if computeChecksum(line[:len(line)-1]) != line[len(line)-1] { + log.Printf("BAD checksum on %s: calculated: %c\n", line, computeChecksum(line[:len(line)-1])) + continue + } + + fields := bytes.Fields(line) + + log.Println(fields) + } } func main() { var interval = flag.Duration("interval", 5*time.Second, "Minimum time between releve") flag.Parse() + log.Println(interval) + if len(flag.Args()) < 1 { log.Println("missing required argument: serial device (eg. /dev/ttyUSB0)") return @@ -37,7 +98,9 @@ func main() { log.Fatal(err) } - go readSerial(s, interval) + c := make(chan []byte) + go readSerial(s, c) + go treatLines(c) interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)