bugst / go-serial

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

lose data in linux #157

Closed weingxing closed 1 year ago

weingxing commented 1 year ago

Hi, i want to use this lib to reveive and handle message by a hardware(SIM900A), but i just receive part of the message, and i use minicom to test the hardware, it works fine. just like the picture: there is my code:

package app

import (
    "go.bug.st/serial"
    "io"
    "log"
    "strings"
    "sync"
)

const BUFFER_SIZE = 1024 * 8
var port io.ReadWriteCloser = nil

func connDevice() {
    options := &serial.Mode{
        BaudRate: 115200,
    }
    p, err := serial.Open("/dev/ttyS2", options)
    if err != nil {
        log.Fatal(err)
    }
    port = p
}

func close() {
    if port != nil {
        port.Close()
    }
}

func listenSms() {
    buffer := make([]byte, BUFFER_SIZE)
    for {
        port.Read(buffer)
        sms := string(buffer[:])
        if strings.Contains(sms, "+CMT:") {
            log.Println("receive a message.")
            log.Println(sms)
        } else if len(strings.ReplaceAll(string(buffer), string(0), "")) > 0 {
            // todo 
        }
    }
}

func main() {
    wg := sync.WaitGroup{}
    wg.Add(1)
    connDevice()
    defer close()
    go listenSms()
       // other gorutine, don't use serial
    wg.Wait()
}

and this code can run correctly in windows with CH340, but in linux (ARM, the hardware is bananapi m2 zero, the os is ubuntu16.04, SIM900A connect to bananapi by UART pins), it is wrong.

darthrookie commented 1 year ago

In my experience sometimes (with all libraries) messages don't arrive complete at the first read, you need to store what you receive in a buffer and then read again the times necessary to complete the message. There are two ways to know if a message is complete; if you see the number of characters you need to receive, you validate for that, or you check if there is an end of the message in the received buffer. For your particular case, the end of the message should be a new line (\n) character.

Good luck.

weingxing commented 1 year ago

@darthrookie Thanks, I have tried it and it works well.