B4X 利用PulsePeriodModulation 控制直流馬達 轉速
(Arduino Uno)
#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: True
#StackBufferSize: 300
#End Region
Sub Process_Globals
Public Serial1 As Serial
Private MotorON = False As Boolean 'motor ON or OFF, ON = True
Private MotorDirection = False As Boolean 'motor direction
Private MotorSpeed = 0 As UInt
Private pinSwitchMotorONOFF, pinSwitchMotorDirection, pinMotorSpeed, pinMotorControl1, pinMotorControl2, pinPot As Pin
Private BounceTimeMotorON, BounceTimeMotorDirection As ULong
Private BounceDelay = 10 As ULong
Private MaxPulsePeriod = 500 As ULong 'Max PulsePeriod value
Private PulseWidth = 20 As ULong 'remains constant
Private PulsePeriod As ULong 'calculated in NextPulse
End Sub
Private Sub AppStart
Serial1.Initialize(115200)
Log("AppStart")
pinSwitchMotorONOFF.Initialize(pinSwitchMotorONOFF.A5, pinSwitchMotorONOFF.MODE_INPUT_PULLUP)
pinSwitchMotorONOFF.AddListener("pinSwitchMotorONOFF_StateChanged")
pinSwitchMotorDirection.Initialize(pinSwitchMotorONOFF.A3, pinSwitchMotorDirection.MODE_INPUT_PULLUP)
pinSwitchMotorDirection.AddListener("pinSwitchMotorDirection_StateChanged")
pinMotorControl1.Initialize(2, pinMotorControl1.MODE_OUTPUT)
pinMotorControl2.Initialize(3, pinMotorControl1.MODE_OUTPUT)
pinMotorSpeed.Initialize(10, pinMotorSpeed.MODE_OUTPUT)
pinPot.Initialize(pinPot.A1, pinPot.MODE_INPUT)
pinMotorControl1.DigitalWrite(MotorDirection)
pinMotorControl2.DigitalWrite(Not(MotorDirection))
End Sub
Private Sub pinSwitchMotorONOFF_StateChanged (State As Boolean)
If State = False Then
If Millis - BounceTimeMotorON < BounceDelay Then
Return
Else
MotorON = Not(MotorON)
If MotorON = True Then
NextPulse(0)
Else
pinMotorSpeed.AnalogWrite(0)
End If
BounceTimeMotorON = Millis
End If
Log("MotorON: ", MotorON)
End If
End Sub
Private Sub pinSwitchMotorDirection_StateChanged (State As Boolean)
' Log("StateON ", State)
If State = False Then
If Millis - BounceTimeMotorDirection < BounceDelay Then
Return
Else
MotorDirection = Not(MotorDirection)
pinMotorControl1.DigitalWrite(MotorDirection)
pinMotorControl2.DigitalWrite(Not(MotorDirection))
BounceTimeMotorDirection = Millis
End If
Log("MotorDirection: ", MotorDirection)
End If
End Sub
Private Sub NextPulse(Tag As Byte)
If MotorON = True Then
PulsePeriod = MapRange(pinPot.AnalogRead, 0, 1023, PulseWidth, MaxPulsePeriod)
Log(PulsePeriod)
If PulsePeriod >= MaxPulsePeriod - 1 Then
pinMotorSpeed.DigitalWrite(False)
Else If PulsePeriod <= PulseWidth + 1 Then
pinMotorSpeed.DigitalWrite(True)
Else
pinMotorSpeed.DigitalWrite(True)
CallSubPlus("EndPulse", PulseWidth, 0)
End If
CallSubPlus("EndPulse", PulseWidth, 0)
CallSubPlus("NextPulse", PulsePeriod, 0)
' Log("NextPulse") 'Log for testing
End If
End Sub
Private Sub EndPulse(Tag As Byte)
pinMotorSpeed.DigitalWrite(False) 'switch the LED OFF
' Log("EndPulse") 'Log for testing
End Sub
(ESP32-WROOM-32)
沒有留言:
張貼留言