|
明示? 程式幫你寫嗎? 如果教你做法,頂多是暗示
站內找找有關 millis() 的程式問題,大多有提到解法
程式是照順序跑的,你喊停( delay() )系統當然停住,
在停住的當下啥事都不會幹等停完再說,然後一個二個
for 迴圈、迴圈裏頭喊停,那還不變慢?
用 millis() 不是直接喊停,而是去判斷時間到了沒?
時間還沒到那其他程式繼續跑,等時間到了才去做
喊停之後的事,就以你的程式來說
void duoji(){
for(pos = 0; pos < 180; pos += 1)
{
myservo.write(pos);
delay(15);
}
for(pos = 180; pos>=1; pos-=1)
{
myservo.write(pos);
delay(15);
}
}
只要一進 douji() 就不得了了,0~179=180*15
=2700ms,再來一個 180~1=180*15=2700ms,
扣掉舵機控制用掉的時間不講,光 delay 就用掉
5400ms,只要進來副程式一次就是5.4秒的浪費,
這 5.4 秒內你只能看著舵機努力地轉動,但其他
程式完全停擺(除非你動用中斷,但最後結果應該是
中斷溢位,也是沒救)
改用 millis() 就不一樣囉,但程式架構就不能像
原先那樣寫,你必須設立旗標或變數來記憶有關
舵機轉動的事你做到哪邊了,下次再回來副程式中
就直接接著先前的事做
比方說我做個全域旗標 servo_run 表示進行
舵機旋轉控制,弄個全域變數pos 來記錄0~359
360 個舵機角度動作,pos=0~179 時正轉(角度值=
pos),pos=180~359 時反轉(角度值=360-pos)
當我要控制舵機時,設立 pos=0; servo_run=true;
主程式一看到這個旗標就無條件呼叫 douji() 副程式,
一進 douji() 就依照 pos 值控制舵機旋轉,同時記錄
millis()現在值,然後副程式返回做其他工作
在主程式中判斷當 servo_run=true; &&目前時間值-
記錄時間值>=15 時,pos++,再呼叫 douji() 副程式
進行舵機旋轉、記錄新時間值、回到主程式,若時間還
沒到就先不管繼續進行主程式其他工作
當 pos++ 後=360 時就自清,servo_run=false;
這樣副程式就不會再被呼叫了,若是要舵機無限自轉,
那就不要清 servo_run 旗標,而是清 pos 的值=0,
就會從頭開始再轉了
接下來你可以把其他 delay(); 也一樣改成用 millis();
那你的程式反應就會很快了,這樣說,很接近明示了吧?
|
|