延續上一篇
米免積木卡車改裝 <機構部份>
今天來看看 Arduino的程式碼
首先,所有程式碼如下:
#include <Servo.h>
const int dirServoCenter = 80;
const int dirServoGap = 40;
const int runServoStop = 111;
const int runServoGap = 80;
const int stepPin[4] = {4, 5, 6, 7};
Servo runServo;
Servo dirServo;
int stepRunFlag = 0;
int stepIndex = 0;
int delayCnt = 0;
void setup() {
runServo.attach(8);
dirServo.attach(9);
runServo.write(runServoStop);
dirServo.write(dirServoCenter);
Serial.begin(9600);
for(int i = 0; i < 4; i++)
{
pinMode(stepPin[i], OUTPUT);
digitalWrite(stepPin[i], LOW);
}
stepRunFlag = 0;
stepIndex = 0;
delayCnt = 0;
}
void loop() {
if(Serial.available())
{
char recvData = Serial.read();
switch(recvData)
{
case 'F' : {
runServo.write(runServoStop + runServoGap);
break;}
case 'B' : {
runServo.write(runServoStop - runServoGap);
break;}
case 'S' : {
runServo.write(runServoStop);
break;}
case 'R' : {
dirServo.write(dirServoCenter - dirServoGap);
break;}
case 'L' : {
dirServo.write(dirServoCenter + dirServoGap);
break;}
case 'C' : {
dirServo.write(dirServoCenter);
break;}
case 'U' : {
stepRunFlag = 1;
break;}
case 'D' : {
stepRunFlag = 2;
break;}
case 'P' : {
stepRunFlag = 0;
break;}
}
}
if(stepRunFlag > 0)
{
if(delayCnt >= 49)
{
delayCnt = 0;
if(stepRunFlag == 1)
{
if(stepIndex >= 3) stepIndex = 0;
else stepIndex ++;
}
else if(stepRunFlag == 2)
{
if(stepIndex <= 0) stepIndex = 3;
else stepIndex --;
}
for(int i = 0; i < 4; i++)
{
if(i == stepIndex) digitalWrite(stepPin[i], HIGH);
else digitalWrite(stepPin[i], LOW);
}
}
else delayCnt ++;
}
else
{
for(int i = 0; i < 4; i++)
{
digitalWrite(stepPin[i], LOW);
}
}
}
接下來我們一一來看這些程式碼到底在做什麼吧!
因為我們使用伺服馬達,所以要將這個函式庫給 include 進來,這樣就可以很方便的控制伺服馬達囉~
這邊定義一些固定的數值,方便程式中使用,若需變更時也不必於程式中多處修改,或是漏到某些沒有改到。
dirServoCenter 這個是定義方向控制的伺服馬達,正中間(不偏左也不偏右)時的控制傳入數值,這個數值須依實際情況修改
dirServoGap 則是左轉或右轉時,方向伺服馬達轉動的角度大小(此數值不是指角度,而是一個 由0~255的數字代表 0度~180度)
runServoStop 為控制前進、後退的伺服,停止時的參數(此伺服為連續運轉的型式,這個數值亦須依實際狀況修改)
runServoGap 為控制前進、後退的速度,數值越大,速度越快
stepPin[4] = {4 , 5, 6, 7} 定義步進馬達的接腳
建立兩個伺服,一個控制 前/後,另一個控制 左/右
宣告一些變數,其作用在下方用到的時侯一併說明
在這個 setup() 大括號裡的程式碼,會於單晶片啟動時(剛給電或重置時)執行一次
設定伺服使用的腳位
設定停止狀態的 前/後 伺服,及 左/右 伺服的參數值
設定串列傳輸的鮑率,用於和藍芽模組通訊
設定步進馬達使用的腳位,並將其設置為低電位(即沒有激磁,馬達為放鬆的狀態)
將變數初始化為 0
在這個 loop() 大括號裡的程式碼,會重覆不斷的執行
先判斷藍芽模組是否有接收到資料,有的話再將資料接收下來,放在 recvData 這個變數裡
看接收到的資料符合大括號裡的那一個 case,再做相對應的處理
這裡先判斷接收到的是否為字元 'F',代表接收到前進的指令,我們就將控制前/後的伺服參數更新為前進的數值
若為'B'則 代表後退,若為'S'代表停止,依指令更新參數
延續上面的判斷,接收到的字元為 'R'代表右轉,'L'代表左轉,'C'代表直行,依指令更新控制左/右轉的伺服的參數
再延續上面的判斷,接收到的字元為 'U'代表車斗上升,'D'代表車斗下降,'P'代表暫停動作,保持目前的狀態
這裡用到的變數 stepRunFlag 是存放目前車斗要做的動作的一個代碼,1代表上升,2代表下降,0代表不動作。這樣後面控制步進馬達動作的程式,即可依照這個代碼做相對應的動作
這裡開始處理步進馬達的動作
首先判斷 stepRunFlag 是否大於 0 ,代表要轉動步進馬達帶動車斗,可能上升,也可能是下降
再來因為如果依序給步進馬達轉動的太快,很容易發生失步,所以這裡我們使用 delayCnt 這個變數來計數,loop每執行50次,才讓步進馬達走一步,這個 delayCnt 的數字越大,步進馬達轉動的越慢
接著我們使用 stepIndex 這個變數來存放目前步進馬達驅動的腳位代碼,當判斷 stepRunFlag 等於1時(上升),將 stepIndex 依 0->1->2->3->0->1->2->3->0->1 ...... 這樣的順序改變;當判斷stepRunFlag 等於2時(下降),將 stepIndex 依 0->3->2->1->0->3->2->1->0->3 ...... 這樣的順序改變
最後使用一個 for 迴圈,讓變數 i 為 0~3 ,當 i 等於 stepIndex 時,將對應的步進馬達腳位輸出 HIGH,其餘的設為 LOW,這樣就能使步進馬達正轉或反轉
這個 else 是對應到上面的第一行 if(stepRunFlag > 0),即表示沒有要轉動步進馬達
這裡做的事是將步進馬達的四個腳位都設為LOW,此時步進馬達沒有溵磁,減少電流消耗
補充:
步進馬達的控制,也可以使用 Arduino 的函式庫,請參考 https://www.arduino.cc/en/reference/stepper
好了,以上所有的程式碼都講解了。至於手機端的APP如何創建呢?我們下一次談囉!
留言列表