forked from hybridgroup/gobot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
motor_driver.go
206 lines (185 loc) · 4.3 KB
/
motor_driver.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package gpio
import (
"github.com/hybridgroup/gobot"
)
// MotorDriver Represents a Motor
type MotorDriver struct {
name string
connection DigitalWriter
SpeedPin string
SwitchPin string
DirectionPin string
ForwardPin string
BackwardPin string
CurrentState byte
CurrentSpeed byte
CurrentMode string
CurrentDirection string
}
// NewMotorDriver return a new MotorDriver given a DigitalWriter, name and pin
func NewMotorDriver(a DigitalWriter, name string, speedPin string) *MotorDriver {
return &MotorDriver{
name: name,
connection: a,
SpeedPin: speedPin,
CurrentState: 0,
CurrentSpeed: 0,
CurrentMode: "digital",
CurrentDirection: "forward",
}
}
// Name returns the MotorDrivers name
func (m *MotorDriver) Name() string { return m.name }
// Connection returns the MotorDrivers Connection
func (m *MotorDriver) Connection() gobot.Connection { return m.connection.(gobot.Connection) }
// Start implements the Driver interface
func (m *MotorDriver) Start() (errs []error) { return }
// Halt implements the Driver interface
func (m *MotorDriver) Halt() (errs []error) { return }
// Off turns the motor off or sets the motor to a 0 speed
func (m *MotorDriver) Off() (err error) {
if m.isDigital() {
err = m.changeState(0)
} else {
err = m.Speed(0)
}
return
}
// On turns the motor on or sets the motor to a maximum speed
func (m *MotorDriver) On() (err error) {
if m.isDigital() {
err = m.changeState(1)
} else {
if m.CurrentSpeed == 0 {
m.CurrentSpeed = 255
}
err = m.Speed(m.CurrentSpeed)
}
return
}
// Min sets the motor to the minimum speed
func (m *MotorDriver) Min() (err error) {
return m.Off()
}
// Max sets the motor to the maximum speed
func (m *MotorDriver) Max() (err error) {
return m.Speed(255)
}
// IsOn returns true if the motor is on
func (m *MotorDriver) IsOn() bool {
if m.isDigital() {
return m.CurrentState == 1
}
return m.CurrentSpeed > 0
}
// IsOff returns true if the motor is off
func (m *MotorDriver) IsOff() bool {
return !m.IsOn()
}
// Toggle sets the motor to the opposite of it's current state
func (m *MotorDriver) Toggle() (err error) {
if m.IsOn() {
err = m.Off()
} else {
err = m.On()
}
return
}
// Speed sets the speed of the motor
func (m *MotorDriver) Speed(value byte) (err error) {
if writer, ok := m.connection.(PwmWriter); ok {
m.CurrentMode = "analog"
m.CurrentSpeed = value
return writer.PwmWrite(m.SpeedPin, value)
}
return ErrPwmWriteUnsupported
}
// Forward sets the forward pin to the specified speed
func (m *MotorDriver) Forward(speed byte) (err error) {
err = m.Direction("forward")
if err != nil {
return
}
err = m.Speed(speed)
if err != nil {
return
}
return
}
// Backward sets the backward pin to the specified speed
func (m *MotorDriver) Backward(speed byte) (err error) {
err = m.Direction("backward")
if err != nil {
return
}
err = m.Speed(speed)
if err != nil {
return
}
return
}
// Direction sets the direction pin to the specified speed
func (m *MotorDriver) Direction(direction string) (err error) {
m.CurrentDirection = direction
if m.DirectionPin != "" {
var level byte
if direction == "forward" {
level = 1
} else {
level = 0
}
err = m.connection.DigitalWrite(m.DirectionPin, level)
} else {
var forwardLevel, backwardLevel byte
switch direction {
case "forward":
forwardLevel = 1
backwardLevel = 0
case "backward":
forwardLevel = 0
backwardLevel = 1
case "none":
forwardLevel = 0
backwardLevel = 0
}
err = m.connection.DigitalWrite(m.ForwardPin, forwardLevel)
if err != nil {
return
}
err = m.connection.DigitalWrite(m.BackwardPin, backwardLevel)
if err != nil {
return
}
}
return
}
func (m *MotorDriver) isDigital() bool {
return m.CurrentMode == "digital"
}
func (m *MotorDriver) changeState(state byte) (err error) {
m.CurrentState = state
if state == 1 {
m.CurrentSpeed = 0
} else {
m.CurrentSpeed = 255
}
if m.ForwardPin != "" {
if state == 0 {
err = m.Direction(m.CurrentDirection)
if err != nil {
return
}
if m.SpeedPin != "" {
err = m.Speed(m.CurrentSpeed)
if err != nil {
return
}
}
} else {
err = m.Direction("none")
}
} else {
err = m.connection.DigitalWrite(m.SpeedPin, state)
}
return
}