2015-05-17 16 views
0

之間的溝通我現在爭奪這個問題了一會兒,這是推動我堅果:從PC(通過USB爲串行設備)C&Arduino的

我試圖用一個Arduino兆2560很簡單溝通當我在這個階段嘗試完成的時候,運行Linux(Knoppix在usb-dok上)是,對於筆記本發送給Arduino的每個數字,'stobe'信號將切換爲高電平或低電平,我用這個頻閃燈來打開和關閉LED。

PC端的C代碼:

#include <stdio.h> 
 

 
int main() 
 
{ 
 
\t FILE * Device = NULL; 
 
\t int counter = 0; 
 
\t 
 
\t Device = fopen("/dev/ttyACM0", "w+"); 
 
\t if(Device == NULL) 
 
\t { 
 
\t \t printf("could not open Device\n"); 
 
\t \t return -1; 
 
\t } 
 

 
\t while (counter < 10) 
 
\t { 
 
\t \t fprintf(Device, "%d\n", counter); 
 
\t \t printf("Sent to Device: %d\n", counter); 
 
\t \t counter++; 
 
\t \t sleep(2); 
 
\t } 
 

 
\t fclose(Device); 
 

 
return 0; 
 
}

的Arduino代碼:

int cnt = 0; 
 
int strobe = 0; 
 
int num; 
 
int ValidInput = 0; 
 

 
char intBuffer[12]; 
 
String intData = ""; 
 
int delimiter = (int) '\n'; 
 

 
void setup() { 
 
    // put your setup code here, to run once: 
 
    Serial.begin(9600); 
 
    pinMode(3, OUTPUT); 
 
} 
 

 
int input; 
 

 
void loop() 
 
{ 
 
    while(num = Serial.available()) 
 
    { 
 
    delay(5); 
 
// Serial.println(num); 
 
    int ch = Serial.read(); 
 
    if(ch == delimiter) 
 
    { 
 
    ValidInput = 1; 
 
    break; 
 
    } 
 
    else 
 
    { 
 
     intData += (char) ch; 
 
    } 
 
    } 
 
    int intLen = intData.length() + 1; 
 
    intData.toCharArray(intBuffer, intLen); 
 
    intData = ""; 
 
    int i = atoi(intBuffer); 
 
    
 
    if(ValidInput) 
 
    { 
 
     if(i == 0) 
 
     { 
 
     strobe = 0; 
 
     Serial.print("Initializing strobe"); 
 
     } 
 
     else 
 
     { 
 
     strobe = !strobe; 
 
     } 
 
     
 
     digitalWrite(3, (strobe) ? HIGH : LOW); 
 
     Serial.println(i); 
 
     ValidInput = 0; 
 
    } 
 
}

我遇到的問題:

  1. 不確定fopen是否與Linux中的串行設備進行通信的正確方式,以及在哪種模式下?
  2. 這是主要問題 - 我遇到了非確定性行爲: 如果我在打開Arduino編輯器的「串行監視器」之前運行此代碼,它不起作用,正如我上面所解釋的那樣 - 相反,它會將LED然後馬上關閉,爲每個新來的新號碼。 ,但是一旦我打開「串行監視器」,它就會按照我希望的那樣工作 - 更改每個新來電號碼的LED狀態。

我想這與Arduino的重置或類似的東西有關。

我看了很多主題在這裏和其他論壇,並找不到解決這個問題的任何解決方案。

我真的很感謝你的見解。

+0

你的Arduino的代碼看起來是合理的。嘗試使用http://www.libusb.org/作爲PC端的東西。 –

+0

@SoundConception - 不,libusb在這裏不是合乎邏輯的選擇。 USB設備由內核/模塊USB串行或(在本例中)CDC/ACM驅動程序處理。應用程序應該使用串行API,這是程序試圖做的事情。缺少(並且與觀察到的問題精確相關)的最明顯的事情是端口配置,並且通常需要來自open()的文件描述符而不是來自fopen()的流。 –

回答

1

首先,arduino的一面看起來不錯。在Linux方面,你需要做一些研究,因爲posix系統上的串行通信比打開文件和寫入文件稍微複雜一些。請使用termios的linux手冊頁,您可以在其中找到有關如何設置通信端口參數的信息,並使用此文檔http://tldp.org/HOWTO/Serial-Programming-HOWTO/實際學習如何完全放置所有內容。串行編程howto將指導您完成設置端口的過程,學習如何控制端口並學習如何接受來自多個源的輸入。此外,爲了成功從非特權帳戶訪問串行端口,您可能需要將該用戶(您的用戶)添加到特定組(Ubuntu和Fedora中的撥出組)。您可以在Google上搜索Linux下的串口訪問,並且可以爲您準備大量代碼示例,以便將其集成到您的應用程序中。你可以在這個線程的底部找到一個很好的參考和完整的文檔實現,也可以在SO How do I read data from serial port in Linux using C?

0

一個簡單的fopen不會設置任何串口通信參數。您需要設置波特率,位數,奇偶校驗和停止位數。而且,如果你想使用Linux線路規則或不。 termio結構用於執行此操作。

有一些關於如何在linux和arduinos之間使用串口的很好的教程。

http://chrisheydrick.com/2012/06/12/how-to-read-serial-data-from-an-arduino-in-linux-with-c-part-1/

http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/