2016-12-22 310 views
0

我有下面的程序試圖用串口讀取arduino中的數據,事情大部分是不讀取任何東西,除了有時它讀取我發送的一塊。 arduino代碼只是在循環中寫一個字母。從串口讀取arduino C

#include <cstdio> 
#include <cstring> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <termios.h> 

int main() { 
    int serialfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 
    if (serialfd == -1) 
     perror("Error opening the serial port"); 
    else 
     fcntl(serialfd, F_SETFL, 0); 

    fprintf(stdout, "Device is open, attempting read \n"); 

    fcntl(serialfd, F_SETFL, 0); 
    char buf[11] = {0}; 
    read(serialfd, buf, 10); 
    fprintf(stdout, "Buffer: %s", buf); 
    close(serialfd); 
    return 0; 
} 

例如輸出是這樣

Device is open, attempting read 
Buffer: AAAAAAAAAAA⏎ 

如果我嘗試再次運行它(多次),我剛剛得到的0'd緩衝

Device is open, attempting read 
Buffer: ⏎     
+0

你沒有說*你重複發送哪個*單個字符。假設你有相應的波特率(沒有提及),並且你發送了'A',那麼在收到其中的11個之後,輸入緩衝區已滿並且沒有''\ 0''的零終止,所以你將一個not_string傳遞給'fprintf',因此不可避免地會輸出一些廢話。但請[閱讀此](http://stackoverflow.com/questions/34943745/why-fcntlfd-f-setfl-0-use-in-serial-port-programming)關於'F_SETFL'。 –

+0

@WeatherVane我在寫arduino的'A',我不知道如何用文件描述符設置波特率。 – Aram

+1

打開串行終端設備後,您必須先配置終端屬性,然後才能讀取或寫入。研究[設置終端模式來適當地(http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html#SEC237) 和[串行編程指南POSIX操作系統(HTTP: //www.cmrr.umn.edu/~strupp/serial.html)有關示例代碼,請參閱http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port -in-C/38318768#38318768和http://stackoverflow.com/questions/12437593/how-to-read-a-binary-data-over-serial-terminal-in-c-program/12457195#12457195 – sawdust

回答

2

這聽起來像配置問題,很可能波特率沒有正確設置。另外,如問題評論中所述,您可能會得到一個完整的緩衝區,最後沒有'\0'字符,因此fprintf的行爲不正確。

這裏我將解釋如何設置波特率,但您可以使用wikibooks鏈接我已經放下了答案來設置其他設置,也請確保檢查緩衝區。

簡單地說就是arduino,我喜歡用115200作爲我的波特率。 There are a few more that are usually supported在其他設備上,但這個值沒有問題,所以我會用我的例子。

在arduino上,這很可能是你必須配置的唯一東西(如果事實上,這是我設置的唯一一個當我想使用串口與我的電腦交談)。

Serial.begin(115200); 

然後根據this wikibook可以在termios結構通過設置中設置了波特率,如維基例子中,我把它叫做attribs

struct termios attribs; 

/* get the current settings */ 
tcgetattr(serialfd, &attribs); 

/* set the baudrate */ 
cfsetospeed(&attribs, B115200); /* outut baudrate */ 
cfsetispeed(&attribs, B115200); /* input baudrate */ 

/* if there is need for it, set other settings here */ 

/* eventually apply everything for your serialfd descriptor */ 
tcsetattr(serialfd, TCSANOW, &attribs); 

所以,是技術上你可以有不同的速度輸入比輸出,但Arduino的的UART只有一個這樣的設置和does not support different speeds for input/ouput,所以你需要在電腦上設置了兩個相同的值。

+0

這並沒有解決它在所有我得到了相同的結果,如果我不是設置波特率。 – Aram

+0

您是否檢查過緩衝區的內容,看它是否被終止? – saeleko

+0

是的,我只是讀了10個字節,所以第11個空終止。現在它'有點作品'。它的大部分時間都在閱讀,但有時候我仍然得到垃圾。你知道這是爲什麼嗎?在一個緊密的循環中,我正確地閱讀了A.如果我有時執行該程序幾次,我會得到隨機字符。 – Aram

0

如果你只需要接受對PC端的二進制數據,也許反應一定的值,並送東西回的Arduino和日誌數據,例如,

那麼你可以使用一些更高級的RS232終端程序,如 http://docklight.de/

它有更多的選項和腳本來基本上做螞蟻數據處理,但我沒有使用腳本。

但是在幾分鐘內,您就可以使用ASCII或二進制格式讀取和應答數據。

當然,對於某些數據庫連接或更多,您將需要自定義程序,但要在調試階段測試操作docklight是一個偉大的工具。