from time import ticks_us,ticks_cpu
import time
from machine import Pin
class Stepper():
def __init__(self,stepPin,directionPin,enablePin):
self.stepPin = Pin(stepPin,Pin.OUT)
self.directionPin = Pin(directionPin,Pin.OUT)
self.enablePin = Pin(enablePin,Pin.OUT)
self.done = True
self.debugModeFlag = False
self.stepsToGo = 0
self.stepsGone = 0
self.acceleration = 0.00
self.stepTime = 0.00
self.starttime = 0.00
self.stage1 = 0.00
self.stage2 = 0.00
self.stage1StepTime = 0.00
self.stage3StepTime = 0.00
self.nextStepTime = 0.00
self.now_time = 0.00
self.nextTimestamp = 0.00
def startup(self):
self.enablePin.value(0)
def shutdown(self):
self.enablePin.value(1)
def stop(self):
self.stepsToGo = 0
self.done = True
def isDown(self):
return self.done
def rotate_init(self,speed,steps,acceleration,accelerationstep): #旋轉參數初始化函數
if (speed != 0 and steps != 0):
if (steps > 0):
self.directionPin.value(1)
else:
self.directionPin.value(0)
self.done = False
self.stepsToGo = abs(steps)
self.acceleration = abs(acceleration)
if (self.stepsToGo <= 4):
self.acceleration = 0
self.stepTime = 1000.0 * 1000.0 / abs(speed)
self.startTime = self.stepTime * (self.acceleration + 1)
self.stage1 = accelerationstep
self.stage1StepTime = self.acceleration * self.stepTime / self.stage1
self.stage2 = self.stepsToGo-accelerationstep
self.stage3StepTime = self.acceleration * self.stepTime / (self.stepsToGo - self.stage2)
self.stepsGone = 0
self.now_time = ticks_us()
self.step()
def step(self):
if (self.stepsToGo > self.stepsGone):
self.stepPin.value(1)
time.sleep_us(1)
self.stepPin.value(0)
self.stepsGone += 1
self.nextStepTime = self.stepTime
if (self.acceleration != 0):
if (self.stepsGone < self.stage1):
self.nextStepTime = self.startTime - self.stage1StepTime * self.stepsGone
elif (self.stepsGone >= self.stage2):
self.nextStepTime = self.stepTime + self.stage3StepTime * (self.stepsGone - self.stage2 + 1)
self.nextTimestamp = ticks_us() + self.nextStepTime
else:
self.done = True
def run(self): #盡可能頻繁地執行run方法電機才會轉
if (not self.done and ticks_us() >= self.nextTimestamp):
self.step()
這個步進電機控制程式是我移植的一個大神的Arduino步進電機控制庫,整體的控制思路就是在run()函數中不斷的比較系統運作時間,如果時間到了就輸出一個脈沖并計算下一次脈沖輸出的時間,這個過程會一直循環執行,直到執行完畢。
這段程式通過Stepper()類可以執行個體化多個步進電機,因而支援多台步進電機同時控制。
這段程式初始化完成之後,正常運作時隻要保證盡可能頻繁的執行run()函數即可,而run()函數的執行時間非常小,是以程式中還可以內建一些其他耗時短的檢測功能和控制功能,可以極大地豐富系統功能。
這段程式控制步進電機的加減速過程是梯形的。
搭配Arduino UNO硬體直接使用原生的Arduino程式可以同時控制5個步進電機同時實作加減速運作,啟動過程平滑,絲毫沒有卡頓現象。
在ESP8266平台上,燒錄MicroPython固件,使用上面的步進電機控制程式,最多隻能控制3台步進電機同時運作,轉速稍高時會出現卡頓現象,我估計是ESP8266+Micropython的代碼執行速度跟不上導緻的,如果有條件可以試一下ESP32。