2013-10-05 50 views
1

我正在嘗試在C#中編寫一個程序,以通過串行連接從我的計算機與我的Arduino UNO進行通信。目前我只是寫一個簡單的應用程序,建立與Arduino的聯繫,然後用幾個控件來控制arduino上的每個引腳;要麼從中讀取值,要麼爲其寫入值。C#-Arduino通信不匹配?

我已經設法建立與Arduino的聯繫並設置引腳值,但它並不總是要服從我的命令。我設置了一些複選框,當我檢查一個盒子時,一個LED應該打開,當我取消檢查時LED會熄滅。問題是,有時LED只是保持打開或關閉,我必須再次點擊方塊幾次才能再次響應,或重置我的電路...

我試圖做一些故障查找,但couldn沒有找到問題的根源:它是我的應用還是Arduino代碼?

這裏是我的代碼的相關部分:

private void sendValue(int RW, int _Pin, int Val) //send from my app to serial port 
{ 
    if (CommPort.IsOpen) 
    { 
     CommPort.WriteLine(RW.ToString() + "," + _Pin.ToString() + "," + Val.ToString()); 
    } 
} 

private void chP9_CheckedChanged(object sender, EventArgs e) //call the sendValue routine 
{ 
    if (chP9.Checked) 
    { 
      sendValue(1, 9, 255); //('Write', to pin 9, 'On') 
    } 
    else 
    { 
     sendValue(1, 9, 0); //('Write', to pin 9, 'Off') 
    } 
} 

這是我的C#代碼,它編譯一個逗號分隔字符串通過串口發送到由Arduino的讀取。

下面是Arduino的代碼:

int RW; //0 to read pin, 1 to write to pin 
int PN; //Pin number to read or write 
int Val; //Value to write to pin 

void setup() { 
    Serial.begin(38400); 
} 

void loop() { 
    ReadIncoming(); 
    ProcessIncoming(); 
} 

void ReadIncoming() 
{ 
    if(Serial.available() > 0) 
    { 
    RW = Serial.parseInt(); 
    PN = Serial.parseInt(); 
    Val = Serial.parseInt(); 
    } 
    while(Serial.available() > 0) //Clear the buffer if any data remains after reading 
    { 
    Serial.read(); 
    } 
} 

void ProcessIncoming() 
{ 
    if(RW == 0) 
    { 
    pinMode(PN, INPUT); 
    } 
    else 
    { 
    pinMode(PN, OUTPUT); 
    analogWrite(PN, Val); 
    } 
} 

parseInt函數只是取出它找到的第一個整數值,並將其存儲和扔掉的逗號,一次又一次地這樣做,但它似乎有點反直覺。

我想我的問題就在這裏:

while(Serial.available() > 0) //Clear the buffer if any data remains after reading 
    { 
    Serial.read(); 
    } 

我認爲應用比Arduino的代碼可以處理速度更快發送數據,尤其是這個循環中,但我該怎麼做過量的數據?

我不喜歡使用parseInt,但這是我能找到正確閱讀我的指示的唯一方法。如何從C#發送一個字節數組,並將該數組讀入Arduino中的數組?

我已經指出了我的假設,並探討了替代方案,但無法獲得任何解決方案。你們對我有什麼建議?

+0

無需來回傳遞字符串時的幾個字節是你真正想要的。 –

回答

2

它不是很清楚爲什麼它可以工作。你應該考慮一個更智能的方式來編碼命令。你只需要三個字節:

private void sendValue(int RW, int _Pin, int Val) { 
     var cmd = new byte[] { (byte)RW, (byte)_Pin, (byte)Val }; 
     ComPort.Write(cmd, 0, cmd.Length); 
    } 

然後你只需要在Arduino的讀取結束的3個字節:

void ReadIncoming() { 
    if (Serial.available() >= 3) { 
     RW = Serial.read(); 
     PN = Serial.read(); 
     Val = Serial.read(); 
     ProcessIncoming(); 
    } 
} 
+0

嗨漢斯,這個作品很有魅力,謝謝!這是我在嘗試parseInt之前一直在尋找的東西。我做了類似的事情,但是我寫道:if(Serial.available()> ** 0 **),並且如我所懷疑的那樣,在所有字節出現之前讀取數據,因此根本不起作用。 –