22package easystepper // import "tinygo.org/x/drivers/easystepper"
33
44import (
5+ "errors"
56 "machine"
67 "time"
78)
89
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+
952// Device holds the pins and the delay between steps
1053type Device struct {
1154 pins [4 ]machine.Pin
12- stepDelay int32
55+ stepDelay time. Duration
1356 stepNumber uint8
57+ stepMode StepMode
1458}
1559
1660// DualDevice holds information for controlling 2 motors
1761type DualDevice struct {
18- devices [2 ]Device
62+ devices [2 ]* Device
1963}
2064
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" )
2669 }
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
2775}
2876
2977// Configure configures the pins of the Device
@@ -34,17 +82,23 @@ func (d *Device) Configure() {
3482}
3583
3684// 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
4290 }
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
4699 }
47- return dual
100+ // Return composite dual device
101+ return & DualDevice {devices : [2 ]* Device {dev1 , dev2 }}, nil
48102}
49103
50104// Configure configures the pins of the DualDevice
@@ -64,7 +118,7 @@ func (d *Device) Move(steps int32) {
64118 var s int32
65119 d .stepMotor (d .stepNumber )
66120 for s = int32 (d .stepNumber ); s < steps ; s ++ {
67- time .Sleep (time . Duration ( d .stepDelay ) * time . Microsecond )
121+ time .Sleep (d .stepDelay )
68122 d .moveDirectionSteps (direction , s )
69123 }
70124}
@@ -101,7 +155,7 @@ func (d *DualDevice) Move(stepsA, stepsB int32) {
101155 stepsA += int32 (d .devices [max ].stepNumber )
102156 minStep = int32 (d .devices [min ].stepNumber )
103157 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 )
105159 d .devices [max ].moveDirectionSteps (directions [max ], s )
106160
107161 if ((s * stepsB ) / stepsA ) > minStep {
@@ -119,6 +173,18 @@ func (d *DualDevice) Off() {
119173
120174// stepMotor changes the pins' state to the correct step
121175func (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 ) {
122188 switch step {
123189 case 0 :
124190 d .pins [0 ].High ()
@@ -148,13 +214,63 @@ func (d *Device) stepMotor(step uint8) {
148214 d .stepNumber = step
149215}
150216
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+
151264// 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, ...
154269func (d * Device ) moveDirectionSteps (direction bool , step int32 ) {
270+ modulus := int32 (d .stepMode .stepCount ())
155271 if direction {
156- d .stepMotor (uint8 (step % 4 ))
272+ d .stepMotor (uint8 (step % modulus ))
157273 } else {
158- d .stepMotor (uint8 ((step + 2 * ( step % 2 )) % 4 ))
274+ d .stepMotor (uint8 ((( - step % modulus ) + modulus ) % modulus ))
159275 }
160276}
0 commit comments