2016-12-21 9 views
1

基本的な概要。 WPFアプリケーションのためArduinoからシリアルデータを送信しています。今までこれはすべて完璧に動作していました。今日私はシリアルポートで "Y"(ascii 89)を探すArduinoコードにループを実装し、受信した場合はループを去って、オフラインモードと呼んでいるものに戻り、オンライン経由でデータを送信しません=偽です。VS WPFからArduinoにシリアル経由で通信するときの奇妙な動作

今、このことについて奇妙な何であるかは、それが「オンラインループを去った後、新しいデータを再送信しようとすると何かでなければならないので、

  1. それは、このループの前に罰金働いていた...ということです'

  2. これは、アップロードセクションでコードが変更されていませんが、それはWPFの問題を示唆するArduinoシリアルモニタから完全に動作します。

これらのプログラムのコードはかなり大きいので、必要なすべての情報を提供しながら簡潔にしておきます。

void loop() { 
    // Check to see if the testbench is in offline mode and run the respective code. 
    if (Online == false) { 
    OfflineMode(); 
    } 
    // Check to see if the testbench is in online mode and run the respective code. 
    if (Online == true) { 
    OnlineMode(); 
    } 
} 

void OfflineMode() { 
    while (Serial.available()) 
    processlncomingByte(Serial.read()); 
    } 

私はその後、着信設定を処理するために、スイッチケースを持っている - 私はアルドゥイーノがリセットされた後、それはまた、アップロードすると、これは正常に動作します知っています。

void processlncomingByte (const byte c) { 
    if (isdigit (c)) { 
    currentValue *= 10; 
    currentValue += c - '0'; 
    } else { 
    // end of digit 
    // The end of the number signals a state change 
    handlePreviousState(); 
    // set the new state, if we recognize it 
    switch (c) { 
     case 'A': 
     state = GOT_A; 
     break; 
etc... 

オンラインモード

void OnlineMode() { 
    CheckForStop(); 
    SendSerialData(); 
} 

void CheckForStop() { 
    //Serial.println("..."); 
    if (Serial.available() > 0) { 
    //Serial.println("getting something"); 
    ch = (char)Serial.read(); 
    inputString = ch; 
    if (ch == 89) { 
     //Serial.end(); 
     Online = false; 
     //Serial.begin(9600); 
     exit; 
     //return; 
    } 
    } else 
    delay(5); 
} 

SendSerialData()は、WPFが処理するための1つの大きな文字列に出力し、serial.printのちょうど範囲から成ります。

Here is a screenshot of the serial monitor working

あなたは、モニター上のリンクから見ていくようにデータの負荷を吐き出し、私は最終的にYを送信したときに、私はArduinoの設定を受信する準備ができているかどうかを「質問」にQを送信を停止しますSはYesを示します。それは素晴らしいもの!

しかし、以下のリンクからわかるように、これはWPFのケースではありません。申し訳ありませんが、私はその時点で2つの画像しかアップロードできないので、それらを結合しなければなりません。

Combo of screenshots

ここでは、現在

private bool checkArduinoisReady() { 
    Stopwatch Uploadtimer = new Stopwatch(); 
    if (!myPort.IsOpen) 
    return false; 
    // Debug.Print("port is ready to be opened"); 
    string tempdata; 
    Uploadtimer.Start(); 
    myPort.DiscardInBuffer(); 
    Start: 
    myPort.WriteLine("Q" + Environment.NewLine); 
    Debug.Print("sent Q"); 
    tempdata = myPort.ReadExisting(); 
    Debug.Print("tempdata_" + tempdata.ToString()); 
    if (Uploadtimer.ElapsedMilliseconds > 5000) 
    return false; 
    if (tempdata.Contains("S")) 
    return true; 
    else 
    goto Start; 
} 

で立ち往生されており、別のページに、これは私が入ってくるデータを停止していますどのようにループがあります。これは、アプリケーション内でシリアルモニター上で動作ではなく、なぜ

private void StopTest(object sender, RoutedEventArgs e) { 
    MessageBoxResult StopConfirm = MessageBox.Show("Are you sure you want to stop the test?", "Stop the test", MessageBoxButton.YesNo, MessageBoxImage.Question); 
    if (StopConfirm == MessageBoxResult.Yes) { 
    Timer.Stop(); 
    Debug.Print("Timer Stopped"); 
    myPort.DiscardInBuffer(); 
    Start: 
    for (int i = 0; i < 100; i++) { 
     myPort.WriteLine("Y"); 
    } 
    string tempData = myPort.ReadExisting(); 
    Debug.Print("Checking..."); 
    Debug.Print("tempData_" + tempData); 
    if (string.IsNullOrWhiteSpace(tempData)) { 
     Debug.Print("Its null!!"); 
     comments_textbox.Text = comments_textbox.Text + "Test Aborted"; 
     MessageBoxResult SaveCurrentData = MessageBox.Show("Would you like to save the data collected up until this point?", "Save", MessageBoxButton.YesNo, MessageBoxImage.Question); 
     if (SaveCurrentData == MessageBoxResult.Yes) { 
     SaveFile(); 
     } 
     if (SaveCurrentData == MessageBoxResult.No) { 
     myPort.Close(); 
     NavigationService.Navigate(new Uri("testSettings.xaml", UriKind.RelativeOrAbsolute)); 
     } 
    } else { 
     Debug.Print("Still going..."); 
     goto Start; 
    } 
    } 
} 

私にとって最大の障害とはあります。また、Arduinoをリセットすると同時に動作します。私もArduinoでresetFunc()を試しましたが、これも役に立たなかった。

ありがとうございます。

+0

まず、送信と読み取りの間に小さな遅延があります。シリアルポートは部分的なメッセージも返すことができるので、 "tempdata = myPort.ReadExisting();"と書いてください。正しくない(追加する必要があります)。最後に、シリアルポートを同期デバイスではなく非同期デバイスとして使用します。 1)1秒ごとにQバイト(例えば)を送信するタイマーを使用して、正しい文字列を受け取ったらすぐに停止することができます。別のタイマーはタイムアウトを検出できます(また、正しいデータを受信した場合は、起動する前に停止してください)。最後に、受信したデータを – frarugi87

+0

[DataReceivedイベント](https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived(v = vs.110).aspx)で読み取ります。 SerialPortクラス。いつもバッファに追加してから終了してください。これを試してみてください。(これは通常、シリアルポートが正しく動作していなかったときにこの方法で保存されました) – frarugi87

+0

HI @ frarugi87、ありがとうございます!私はすべてを助けるタイマーを実装しました、その多くのより良い! RE myPort.ReadExistingが正しくありません。私はどこから来ているのか分かりませんが、たとえばバイトを読み込んで追加すると、現在のところArduinoは何も送信していないように見えます。したがって、アプリケーションは何も受信しておらず、確かに "S"ではありません – charley

答えて

0

シリアルモニタがデータを送信し続けないようにしていた私のスイッチのケースではまだresetFunc()がありました。

関連する問題