2017-07-07 91 views
0

我正在開發一個C++程序來與運行自動化系統的Arduino進行通信。我使用的是串行庫從這個:Arduino到C++串行讀取Gibberish [已解決]

https://playground.arduino.cc/Interfacing/CPPWindows

我試圖發送一個Arduino的字符串,它就會解析到一個命令,將告訴它系統應該如何移動。從串口讀取命令的代碼是這樣的:

'無效的serialEvent(){

while (Serial.available()) { 
    char in = (char)Serial.read(); 
    input.concat(in); 
    } 
    int endChar = input.indexOf('\r'); 
    if (endChar != -1) { 
    //inputLog.concat(input); 
    //inputLog.concat('\n'); 
    String command = input.substring(0,endChar); 
    command.toLowerCase(); 
    input.remove(0, endChar+1); 
    String keyword = command.substring(0,4); 
    if(keyword == "move"){ 
      int i = command.indexOf('x'); 
      if (i != -1) { 
      endChar = command.indexOf(i, ','); 
      xMove = command.substring(i + 1, endChar).toFloat(); 
      } 
      i = command.indexOf('y'); 
      if (i != -1) { 
      endChar = command.indexOf(i, ','); 
      yMove = command.substring(i + 1, endChar).toFloat(); 
      } 
    } else if (keyword == "stop") { 
     xMove = 0; 
     yMove = 0; 
    } else if (keyword == "xpos") { 
     Serial.print("X: "); 
     Serial.println(xPos); 
    } else if (keyword == "ypos") { 
     Serial.print("Y: "); 
     Serial.println(yPos); 
    } else if (keyword == "getp") { 
     Serial.print("X: "); 
     Serial.print(xPos); 
     Serial.print(", Y: "); 
     Serial.println(yPos); 
    } else if (keyword == "setx") { 
     xPos = command.substring(4).toFloat(); 
    } else if (keyword == "sety") { 
     yPos = command.substring(4).toFloat(); 
    } else if (keyword == "setp") { 
     int i = command.indexOf('x'); 
      if (i != -1) { 
      endChar = command.indexOf(i, ','); 
      xPos = command.substring(i + 1, endChar).toFloat(); 
      } 
      i = command.indexOf('y'); 
      if (i != -1) { 
      endChar = command.indexOf(i, ','); 
      yPos = command.substring(i + 1, endChar).toFloat(); 
      } 
    } else if (keyword == "getl") { 
     Serial.println(inputLog); 
     inputLog = ""; 
    } else { 
     Serial.println("error: 1"); 
     return; 
    } 
    Serial.println("ok\r"); 
    //Serial.print(nc); 
    } 

}`

這部分似乎運行正常,因爲我可以與運行Arduino串行監視器,它的工作原理。這裏是我在C++編寫的代碼的一個簡短的測試:

while (SP->IsConnected()) 
{ 
    string outputData = ""; 
    cin >> outputData; 
    outputData.append(pcr); 
    //outputData.append(pnc); 
    writeResult = SP->WriteData((char*)outputData.c_str(), outputData.length()); 
    //writeResult = writeResult && SP->WriteData(pnc, 1); 
    //writeResult = writeResult & SP->WriteData(pcr, 1); 

    while (true) { 
     Sleep(500); 
     char incomingData[256] = ""; 
     readResult = SP->ReadData(incomingData, dataLength); 
     //printf("Bytes read: (0 means no data available) %i\n", readResult); 
     //incomingData[readResult] = 0; 
     input.append(incomingData, 0, readResult); 

     check_ok = input.find(pcr); 
     check_error = input.find(error); 

     if (check_ok != string::npos || check_error != string::npos || readResult == 0) { 
      cout << "Receiving: " << input << '\n'; 
      input.clear(); 
      break; 
     } 
    } 
} 

變量,PCR是先前在代碼定義爲一個指針到回車符,其Arduino的用來識別一個命令的結束。我運行這段代碼的結果是,Arduino似乎讀取了第一條命令並執行它;然而,它也讀取了幾個亂碼字符,其中大部分等同於-52作爲數字值。任何下面的命令似乎都沒有做任何事情,並且arduino繼續得到亂碼字符。另外,似乎C++中的ReadData函數工作正常。有誰知道爲什麼發生這種情況? Arduino的串行緩衝區是否被WriteData函數破壞了?

編輯:

我似乎找到了問題。語句outputData(pcr)需要爲outputData(pcr,0,1),因爲指針不是空終止。因此該字符串正在附加額外的字符,直到它到達空字符。感謝您的評論和答覆。

+0

您是否正確設置了串口?正確的波特率,結束字符,這樣的東西?通常情況下,輸出到串行監視器的亂碼意味着波特率不好。 –

+0

不,它的波特率不錯。它仍然讀出它應該一致的一切。它只是增加了我發送arduino的數據結尾的亂碼。 –

+0

好的,那很好。您是否檢查過並確保停止位,奇偶校驗和換行符正確配置? –

回答

0

你的數據線有多長? 您是否使用TTL級別發送數據? 如果您的線路長度超過幾米,並且您正在使用TTL電平通信(設備之間直接佈線),那麼您肯定會收到來自其他設備的垃圾。長線通信線應該使用RS232或RS485,這是專門爲它設計的。