#define MILLIS_PER_MIN 60000L //預設一分鐘是 60000 毫秒(理論值)
int delaytime = 3; //每步延遲時間(毫秒),數值越大,馬達轉動越慢、扭力越大
#define STEP_PER_ROTATION 2048 //馬達一圈所需的步數(常見 28BYJ-48 步進馬達是 2048 步/圈)
#define FORWARD_STEP ((STEP_PER_ROTATION * 2) / 5) //設定為一圈的 2/5,代表一次「推動」的主要旋轉量
int port[4] = {4, 5, 6, 7}; //ULN2003接到控制板的PIN
int seq[4][4] = {
{ LOW, LOW, HIGH, LOW},
{ LOW, LOW, LOW, HIGH},
{ HIGH, LOW, LOW, LOW},
{ LOW, HIGH, LOW, LOW}
}; //seq陣列→控制馬達相位的通電順序(4 相驅動模式)
void rotate(int step) { //馬達旋轉函式
static int phase = 0;
int i, j;
int delta = (step > 0) ? 1 : 3; //用來控制正反轉,+1是正轉;+3是反轉
int dt = 20;
step = (step > 0) ? step : -step;
for(j = 0; j < step; j++) {
phase = (phase + delta) % 4; //記錄馬達目前相位,取餘數
for(i = 0; i < 4; i++) {
digitalWrite(port[i], seq[phase][i]);
}
delay(dt);
if(step - j < 20) dt+=1; //延遲控制,有點像加速到定速,最後再減速停下來,避免震動
else if(dt > delaytime) dt--;
}
for(i = 0; i < 4; i++) { //切斷馬達電源
digitalWrite(port[i], LOW);
}
}
void setup() { //pin位初始化設定馬達接腳為輸出
pinMode(port[0], OUTPUT);
pinMode(port[1], OUTPUT);
pinMode(port[2], OUTPUT);
pinMode(port[3], OUTPUT);
rotate(-FORWARD_STEP / 4); // 啟動時先反轉 1/4,消除機械鬆動並初始化位置
}
void loop() {
static long prev_min = -1;
long min = millis() / MILLIS_PER_MIN; //計算目前過了多少分鐘(用 millis() 除以每分鐘的毫秒數)
if(prev_min == min)
return; //如果 min 沒變,就什麼都不做
rotate(FORWARD_STEP + FORWARD_STEP / 4); //馬達向前推動
rotate(-FORWARD_STEP / 3); // 輕微回退對位
rotate(20); // 小幅前進,釋放力矩
prev_min = min;
}
#include <WiFi.h>
WiFi.begin();
#if WIFI_SMARTCONFIG
if (WiFi.status() != WL_CONNECTED) {
WiFi.mode(WIFI_AP_STA);
WiFi.beginSmartConfig();
for(int i = 0; !WiFi.smartConfigDone(); i++) { //Wait for SmartConfig packet from mobile
delay(1000);
if(i > 300) { // 5 minutes
ESP.restart();
} }