2016-12-02 71 views
1

我有步進器在50的中斷計時器中步進,並讓我所有的代碼在中斷之間工作,直到我嘗試讀取長度超過一個字符的串行命令。如何在Arduino上的中斷之間讀取串行?

我得到了丟失的字節,所以我的字符串每4-5個字符就缺少一個字母。我一整天都在研究嘗試找出解決方案,但一無所獲。如果我不使用中斷,則我的步進器會以字符串形式讀取一個字符串行輸入,停止2秒鐘。

我的目標是有一個遙控應用程序發送速度命令。我需要幫助解決這個問題。

https://sourceforge.net/p/open-slider/code/ci/master/tree/OpenSliderFirmware/

String incomingString = ""; 
if (Serial.available() > 0) { 
    incomingString = Serial.readString(); 
    Serial.println(incomingString); 
} 

使用Accelstepper庫

中斷:

//Interrupt Timer1 
void ISR_stepperManager() { 
    Slide.runSpeed(); 
    Xaxis.runSpeed(); 
    Yaxis.runSpeed(); 
} 
+1

您使用的是軟件(bit-banged?)串口嗎?什麼是串行數據速率和步進中斷的速率? – barny

+0

中斷是50ms。串口0 USB上的波特率爲115200。最終,我將有一個軟件序列在針腳2和3上運行,我相信藍牙(如果我能弄明白的話) 我仍然試圖找到能夠解釋Marlin固件如何在同一時間可靠地完成步進和串行的人。馬林一次讀取1個字符,我將切換回所以它不會阻止其他事情。我以爲他們用中斷來驅動步進機,但我不再確定這一點。我使用的是2560和RAMPS。我對先進的東西還是一個新手。 – naps1saps

+0

您應該先嚐試降低串口波特率:115200波特大約是每個字節80微秒 - 所以如果您的步進中斷服務程序需要超過80us,您立即可能會丟失串行字符。嘗試9600波特(或更慢),即每個字節大約1毫秒。如果您不確定ISR需要多長時間並且有可用範圍,請在ISR開始時將ISR輸出端口設置爲1,並在末端設置爲0,然後查看脈衝寬度以及多少它有所不同。對於有點臃腫的你肯定不得不減慢串行數據速率。 – barny

回答

0

快速回答:如果中斷計時器太頻繁切換,則不需要。

我使用可變中斷計時器和步進乘法器解決了問題。基本上這些步驟在每次定時器中斷時調用,而不是在中斷函數中檢查millis。這解決了很多問題。現在步進器的速度由中斷計時器控制。這給了我更多的空閒週期來完全讀取傳入的串行而不會損壞並提高效率。每超過4k步/秒時,每個循環調用更多步驟也提高了效率,對於高速步驟而言需要更少的循環。

該序列每個週期處理一個字符以防止阻塞。總的來說,如果你使用串口和中斷定時器,發生任何中斷< 100us你應該謹慎在中斷期間你正在運行多少代碼。這將導致傳入串行和用戶輸入的問題。在25us定時器中斷中有幾行代碼,輸入串行將不起作用。

0

我不知道這是否會幫助你的問題,但我沿着時間的字符串看見類型在需要發生其他事情時不安全。 我更喜歡使用char數組並一次讀取一個字符。

while(Serial.available()) 
{ 
data[x] = Serial.read(); 
x++; 
} 

我發現它更可靠。

希望它的幫助!

+0

不幸的是,在我的代碼中使用它不會有什麼區別,因爲while循環會被定時器中斷中斷,這是我遇到的問題。 (還是)感謝你的建議。 – naps1saps