Robofun 機器人論壇

 找回密碼
 申請會員
搜索
熱搜: 活動 交友 discuz
查看: 2926|回復: 5
打印 上一主題 下一主題

請問有關Arduino 停止傳送脈波的問題

[複製鏈接]
跳轉到指定樓層
1#
發表於 2017-10-6 19:41:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最後由 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當掉的問題。


煩請大大給予指教。

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

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

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

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

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

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

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

再次感謝!
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

小黑屋|手機版|Archiver|機器人論壇 from 2005.07

GMT+8, 2024-11-21 20:59 , Processed in 0.137214 second(s), 6 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表