|
发表于 2017-3-10 15:11:08
|
显示全部楼层
本帖最后由 Super169 于 2017-3-10 15:25 编辑
單看你的程式, 有幾個複雜的問題, 互相影響了, 真的不太肯定你收集到的結果, 會是什麼.
首先, 可能要看你的電機速度, 單從數字上推算:
20 線编码盘, CHANGE 的話, 一圈就有 40 個訊號.
5ms 以內不計算的, 一秒最多 200次, 即 5 圈左右.
換句話說, 只要你的電機, 超過 300rpm, 豈非就有問題了.
if((millis()-time3)>5) 不成立, 就不計算, 之後再把 time3 = millis()....豈非更有問題???
一般電機, 300rpm 會不會太慢了?
我反而奇怪, 如果你的電機超過 300rpm, 每次都少於 5ms, 豈非因為 ((millis()-time3)>5) 不成立, 而完全不作計算?
但又有另一個可能, 當速度未達 5ms 時, 執行 ((millis()-time3)>5) 成立.
之後的 Serial 輸出, 如果超過 5ms...單從輸出計算, 9600bps, 只要輸出 6 個 byte, 就要 5ms 了 (1/9600*8*5 = 0.005), 還沒有計算其他運算時間. 所以, 你每次在 ISP 內都要花上 5ms 以上. 本來應該要觸發另一次中斷了, 但因為之前的還未完成, 就被忽略了.
再者, 因為 millis() 在 ISP 內是停止的, 你最後用 time3=millis(), 那 time3 的值, 只會記下開始的時間, 那就已經是 5ms 之前的時間了. 如此下去, 每次都記下了 5ms 之前的時間, 當下次 ISP 執行時, ((millis()-time3)>5) 又變成自然成立了.
不過, Serial 是有 buffer 的, Serial.print 實際上不一定要用上幾個 ms, 在 ISP 內的運作會否有分別, 產生的 IO 是否會有點影響, 真的不知道. 所以 ISP 內實際所花的時間, 真的不太肯定. 但如果要每 5ms, 發出 "count=xx" 的訊息, 以 9600bps 是不能做到的, 應該會出現 overflow.
你的程式中, 混雜了 Serial.print 的耗時, millis() 的停止, 以及 電機速度的因素. 很難完全憑空想像 ((millis()-time3)>5) 的結果會變怎樣了. 以上全屬憑空推測, 太多不肯定的地方了.
所以, 我之前就建議你先把 millis() 及 Serial.print 的部份, 從 ISP 中移除, 再看看結果.
|
|