Skip to content

Commit

Permalink
Improve client serial robustness
Browse files Browse the repository at this point in the history
  • Loading branch information
alexozer committed Feb 16, 2017
1 parent 7b30e30 commit 43b83dd
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
1 change: 1 addition & 0 deletions client/cli.go
Expand Up @@ -282,6 +282,7 @@ func (this *Cli) drawAxis(name string, x, y, width, height int) {
textWidth := width - 3
ls.Items = []string{
padApart("VAL:", this.vars["placement"][name].ValueString(), textWidth),
padApart("VEL:", this.vars["placement"][name+"Vel"].ValueString(), textWidth),
padApart("OUT:", this.vars["controllerOut"][name].ValueString(), textWidth),
padApart("EN:", conf["enabled"].ValueString(), textWidth),
}
Expand Down
7 changes: 4 additions & 3 deletions client/sender.go
Expand Up @@ -37,6 +37,7 @@ func (this *Sender) Start() {

go func() {
var handheldConnected, droneConnected bool
//var handheldConnected bool

for {
select {
Expand Down Expand Up @@ -123,7 +124,7 @@ func (this *Sender) read(encodedInChan chan chan []byte) {
}
if proto.Unmarshal(encodedVar[1:encodedVar[0]+1], shmMsg) != nil {
this.status <- "Unable to unmarshal remote message"
continue
break
}

var outValue interface{}
Expand All @@ -136,13 +137,13 @@ func (this *Sender) read(encodedInChan chan chan []byte) {
outValue = inValue.BoolValue
default:
this.status <- "Unknown remote var type"
continue
break
}

v, err := BindVarTag(int(*shmMsg.Tag), outValue)
if err != nil {
this.status <- fmt.Sprint("Failed to bind remote var:", err)
continue
break
}
this.varsOut <- v
encodedVar = encodedVar[encodedVar[0]+1:]
Expand Down
48 changes: 37 additions & 11 deletions client/serial.go
Expand Up @@ -7,7 +7,10 @@ import (
"github.com/tarm/serial"
)

const handheldRetryPeriod = time.Millisecond * 250
const (
serialRetryPeriod = time.Second / 4
serialTimeout = time.Second / 10
)

type Serial struct {
In chan [][]byte
Expand Down Expand Up @@ -38,13 +41,17 @@ func (this *Serial) Start() {
go func() {
for {
this.startSession(portChan)
time.Sleep(handheldRetryPeriod)
time.Sleep(serialRetryPeriod)
}
}()
}

func (this *Serial) startSession(portChan chan *serial.Port) {
config := serial.Config{Name: this.portName, Baud: this.baud}
config := serial.Config{
Name: this.portName,
Baud: this.baud,
ReadTimeout: serialTimeout,
}
port, err := serial.OpenPort(&config)
if err != nil {
return
Expand All @@ -55,18 +62,37 @@ func (this *Serial) startSession(portChan chan *serial.Port) {

portChan <- port

disconnect := func() {
this.Connected <- false
this.status <- fmt.Sprint("Serial disconnected on", this.portName)
}

buf := make([]byte, 256)
for {
n, err := port.Read(buf)
if err != nil {
this.Connected <- false
this.status <- fmt.Sprint("Serial disconnected on", this.portName)
return
t := time.Now()
n, _ := port.Read(buf[:1])
if n == 0 {
if time.Since(t) < serialTimeout/2 {
disconnect()
return
}
continue
}

msgTarget := buf[1 : buf[0]+1]
t = time.Now()
n, _ = port.Read(msgTarget)
if n < len(msgTarget) {
if time.Since(t) < serialTimeout/2 {
disconnect()
return
}
continue
}

// Assume we get the whole message(s) at once
outBuf := make([]byte, n)
copy(outBuf, buf[:n])
// Assume we've received the entire message at this point
outBuf := make([]byte, len(msgTarget)+1)
copy(outBuf, buf[:len(msgTarget)+1])
this.Out <- outBuf
}
}
Expand Down

0 comments on commit 43b83dd

Please sign in to comment.