more drivers are now cross platform

This commit is contained in:
soypat
2025-07-02 22:03:58 -03:00
committed by deadprogram
parent 7d3404f060
commit cd37668592
20 changed files with 481 additions and 325 deletions
+55 -116
View File
@@ -1,10 +1,12 @@
//go:build baremetal
// Package easystepper provides a simple driver to rotate a 4-wire stepper motor.
package easystepper // import "tinygo.org/x/drivers/easystepper"
import (
"errors"
"machine"
"time"
"tinygo.org/x/drivers"
)
// StepMode determines the coil sequence used to perform a single step
@@ -30,28 +32,10 @@ func (sm StepMode) stepCount() uint {
}
}
// DeviceConfig contains the configuration data for a single easystepper driver
type DeviceConfig struct {
// Pin1 ... Pin4 determines the pins to configure and use for the device
Pin1, Pin2, Pin3, Pin4 machine.Pin
// StepCount is the number of steps required to perform a full revolution of the stepper motor
StepCount uint
// RPM determines the speed of the stepper motor in 'Revolutions per Minute'
RPM uint
// Mode determines the coil sequence used to perform a single step
Mode StepMode
}
// DualDeviceConfig contains the configuration data for a dual easystepper driver
type DualDeviceConfig struct {
DeviceConfig
// Pin5 ... Pin8 determines the pins to configure and use for the second device
Pin5, Pin6, Pin7, Pin8 machine.Pin
}
// Device holds the pins and the delay between steps
type Device struct {
pins [4]machine.Pin
pins [4]drivers.PinOutput
config func()
stepDelay time.Duration
stepNumber uint8
stepMode StepMode
@@ -62,51 +46,6 @@ type DualDevice struct {
devices [2]*Device
}
// New returns a new single easystepper driver given a DeviceConfig
func New(config DeviceConfig) (*Device, error) {
if config.StepCount == 0 || config.RPM == 0 {
return nil, errors.New("config.StepCount and config.RPM must be > 0")
}
return &Device{
pins: [4]machine.Pin{config.Pin1, config.Pin2, config.Pin3, config.Pin4},
stepDelay: time.Second * 60 / time.Duration((config.StepCount * config.RPM)),
stepMode: config.Mode,
}, nil
}
// Configure configures the pins of the Device
func (d *Device) Configure() {
for _, pin := range d.pins {
pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
}
}
// NewDual returns a new dual easystepper driver given 8 pins, number of steps and rpm
func NewDual(config DualDeviceConfig) (*DualDevice, error) {
// Create the first device
dev1, err := New(config.DeviceConfig)
if err != nil {
return nil, err
}
// Create the second device
config.DeviceConfig.Pin1 = config.Pin5
config.DeviceConfig.Pin2 = config.Pin6
config.DeviceConfig.Pin3 = config.Pin7
config.DeviceConfig.Pin4 = config.Pin8
dev2, err := New(config.DeviceConfig)
if err != nil {
return nil, err
}
// Return composite dual device
return &DualDevice{devices: [2]*Device{dev1, dev2}}, nil
}
// Configure configures the pins of the DualDevice
func (d *DualDevice) Configure() {
d.devices[0].Configure()
d.devices[1].Configure()
}
// Move rotates the motor the number of given steps
// (negative steps will rotate it the opposite direction)
func (d *Device) Move(steps int32) {
@@ -126,7 +65,7 @@ func (d *Device) Move(steps int32) {
// Off turns off all motor pins
func (d *Device) Off() {
for _, pin := range d.pins {
pin.Low()
pin(false)
}
}
@@ -187,28 +126,28 @@ func (d *Device) stepMotor(step uint8) {
func (d *Device) stepMotor4(step uint8) {
switch step {
case 0:
d.pins[0].High()
d.pins[1].Low()
d.pins[2].High()
d.pins[3].Low()
d.pins[0](true)
d.pins[1](false)
d.pins[2](true)
d.pins[3](false)
break
case 1:
d.pins[0].Low()
d.pins[1].High()
d.pins[2].High()
d.pins[3].Low()
d.pins[0](false)
d.pins[1](true)
d.pins[2](true)
d.pins[3](false)
break
case 2:
d.pins[0].Low()
d.pins[1].High()
d.pins[2].Low()
d.pins[3].High()
d.pins[0](false)
d.pins[1](true)
d.pins[2](false)
d.pins[3](true)
break
case 3:
d.pins[0].High()
d.pins[1].Low()
d.pins[2].Low()
d.pins[3].High()
d.pins[0](true)
d.pins[1](false)
d.pins[2](false)
d.pins[3](true)
break
}
d.stepNumber = step
@@ -218,45 +157,45 @@ func (d *Device) stepMotor4(step uint8) {
func (d *Device) stepMotor8(step uint8) {
switch step {
case 0:
d.pins[0].High()
d.pins[2].Low()
d.pins[1].Low()
d.pins[3].Low()
d.pins[0](true)
d.pins[2](false)
d.pins[1](false)
d.pins[3](false)
case 1:
d.pins[0].High()
d.pins[2].High()
d.pins[1].Low()
d.pins[3].Low()
d.pins[0](true)
d.pins[2](true)
d.pins[1](false)
d.pins[3](false)
case 2:
d.pins[0].Low()
d.pins[2].High()
d.pins[1].Low()
d.pins[3].Low()
d.pins[0](false)
d.pins[2](true)
d.pins[1](false)
d.pins[3](false)
case 3:
d.pins[0].Low()
d.pins[2].High()
d.pins[1].High()
d.pins[3].Low()
d.pins[0](false)
d.pins[2](true)
d.pins[1](true)
d.pins[3](false)
case 4:
d.pins[0].Low()
d.pins[2].Low()
d.pins[1].High()
d.pins[3].Low()
d.pins[0](false)
d.pins[2](false)
d.pins[1](true)
d.pins[3](false)
case 5:
d.pins[0].Low()
d.pins[2].Low()
d.pins[1].High()
d.pins[3].High()
d.pins[0](false)
d.pins[2](false)
d.pins[1](true)
d.pins[3](true)
case 6:
d.pins[0].Low()
d.pins[2].Low()
d.pins[1].Low()
d.pins[3].High()
d.pins[0](false)
d.pins[2](false)
d.pins[1](false)
d.pins[3](true)
case 7:
d.pins[0].High()
d.pins[2].Low()
d.pins[1].Low()
d.pins[3].High()
d.pins[0](true)
d.pins[2](false)
d.pins[1](false)
d.pins[3](true)
}
d.stepNumber = step
}
+83
View File
@@ -0,0 +1,83 @@
//go:build baremetal
package easystepper
import (
"errors"
"machine"
"time"
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
)
// New returns a new single easystepper driver given a DeviceConfig
func New(config DeviceConfig) (*Device, error) {
if config.StepCount == 0 || config.RPM == 0 {
return nil, errors.New("config.StepCount and config.RPM must be > 0")
}
return &Device{
pins: [4]drivers.PinOutput{config.Pin1.Set, config.Pin2.Set, config.Pin3.Set, config.Pin4.Set},
stepDelay: time.Second * 60 / time.Duration((config.StepCount * config.RPM)),
stepMode: config.Mode,
config: func() {
legacy.ConfigurePinOut(config.Pin1)
legacy.ConfigurePinOut(config.Pin2)
legacy.ConfigurePinOut(config.Pin3)
legacy.ConfigurePinOut(config.Pin4)
},
}, nil
}
// Configure configures the pins of the Device
func (d *Device) Configure() {
if d.config == nil {
panic(legacy.ErrConfigBeforeInstantiated)
}
d.config()
}
// Configure configures the pins of the DualDevice
func (d *DualDevice) Configure() {
d.devices[0].Configure()
d.devices[1].Configure()
}
// NewDual returns a new dual easystepper driver given 8 pins, number of steps and rpm
func NewDual(config DualDeviceConfig) (*DualDevice, error) {
// Create the first device
dev1, err := New(config.DeviceConfig)
if err != nil {
return nil, err
}
// Create the second device
config.DeviceConfig.Pin1 = config.Pin5
config.DeviceConfig.Pin2 = config.Pin6
config.DeviceConfig.Pin3 = config.Pin7
config.DeviceConfig.Pin4 = config.Pin8
dev2, err := New(config.DeviceConfig)
if err != nil {
return nil, err
}
// Return composite dual device
return &DualDevice{devices: [2]*Device{dev1, dev2}}, nil
}
// DeviceConfig contains the configuration data for a single easystepper driver
type DeviceConfig struct {
// Pin1 ... Pin4 determines the pins to configure and use for the device
Pin1, Pin2, Pin3, Pin4 machine.Pin
// StepCount is the number of steps required to perform a full revolution of the stepper motor
StepCount uint
// RPM determines the speed of the stepper motor in 'Revolutions per Minute'
RPM uint
// Mode determines the coil sequence used to perform a single step
Mode StepMode
}
// DualDeviceConfig contains the configuration data for a dual easystepper driver
type DualDeviceConfig struct {
DeviceConfig
// Pin5 ... Pin8 determines the pins to configure and use for the second device
Pin5, Pin6, Pin7, Pin8 machine.Pin
}
+26
View File
@@ -0,0 +1,26 @@
package easystepper
import (
"errors"
"time"
"tinygo.org/x/drivers"
)
func NewCrossPlatform(stepcount, rpm uint, mode StepMode, pins [4]drivers.PinOutput) (*Device, error) {
if stepcount == 0 || rpm == 0 {
return nil, errors.New("zero rpm and/or stepcount")
}
for i := range pins {
if pins[i] == nil {
return nil, errors.New("nil pin")
}
}
d := &Device{
pins: pins,
stepDelay: time.Second * 60 / time.Duration((stepcount * rpm)),
stepMode: mode,
config: func() {},
}
return d, nil
}