2
2
package easystepper // import "tinygo.org/x/drivers/easystepper"
3
3
4
4
import (
5
+ "errors"
5
6
"machine"
6
7
"time"
7
8
)
8
9
10
+ // StepMode determines the coil sequence used to perform a single step
11
+ type StepMode uint8
12
+
13
+ // Valid values for StepMode
14
+ const (
15
+ // ModeFour uses a 'four step' coil sequence (12-23-34-41). This is the default (zero-value) mode
16
+ ModeFour StepMode = iota
17
+ // ModeEight uses an 'eight step' coil sequence (1-12-2-23-3-34-4-41)
18
+ ModeEight
19
+ )
20
+
21
+ // stepCount is a helper function to return the number of steps in a StepMode sequence
22
+ func (sm StepMode ) stepCount () uint {
23
+ switch sm {
24
+ default :
25
+ fallthrough
26
+ case ModeFour :
27
+ return 4
28
+ case ModeEight :
29
+ return 8
30
+ }
31
+ }
32
+
33
+ // DeviceConfig contains the configuration data for a single easystepper driver
34
+ type DeviceConfig struct {
35
+ // Pin1 ... Pin4 determines the pins to configure and use for the device
36
+ Pin1 , Pin2 , Pin3 , Pin4 machine.Pin
37
+ // StepCount is the number of steps required to perform a full revolution of the stepper motor
38
+ StepCount uint
39
+ // RPM determines the speed of the stepper motor in 'Revolutions per Minute'
40
+ RPM uint
41
+ // Mode determines the coil sequence used to perform a single step
42
+ Mode StepMode
43
+ }
44
+
45
+ // DualDeviceConfig contains the configuration data for a dual easystepper driver
46
+ type DualDeviceConfig struct {
47
+ DeviceConfig
48
+ // Pin5 ... Pin8 determines the pins to configure and use for the second device
49
+ Pin5 , Pin6 , Pin7 , Pin8 machine.Pin
50
+ }
51
+
9
52
// Device holds the pins and the delay between steps
10
53
type Device struct {
11
54
pins [4 ]machine.Pin
12
- stepDelay int32
55
+ stepDelay time. Duration
13
56
stepNumber uint8
57
+ stepMode StepMode
14
58
}
15
59
16
60
// DualDevice holds information for controlling 2 motors
17
61
type DualDevice struct {
18
- devices [2 ]Device
62
+ devices [2 ]* Device
19
63
}
20
64
21
- // New returns a new easystepper driver given 4 pins, number of steps and rpm
22
- func New (pin1 , pin2 , pin3 , pin4 machine.Pin , steps int32 , rpm int32 ) Device {
23
- return Device {
24
- pins : [4 ]machine.Pin {pin1 , pin2 , pin3 , pin4 },
25
- stepDelay : 60000000 / (steps * rpm ),
65
+ // New returns a new single easystepper driver given a DeviceConfig
66
+ func New (config DeviceConfig ) (* Device , error ) {
67
+ if config .StepCount == 0 || config .RPM == 0 {
68
+ return nil , errors .New ("config.StepCount and config.RPM must be > 0" )
26
69
}
70
+ return & Device {
71
+ pins : [4 ]machine.Pin {config .Pin1 , config .Pin2 , config .Pin3 , config .Pin4 },
72
+ stepDelay : time .Second * 60 / time .Duration ((config .StepCount * config .RPM )),
73
+ stepMode : config .Mode ,
74
+ }, nil
27
75
}
28
76
29
77
// Configure configures the pins of the Device
@@ -34,17 +82,23 @@ func (d *Device) Configure() {
34
82
}
35
83
36
84
// NewDual returns a new dual easystepper driver given 8 pins, number of steps and rpm
37
- func NewDual (pin1 , pin2 , pin3 , pin4 , pin5 , pin6 , pin7 , pin8 machine. Pin , steps int32 , rpm int32 ) DualDevice {
38
- var dual DualDevice
39
- dual . devices [ 0 ] = Device {
40
- pins : [ 4 ]machine. Pin { pin1 , pin2 , pin3 , pin4 },
41
- stepDelay : 60000000 / ( steps * rpm ),
85
+ func NewDual (config DualDeviceConfig ) ( * DualDevice , error ) {
86
+ // Create the first device
87
+ dev1 , err := New ( config . DeviceConfig )
88
+ if err != nil {
89
+ return nil , err
42
90
}
43
- dual .devices [1 ] = Device {
44
- pins : [4 ]machine.Pin {pin5 , pin6 , pin7 , pin8 },
45
- stepDelay : 60000000 / (steps * rpm ),
91
+ // Create the second device
92
+ config .DeviceConfig .Pin1 = config .Pin5
93
+ config .DeviceConfig .Pin2 = config .Pin6
94
+ config .DeviceConfig .Pin3 = config .Pin7
95
+ config .DeviceConfig .Pin4 = config .Pin8
96
+ dev2 , err := New (config .DeviceConfig )
97
+ if err != nil {
98
+ return nil , err
46
99
}
47
- return dual
100
+ // Return composite dual device
101
+ return & DualDevice {devices : [2 ]* Device {dev1 , dev2 }}, nil
48
102
}
49
103
50
104
// Configure configures the pins of the DualDevice
@@ -64,7 +118,7 @@ func (d *Device) Move(steps int32) {
64
118
var s int32
65
119
d .stepMotor (d .stepNumber )
66
120
for s = int32 (d .stepNumber ); s < steps ; s ++ {
67
- time .Sleep (time . Duration ( d .stepDelay ) * time . Microsecond )
121
+ time .Sleep (d .stepDelay )
68
122
d .moveDirectionSteps (direction , s )
69
123
}
70
124
}
@@ -101,7 +155,7 @@ func (d *DualDevice) Move(stepsA, stepsB int32) {
101
155
stepsA += int32 (d .devices [max ].stepNumber )
102
156
minStep = int32 (d .devices [min ].stepNumber )
103
157
for s := int32 (d .devices [max ].stepNumber ); s < stepsA ; s ++ {
104
- time .Sleep (time . Duration ( d .devices [0 ].stepDelay ) * time . Microsecond )
158
+ time .Sleep (d .devices [0 ].stepDelay )
105
159
d .devices [max ].moveDirectionSteps (directions [max ], s )
106
160
107
161
if ((s * stepsB ) / stepsA ) > minStep {
@@ -119,6 +173,18 @@ func (d *DualDevice) Off() {
119
173
120
174
// stepMotor changes the pins' state to the correct step
121
175
func (d * Device ) stepMotor (step uint8 ) {
176
+ switch d .stepMode {
177
+ default :
178
+ fallthrough
179
+ case ModeFour :
180
+ d .stepMotor4 (step )
181
+ case ModeEight :
182
+ d .stepMotor8 (step )
183
+ }
184
+ }
185
+
186
+ // stepMotor4 changes the pins' state to the correct step in 4-step mode
187
+ func (d * Device ) stepMotor4 (step uint8 ) {
122
188
switch step {
123
189
case 0 :
124
190
d .pins [0 ].High ()
@@ -148,13 +214,63 @@ func (d *Device) stepMotor(step uint8) {
148
214
d .stepNumber = step
149
215
}
150
216
217
+ // stepMotor8 changes the pins' state to the correct step in 8-step mode
218
+ func (d * Device ) stepMotor8 (step uint8 ) {
219
+ switch step {
220
+ case 0 :
221
+ d .pins [0 ].High ()
222
+ d .pins [2 ].Low ()
223
+ d .pins [1 ].Low ()
224
+ d .pins [3 ].Low ()
225
+ case 1 :
226
+ d .pins [0 ].High ()
227
+ d .pins [2 ].High ()
228
+ d .pins [1 ].Low ()
229
+ d .pins [3 ].Low ()
230
+ case 2 :
231
+ d .pins [0 ].Low ()
232
+ d .pins [2 ].High ()
233
+ d .pins [1 ].Low ()
234
+ d .pins [3 ].Low ()
235
+ case 3 :
236
+ d .pins [0 ].Low ()
237
+ d .pins [2 ].High ()
238
+ d .pins [1 ].High ()
239
+ d .pins [3 ].Low ()
240
+ case 4 :
241
+ d .pins [0 ].Low ()
242
+ d .pins [2 ].Low ()
243
+ d .pins [1 ].High ()
244
+ d .pins [3 ].Low ()
245
+ case 5 :
246
+ d .pins [0 ].Low ()
247
+ d .pins [2 ].Low ()
248
+ d .pins [1 ].High ()
249
+ d .pins [3 ].High ()
250
+ case 6 :
251
+ d .pins [0 ].Low ()
252
+ d .pins [2 ].Low ()
253
+ d .pins [1 ].Low ()
254
+ d .pins [3 ].High ()
255
+ case 7 :
256
+ d .pins [0 ].High ()
257
+ d .pins [2 ].Low ()
258
+ d .pins [1 ].Low ()
259
+ d .pins [3 ].High ()
260
+ }
261
+ d .stepNumber = step
262
+ }
263
+
151
264
// moveDirectionSteps uses the direction to calculate the correct step and change the motor to it.
152
- // Direction true: 0, 1, 2, 3, 0, 1, 2, ...
153
- // Direction false: 0, 3, 2, 1, 0, 3, 2, ...
265
+ // Direction true: (4-step mode) 0, 1, 2, 3, 0, 1, 2, ...
266
+ // Direction false: (4-step mode) 0, 3, 2, 1, 0, 3, 2, ...
267
+ // Direction true: (8-step mode) 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, ...
268
+ // Direction false: (8-step mode) 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, ...
154
269
func (d * Device ) moveDirectionSteps (direction bool , step int32 ) {
270
+ modulus := int32 (d .stepMode .stepCount ())
155
271
if direction {
156
- d .stepMotor (uint8 (step % 4 ))
272
+ d .stepMotor (uint8 (step % modulus ))
157
273
} else {
158
- d .stepMotor (uint8 ((step + 2 * ( step % 2 )) % 4 ))
274
+ d .stepMotor (uint8 ((( - step % modulus ) + modulus ) % modulus ))
159
275
}
160
276
}
0 commit comments