Robofun 機器人論壇

標題: 請問有關Arduino 停止傳送脈波的問題 [打印本頁]

作者: adolclistin    時間: 2017-10-6 19:41
標題: 請問有關Arduino 停止傳送脈波的問題
本帖最後由 adolclistin 於 2017-10-6 19:59 編輯

各位前輩 大家好

我使用Arduino 來控制步進馬達

使用的回圈如下:

inline void microWaitUntil(unsigned long target_micros){
    yield();
    while (micros() < target_micros);
}

void loop() {

     digitalWrite(MOTOR_STEP, HIGH);        //送高電位
     unsigned long next_edge = micros() + pulse_duration;
     microWaitUntil(next_edge);                        //delay
     digitalWrite(MOTOR_STEP, LOW);        //送低電位
     microWaitUntil(next_edge + pulse_duration);        //delay
     
}

在loop中的函式是不斷的送出脈波。
其中  pulse_duration是需要delay的時間。

現在有一個問題,在執行時,有一定的機率arduino會停止送脈波,也就是loop內沒有在工作。

初步測試,我們使用外部中斷來進行測試發現,arduino 是有回應的,所以可以排除arduino當掉的問題。


煩請大大給予指教。

謝謝!
作者: 超新手    時間: 2017-10-6 21:19
micros 大約 70 分鐘就會溢位
如果在溢位時,就有機率產生bug
例如 next_edge計算等於
0xffffffff(或接近也會)
但是等到真正呼叫 micros 時
已經溢位從 0 重新數
就會變成
while(micros()<0xffffffff)
可能要下次 70分才出的來
(也可能永遠卡死)
作者: 超新手    時間: 2017-10-7 06:48
另外,這個 yield 的作用是?
如果程式有用到 scheduler
就可能會卡在另一個程式中
作者: adolclistin    時間: 2017-10-7 14:34
很感謝 超新手大大的說明

我昨天發問完後,就先測試了先將yield拿掉,經過12小時的運轉是沒有問題的,也只能說剛剛好沒有問題。
今天又再開一次,進行第二輸的測試。

看了超新手大大的回覆之後,我一直上網找看看是否有reset的方式,只找到millis這個函數的reset。

在下想說是不是用 long long這個資料型態來接micros()這個函數,讓相減之後產生負數來跳脫迴圈,
或是改用delayMicroseconds()來進行暫停的動作。


作者: 超新手    時間: 2017-10-7 15:16
可以用
unsigned long d;
unsigned long p=micros();
do{
d=micros()-p;
}while(d<duration);
這樣即使溢位,也沒問題
而且其實也不必宣告到 unsigned long
只要時間來的及即可,如 unsigned int
(或更小)
速度會快一點
但注意所有變數要一致
作者: adolclistin    時間: 2017-10-11 17:15
先感謝超新手回答。

這幾天我嘗試了delayMicroseconds(),並用土法練鋼的方法找到相對應的轉速。
早知道就先上來讀您的回覆了。

您的方法很好,我接下來再進行測試。

再次感謝!





歡迎光臨 Robofun 機器人論壇 (https://robofun.net/forum/) Powered by Discuz! X3.2