2017-06-08 187 views
2

我正在使用C#和arduino。我仍然是這方面的新手。我希望有人能幫助我。所以我的項目是發送一些代碼給Arduino。然後在Arduino上應用延遲並將一些字符串/字符發送回C#。我在C#上給出了一個文本框來顯示閱讀結果。這是我的代碼: C#代碼arduino寫入和讀取

Public form1() 
{ 
    initializeComponent(); 
    Serialport1.Open(); 
} 

public void Read() 
{ 
    while (Serialport1.IsOpen) 
    { 
     try 
     { 
      string message = SerialPort1.ReadLine(); 
      textbox1.text = message; 
     } 
     catch (timeoutException) 
     { 
     } 
    } 
} 
private void button1_click(object sender, eventargs e) 
{ 
    SerialPort1.write("A"); 
    read(); 
} 

的Arduino代碼:

int data; 
void setup() 
{ 
    Serial.begin(9600); 
    Serial.print("START\n"); 
} 

void loop() 
{ 
    if(Serial.available()) 
    { 
     data = Serial.read(); 
     if(data=='A') 
     { 
      delay(3000); 
      Serial.print("B"); 
     } 
    } 
} 

我希望是文本結果寫入B,但沒有什麼是來和文本框保留爲空白。我做錯了什麼?我希望有人能向我解釋。謝謝

回答

1

ReadLine是根據documentation

返回輸入緩衝器的內容到一個換行值的第一次出現的方法。
....
默認情況下,ReadLine方法將阻塞,直到收到一行。如果此行爲不受歡迎,請將ReadTimeout屬性設置爲任何非零值,以強制ReadLine方法在端口上不存在線路時引發TimeoutException。

所以,如果你看看arduino發送什麼,它只是一個"B"。您應該在郵件中添加換行符:"B\n"或使用println方法,該方法會自動添加一個新行。

但主要問題實際上是你永遠不會從你那裏返回方法Read所以GUI永遠不會被更新,即使你收到一些你不會看到的東西。
此外,在您的while循環中,僅當數據在緩衝區中時纔會進行讀取。您可以使用BytesToRead屬性來檢查是否值得從端口讀取:

while (Serialport1.IsOpen) 
{ 
    if (Serialport1.BytesToRead > 0) 
    { 
     try 
     { 
      string message = Serialport1.ReadLine(); 
      textbox1.text = message; 
      // break out the while loop here so that you can see the content of the textbox 
      break; 
     } 
     catch (Exception ex) 
     { 
      textbox1.text = "ERROR: " + ex.Message; 
     } 
    } 
} 

而且它是一個壞習慣趕的厚望,不要做這種事情的信息。因爲它經常可以讓你掌握錯誤的性質。到目前爲止,你只是掩蓋它。

0

你應該監聽器連接到端口是這樣的:
SerialPort port = new SerialPort("COM4", 9600); port.DataReceived += new SerialDataReceivedEventHandler(dataReceivedHandler); port.open();

,然後寫您的處理程序,如:

private void dataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
    { 
     SerialPort sp = (SerialPort)sender; 
     string indata = sp.ReadExisting(); 

     Dispatcher.Invoke(
      delegate 
     { 
      textbox1.Text = indata; 
     }); 
    } 

而且你按一下按鈕可能是這樣的:

private void button1_click(object sender, RoutedEventArgs e) 
    { 
     try {    
      port.Write("A");     
     } 
     catch (Exception ex) 
     { 
      textbox.Text = " Send Failed !"; 
     } 
    } 
1

試試這個:

功能:

  • 計算機:點擊ON/OFF按鈕
  • 的Arduino:開啓/關閉LED

的Arduino代碼:

const int LedPin = 13; 
int ledState = 0; 

void setup() 
{ 
    pinMode(LedPin, OUTPUT); 

    Serial.begin(9600);  
} 

void loop() 
{ 
    char receiveVal;  

    if(Serial.available() > 0) 
    {   
     receiveVal = Serial.read(); 

     if(receiveVal == '1')  
      ledState = 1;  
     else 
      ledState = 0;  
    }  

    digitalWrite(LedPin, ledState); 

    delay(50);  
} 

C#代碼:

using System; 
using System.Windows.Forms; 
using System.IO.Ports; 
namespace ledcontrol 
{ 
    public partial class Form1 : Form 
    { 
     SerialPort port; 
     public Form1() 
     { 
      InitializeComponent(); 
      this.FormClosed += new FormClosedEventHandler(Form1_FormClosed); 
      if (port==null) 
      { 
       port = new SerialPort("COM7", 9600);//Set your board COM 
       port.Open(); 
      } 
     } 
     void Form1_FormClosed(object sender,FormClosedEventArgs e) 
     { 
      if(port !=null &&port.IsOpen) 
      { 
       port.Close(); 
      } 
     } 
     private void button1_Click(object sender, EventArgs e) 
     { 
      PortWrite("1"); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      PortWrite("0"); 
     } 
     private void PortWrite(string message) 
     { 
      port.Write(message); 
     } 
    } 
} 

你可以看到tutori al here:http://www.lattepanda.com/topic-f6t1534.html?sid=0aac1b4a519c7a2d970b81059e6e581f