-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathservo_serial.go
125 lines (107 loc) · 2.93 KB
/
servo_serial.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package mks42d
import (
"fmt"
"time"
"github.com/tarm/serial"
)
/*
This module contains the abstraction for interacting with a stepper motor and its driver board.
Each concrete implementation of this interface for different driver boards should be in their
own files.
*/
type StepperDriver interface {
Connect() error // initialize serial connection
GetCurrentDistanceTraveled() int // get distance traveled since counter started in mm
ResetCounters() error // resets pulse and distance counters
StartGoingDown() error // start motor going forward
StartGoingUp(speed uint16) error // start motor going in reverse
Stop() error // stop all movement
FindMaxBottom() (int, error) // find the maximum encoder value to the bottom of the system
GoHome(speed uint16) error // go to the very top of the system
}
type DriverCommand struct {
name string
payload []byte
expectedResponseSize int
waitForResponseMs int
}
type ServoMessageType int
const (
ServoError ServoMessageType = iota // 0 ...
ServoTravelMessage
ServoEncoderMessage
ServoPulseCountMessage
)
type ServoMessage struct {
Type ServoMessageType
Data any
Message string
}
func msSinceEpoch() int64 {
return time.Now().UnixNano() / int64(time.Millisecond)
}
func connectToDriver(config *serial.Config) (*serial.Port, error) {
driverPort, err := serial.OpenPort(config)
if err != nil {
fmt.Println(err.Error())
return nil, fmt.Errorf("failed to connect to %s", config.Name)
}
return driverPort, nil
}
func addCRC(data []byte) []byte {
var checksum byte
for _, b := range data {
checksum += b
}
checksum &= 0xFF
data = append(data, checksum)
return data
}
func writeToDriver(port *serial.Port, payload []byte, flush bool) error {
if port == nil {
return fmt.Errorf("cannot write to nil port")
}
_, err := port.Write(addCRC(payload))
if err != nil {
fmt.Println(err.Error())
return fmt.Errorf("error writing to serial port")
}
if flush {
err = port.Flush()
if err != nil {
fmt.Println(err.Error())
return fmt.Errorf("error flushing serial port")
}
}
// time.Sleep(50 * time.Millisecond)
return nil
}
func readFromDriver(port *serial.Port, buffer []byte, flush bool) (int, []byte, error) {
if port == nil {
return 0, nil, fmt.Errorf("cannot read from nil port")
}
numberOfBytes, err := port.Read(buffer)
if err != nil {
fmt.Println(err.Error())
if err.Error() == "EOF" {
return 5, buffer, nil
}
return 0, nil, fmt.Errorf("error reading from serial port")
}
if flush {
err = port.Flush()
if err != nil {
fmt.Println(err.Error())
return 0, nil, fmt.Errorf("error flushing serial port")
}
}
time.Sleep(50 * time.Millisecond)
return numberOfBytes, buffer, nil
}
func ByteArrayToString(array []byte) string {
var hexString string
for _, byteValue := range array {
hexString += fmt.Sprintf("0x%02x ", byteValue)
}
return hexString
}