2012-09-17 141 views
1

我在使用兩個帶有arduino板的軟件串行端口從兩個傳感器獲取數據時遇到了問題。我注意到一個類似的問題可能之前已經問過,但答案表明它不能完成,我完全清楚它可以基於這裏的示例(http://arduino.cc/en/Tutorial/TwoPortReceive)!在Arduino上使用軟件串口接收兩個端口

我正在使用arduino以太網。我試圖從中獲取數據的設備包括來自sparkfun的GPS和IMU。

我可以從任何設備上使用軟件串行端口獲取數據,但只要添加第二個軟件串行端口,兩個端口都不會工作。我無法使用硬件串行端口,因爲它正在被其他設備使用。

我的代碼是完全同樣的例子:

#include <SoftwareSerial.h> 

SoftwareSerial portOne(7,8); 
SoftwareSerial portTwo(5,6); 

void setup() 
{ 
    Serial.begin(9600); 


    portOne.begin(9600); 
    portTwo.begin(9600); 
} 

void loop() 
{ 

    portOne.listen(); 
    while (portOne.available() > 0) { 
    char inByte = portOne.read(); 
    Serial.write(inByte); 
    } 

    delay(500); 

    portTwo.listen(); 
    while (portTwo.available() > 0) { 
    char inByte = portTwo.read(); 
    Serial.write(inByte); 
    } 

    Serial.println(); 
} 

有任何想法嗎?

+0

燦你給我們提供了有關它不起作用的更多信息嗎? – Jeff

+0

我以某種方式得到它的工作,你必須設置引腳狀態,即接收引腳作爲輸入和傳輸引腳作爲輸出。 – Dyps

回答

1

引用的示例一次只能主動監聽一個端口。推薦的解決方案是升級到具有4個硬件串行端口的Arduino Mega(https://www.sparkfun.com/products/11061)。

爲了同時支持兩個軟件串口需要大量的CPU資源。這也是一個困難的設計和過多的編程時間,遠遠超過58美元+運輸的成本。

再次看着你的代碼,我發現你立即檢查你的portOne.listen命令後的字符。在9600波特時,第一個字符到達需要大約1ms,你的while測試已經完成,並且portTwo.listen命令在第一個字符到達之前就已經執行了。

出於測試目的,請嘗試在portOne.listen命令之後添加1-2 ms的延遲並查看是否有字符。

作爲一個例子(未經測試和注意,如果端口的一個不與任何字符間的間隙發送的字符,所述第一而永遠不會失敗,防止讀取portTwo字符):

void loop() 
{ 

    portOne.listen(); 
    delay(2); 
    while (portOne.available() > 0) { 
     char inByte = portOne.read(); 
     Serial.write(inByte); 
     delay(1); 
    } 

    portTwo.listen(); 
    delay(2); 
    while (portTwo.available() > 0) { 
     char inByte = portTwo.read(); 
     Serial.write(inByte); 
     delay(1); 
    } 
    Serial.println(); 
} 
+0

你是說,上面的代碼不起作用?我一次只能在一個端口上收聽。 – Dyps

+0

我應該說我沒有試過這樣做。只要你打開端口1,接收數據,關閉端口1,打開端口2,接收數據,關閉端口2,然後重複,我就會工作。它仍然會使用更多的微型資源,然後使用兩個硬件端口,但取決於微載和其他固件,這可能不是問題。 – Jeff

3

此代碼將無法正常工作,或如果它工作的話,它的效果會很差。 SoftwareSerial只有一個內部緩衝區。是的,您可以擁有多個SoftwareSerial對象,但其中只有一個控制內部緩衝區。當任何RX引腳被置位時,會產生一箇中斷,但只有listen()的RX引腳被檢測到一個起始位。

真正需要的是在中斷從起始位出現時檢查多個引腳的能力。然後你必須設置指向適當數據結構的指針。這將是複雜的,但可能的。或者只是放棄中斷驅動的接收,然後旋轉檢查兩個/所有的RX引腳,然後根據您看到的引腳開始接收。應該警告說,這段代碼有很多頭髮,你需要一臺示波器才能使它工作。

我有類似的問題,這就是爲什麼我找到了你的傳感器。在與我的同事交談之後,我們決定按循環順序閱讀我們的傳感器。我們的傳感器報告傳感器的當前狀態,而不是特定的事件,所以如果我們丟失了一些報告就沒關係。因此,我們將從端口1讀取數據,然後從端口2讀取數據,然後從端口1讀取數據。我們的傳感器會吐出一行文字,因此我們知道何時切換到下一個傳感器。

+1

感謝您的回答。您能否提供一些代碼來演示您的旋轉訂單概念? – Dyps

0

不要使用,而......

用途:

{  portOne.listen(); 

    if (PortOne.available()) { 
     ricevo = myPort1.read(); } 

    // delay(2); // ridiculos waiting time 
    // delay(1); // extra ridiculos waiting time 

超過500毫秒是一個太大的時間切換,沒有時間.....