範例程式
https://github.com/MarcoYang21/stepMotor/tree/master
//stepMotor.ino
// 此版本是用Arduino Uno R4 WiFi撰寫
// 用物件的寫法來控制步進馬達
// 這個範例只是轉動33度,不間斷往反運動。
#include "StepMotor.h" // 引入自定義的步進馬達控制頭文件
int rotateTime = 100; // 旋轉運動時間,單位毫秒
float targetAngle = 33; // 目標旋轉角度
const int PUL = 11; // 步進腳位
const int DIR = 12; // 正反轉控制腳位
const int EN = 13; // 致能腳位
StepMotor myMotor(DIR, EN, PUL); // 創建名為 myMotor 的 StepMotor 物件並初始化引腳
void setup() {
// 執行初始化
pinMode(PUL, OUTPUT); // 設定步進腳位為輸出模式
pinMode(DIR, OUTPUT); // 設定正反轉控制腳位為輸出模式
pinMode(EN, OUTPUT); // 設定致能腳位為輸出模式
myMotor.enable(); // 最初啟用電機
Serial.begin(115200); // 開啟串列通信
Serial.println("Ready"); // 顯示訊息,表示程式已就緒
}
void loop() {
myMotor.run(); // 啟動步進馬達運動
if (myMotor.isFinished()) {
// 旋轉後到設定位置後,才執行的程式碼
delay(200); // 延遲 200 毫秒
myMotor.reverseRotation(); // 反轉旋轉方向
myMotor.rotate(targetAngle, rotateTime); // 以指定角度和時間旋轉
}
// 其它需要一直被執行的工作
}
\\stepMotor.h
#ifndef StepMotor_h
#define StepMotor_h
#include <Arduino.h> // 引入 Arduino 標準庫
class StepMotor {
public:
StepMotor(int dirPin, int enaPin, int stpPin); // 類別建構函數,用於初始化步進馬達的引腳
void setDirection(int dir); // 設定步進馬達的運動方向
void enable(); // 啟用步進馬達
void disable(); // 停用步進馬達
void rotate(float degrees, unsigned long rotationTime); // 控制步進馬達旋轉到指定角度和時間
void reverseRotation(); // 反轉步進馬達的運動方向
bool isFinished(); // 檢查步進馬達是否已完成運動
void run(); // 開始步進馬達的運動
private:
int directionPin; // 步進馬達的方向控制引腳
int enablePin; // 步進馬達的啟用/停用控制引腳
int stepPin; // 步進馬達的步進引腳
int stepsPerRev; // 一個完整旋轉(360度)所需的步數
int targetSteps; // 目標步數
int currentStep; // 目前的步數
int stepDelay; // 步進間的時間延遲
int lastStepTime; // 最後一次輸出步進脈衝的時間
int rotationDirection; // 1 表示正向旋轉,-1 表示反向旋轉
bool pulseDirection; // 控制步進脈衝方向
bool isRunning; // 步進馬達是否正在運行
};
#endif
//stepMotor.cpp
#include "StepMotor.h"
#include <Arduino.h>
StepMotor::StepMotor(int dirPin, int enaPin, int stpPin) {
directionPin = dirPin; // 設定方向控制腳的引腳
enablePin = enaPin; // 設定啟用/停用控制腳的引腳
stepPin = stpPin; // 設定步進腳的引腳
isRunning = false; // 初始化為非運行狀態
rotationDirection = 1; // 初始為正向旋轉
stepsPerRev = 1600; // 一個完整旋轉(360度)所需的步數,看微步器的設定隨之改變
pulseDirection = true; // 起始脈衝方向為真(正向)
pinMode(directionPin, OUTPUT); // 設定方向控制腳為輸出模式
pinMode(enablePin, OUTPUT); // 設定啟用/停用控制腳為輸出模式
pinMode(stepPin, OUTPUT); // 設定步進腳為輸出模式
}
void StepMotor::setDirection(int dir) {
digitalWrite(directionPin, dir); // 設定方向控制腳的電位高低
rotationDirection = (dir == HIGH) ? 1 : -1; // 根據電位高低設定旋轉方向
}
void StepMotor::enable() {
digitalWrite(enablePin, LOW); // 啟用馬達
}
void StepMotor::disable() {
digitalWrite(enablePin, HIGH); // 停用馬達
}
void StepMotor::rotate(float degrees, unsigned long rotationTime) {
targetSteps = int((degrees / 360.0) * stepsPerRev); // 計算所需的步數
stepDelay = static_cast<double>(rotationTime) / targetSteps * 1000; // 計算每步之間的時間延遲
currentStep = 0; // 初始化當前步數
isRunning = true; // 設定為運行狀態
enable(); // 啟用馬達
}
void StepMotor::reverseRotation() {
rotationDirection = -rotationDirection; // 反轉旋轉方向
digitalWrite(directionPin, (rotationDirection == 1) ? HIGH : LOW); // 根據反轉方向設定方向控制腳
}
bool StepMotor::isFinished() {
return !isRunning; // 檢查是否完成運行
}
void StepMotor::run() {
if (isRunning) {
unsigned long currentTime = micros(); // 取得當前時間(微秒)
if (currentStep > targetSteps) {
isRunning = false; // 如果已完成所有步數,則設定為非運行狀態
} else {
if (currentTime - lastStepTime >= stepDelay) {
digitalWrite(enablePin, LOW); // 啟用馬達
digitalWrite(stepPin, pulseDirection); // 輸出步進脈衝
pulseDirection = !pulseDirection; // 切換脈衝方向
currentStep++; // 增加當前步數
lastStepTime = currentTime; // 更新最後一次輸出脈衝的時間
}
}
}
}