gobot.io/x/gobot/v2@v2.1.0/drivers/gpio/motor_driver.go (about) 1 package gpio 2 3 import ( 4 "gobot.io/x/gobot/v2" 5 ) 6 7 // MotorDriver Represents a Motor 8 type MotorDriver struct { 9 name string 10 connection DigitalWriter 11 SpeedPin string 12 SwitchPin string 13 DirectionPin string 14 ForwardPin string 15 BackwardPin string 16 CurrentState byte 17 CurrentSpeed byte 18 CurrentMode string 19 CurrentDirection string 20 } 21 22 // NewMotorDriver return a new MotorDriver given a DigitalWriter and pin 23 func NewMotorDriver(a DigitalWriter, speedPin string) *MotorDriver { 24 return &MotorDriver{ 25 name: gobot.DefaultName("Motor"), 26 connection: a, 27 SpeedPin: speedPin, 28 CurrentState: 0, 29 CurrentSpeed: 0, 30 CurrentMode: "digital", 31 CurrentDirection: "forward", 32 } 33 } 34 35 // Name returns the MotorDrivers name 36 func (m *MotorDriver) Name() string { return m.name } 37 38 // SetName sets the MotorDrivers name 39 func (m *MotorDriver) SetName(n string) { m.name = n } 40 41 // Connection returns the MotorDrivers Connection 42 func (m *MotorDriver) Connection() gobot.Connection { return m.connection.(gobot.Connection) } 43 44 // Start implements the Driver interface 45 func (m *MotorDriver) Start() (err error) { return } 46 47 // Halt implements the Driver interface 48 func (m *MotorDriver) Halt() (err error) { return } 49 50 // Off turns the motor off or sets the motor to a 0 speed 51 func (m *MotorDriver) Off() (err error) { 52 if m.isDigital() { 53 err = m.changeState(0) 54 } else { 55 err = m.Speed(0) 56 } 57 return 58 } 59 60 // On turns the motor on or sets the motor to a maximum speed 61 func (m *MotorDriver) On() (err error) { 62 if m.isDigital() { 63 err = m.changeState(1) 64 } else { 65 if m.CurrentSpeed == 0 { 66 m.CurrentSpeed = 255 67 } 68 err = m.Speed(m.CurrentSpeed) 69 } 70 return 71 } 72 73 // Min sets the motor to the minimum speed 74 func (m *MotorDriver) Min() (err error) { 75 return m.Off() 76 } 77 78 // Max sets the motor to the maximum speed 79 func (m *MotorDriver) Max() (err error) { 80 return m.Speed(255) 81 } 82 83 // IsOn returns true if the motor is on 84 func (m *MotorDriver) IsOn() bool { 85 if m.isDigital() { 86 return m.CurrentState == 1 87 } 88 return m.CurrentSpeed > 0 89 } 90 91 // IsOff returns true if the motor is off 92 func (m *MotorDriver) IsOff() bool { 93 return !m.IsOn() 94 } 95 96 // Toggle sets the motor to the opposite of it's current state 97 func (m *MotorDriver) Toggle() (err error) { 98 if m.IsOn() { 99 err = m.Off() 100 } else { 101 err = m.On() 102 } 103 return 104 } 105 106 // Speed sets the speed of the motor 107 func (m *MotorDriver) Speed(value byte) (err error) { 108 if writer, ok := m.connection.(PwmWriter); ok { 109 m.CurrentMode = "analog" 110 m.CurrentSpeed = value 111 return writer.PwmWrite(m.SpeedPin, value) 112 } 113 return ErrPwmWriteUnsupported 114 } 115 116 // Forward sets the forward pin to the specified speed 117 func (m *MotorDriver) Forward(speed byte) (err error) { 118 err = m.Direction("forward") 119 if err != nil { 120 return 121 } 122 err = m.Speed(speed) 123 if err != nil { 124 return 125 } 126 return 127 } 128 129 // Backward sets the backward pin to the specified speed 130 func (m *MotorDriver) Backward(speed byte) (err error) { 131 err = m.Direction("backward") 132 if err != nil { 133 return 134 } 135 err = m.Speed(speed) 136 if err != nil { 137 return 138 } 139 return 140 } 141 142 // Direction sets the direction pin to the specified speed 143 func (m *MotorDriver) Direction(direction string) (err error) { 144 m.CurrentDirection = direction 145 if m.DirectionPin != "" { 146 var level byte 147 if direction == "forward" { 148 level = 1 149 } else { 150 level = 0 151 } 152 err = m.connection.DigitalWrite(m.DirectionPin, level) 153 } else { 154 var forwardLevel, backwardLevel byte 155 switch direction { 156 case "forward": 157 forwardLevel = 1 158 backwardLevel = 0 159 case "backward": 160 forwardLevel = 0 161 backwardLevel = 1 162 case "none": 163 forwardLevel = 0 164 backwardLevel = 0 165 } 166 err = m.connection.DigitalWrite(m.ForwardPin, forwardLevel) 167 if err != nil { 168 return 169 } 170 err = m.connection.DigitalWrite(m.BackwardPin, backwardLevel) 171 if err != nil { 172 return 173 } 174 } 175 return 176 } 177 178 func (m *MotorDriver) isDigital() bool { 179 return m.CurrentMode == "digital" 180 } 181 182 func (m *MotorDriver) changeState(state byte) (err error) { 183 m.CurrentState = state 184 if state == 1 { 185 m.CurrentSpeed = 255 186 } else { 187 m.CurrentSpeed = 0 188 } 189 if m.ForwardPin != "" { 190 if state == 1 { 191 err = m.Direction(m.CurrentDirection) 192 if err != nil { 193 return 194 } 195 if m.SpeedPin != "" { 196 err = m.Speed(m.CurrentSpeed) 197 if err != nil { 198 return 199 } 200 } 201 } else { 202 err = m.Direction("none") 203 } 204 } else { 205 err = m.connection.DigitalWrite(m.SpeedPin, state) 206 } 207 208 return 209 }