Strange behaviour when communicating over serial from VS WPF to Arduino

162 views Asked by At

A basic overview. I am sending serial data from an Arduino Due to WPF application. Up until now this has all been working perfectly. Today I implemented a loop into the Arduino code that looks for a "Y" (ascii 89) in the serial port, if received it leaves the loop and returns back into what I am calling offline mode and stops sending over data, via online = false.

Now what is strange about this is that...

  1. It was working fine before this loop so it must be something to do with trying to resend new data once it has left the 'online loop'.

  2. It works perfectly from the Arduino serial monitor, which suggests it's a WPF problem, although the code hasn't changed on the upload section.

The code for both of these programmes is pretty big so I will try and keep it concise whilst providing all the information necessary.

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());
  }

I then have switch cases to handle incoming settings - I know this works fine as it will also upload after the Arduino is reset.

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...

Online Mode

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() consists of just a range of serial.print, outputting into one large string for WPF to handle.

Here is a screenshot of the serial monitor working

As you will see from the link above the monitor spits out a load of data, stops when I send a Y and finally I send a Q to 'question' whether the Arduino is ready to receive settings and S signifies a Yes. Great stuff it works!

However as you can see from the link below this isn't the case in WPF. Sorry, I can only upload 2 images at the moment so had to combine them.

Combo of screenshots

Here is the loop it is currently getting stuck in

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;
}

And on a separate page this is how I am stopping the incoming data.

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;
    }
  }
}

The biggest stumbling block for me is why this works over the serial monitor but not within the application. And it also works as soon as I reset the Arduino. I have also tried the resetFunc() in Arduino but this didn't help either.

Thanks in advance.

1

There are 1 answers

0
charley On BEST ANSWER

It turns out i still had a resetFunc() in my switch case which was preventing the serial monitor from continuing to send data!