1

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.

dda
  • 6,030
  • 2
  • 25
  • 34
charley
  • 87
  • 4
  • 17
  • First of all I'd put a small delay between the sending and the readexisting functions. Then the serial port can return also a partial message, so writing "tempdata = myPort.ReadExisting();" is not correct (you should append). Finally I'd use the serial port as an ASYNCHRONOUS device, not a synchronous one. You can use 1) a timer to send the Q byte (for instance) every second, then when you receive the correct string you can just stop it. Another timer can detect the timeout (and if you receive the correct data just stop it before it is fired). Finally read the incoming data through the – frarugi87 Dec 21 '16 at 14:06
  • [DataReceived event](https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived(v=vs.110).aspx) of the SerialPort class. Remember to always append to the buffer, then remove from it when done. Try this and I think it will work (this approach usually saved my day when the serial port was not behaving correctly) – frarugi87 Dec 21 '16 at 14:07
  • HI @frarugi87, thanks for the reply! I have implemented the timer which helps everything a lot, its much nicer! RE myPort.ReadExisting is not correct. I see where you are coming from however reading and appending a byte for example currently doesn't work as the Arduino doesn't appear to be sending anything, as far as the software is concerned anyway. and therefore the application isn't receiving anything, and definitely not a "S" – charley Dec 21 '16 at 14:33
  • It turns out is till had a resetFunc() in my switch case which was preventing the serial monitor from continuing to send data! Its always one line that hold you up! – charley Dec 21 '16 at 15:33
  • Well, all's well that ends well :-) glad you could find the solution to your problem – frarugi87 Dec 21 '16 at 16:11

1 Answers1

0

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

charley
  • 87
  • 4
  • 17