Strange Serial problem

A friend and I are trying to send commands from C# to Arduino Due through Serial. We've got the Arduino hooked up to USB through the Programming Port. We ran into really strange behaviour.

We start off with a simple handshake, the Arduino sends "A" over and over as long as Serial.available() returns 0. Our C# code checks all COM Ports, listening for "A". When it receives "A", it sends out "B". Once the Arduino gets "B", we continue to our main loop. Nothing crazy.

In theory it works perfectly. When you connect to Arduino via Serial on my laptop, it resets and the handshake works. Once I press the reset button however, it stops working. The Arduino fails to receive "B". Serial.available() will always return 0 and we're stuck in a loop sending out "A".

On my friend's PC it only works right after uploading the Arduino's code from the Arduino IDE. If he tries to connect to the Arduino otherwise, it will always fail to receive "B".

We would greatly appreciate any help.

You have not posted any of your code so I can only guess - probably wrongly.

Your C# program has to be written to take account of the Arduino resetting when it opens the Serial Port. It should then keep the serial port open until it is completely finished with the Arduino.

Have a look at this Python - Arduino demo. The same technique should work in any language.

It is a good idea, at least during development, to include some code in your PC program so it displays every message it receives from the Arduino.

...R

I looked through the sample projects you provided but unfortunately, they didn’t help.
It’s not that we’re not getting it to work, it doesn’t work under certain circumstances, like I wrote in the OP. Once I hit the reset button it doesn’t work anymore. On my friend’s machine it only works right after uploading the code from the IDE to the Arduino. We’re thinking that maybe the IDE does something to the USB Port/Controller, that we are missing in our code?

Here’s our code:
Arduino:

void setup()
{

  Serial.begin(57600);
  
  handshake();


.......................


void handshake() {
    delay(10);
    bool isFound = false;
    while(!isFound) {
      while(Serial.available() <= 0) {
        Serial.write("A\n");
        delay(50);
      }
      if(Serial.read()=='B')
        isFound=true;
     }
   }

C# Code for the

private void getConnection()
        {
            //try simple handshake with every port
            //if 'A' is received, send 'B'    
            //TODO: exception handling
            foreach (string portname in SerialPort.GetPortNames())
            {
                Console.WriteLine("Check Port " +portname);
                serialPort = new SerialPort(portname, 57600);
                serialPort.DtrEnable = true;
                serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                try {
                    serialPort.Open();
                } catch (UnauthorizedAccessException e)
                {
                    Console.WriteLine("Exception in SerialConnection. UnauthorizedAccessException for Port " + portname);
                    serialPort = null;
                    continue;
                }
                catch (ArgumentOutOfRangeException e)
                {
                    Console.WriteLine("Exception in SerialConnection. ArgumentOutOfRangeException for Port " + portname);
                    serialPort = null;
                    continue;
                }
                catch (ArgumentException e)
                {
                    Console.WriteLine("Exception in SerialConnection. ArgumentException for Port " + portname);

                    serialPort = null;
                    continue;
                }
                catch (InvalidOperationException e)
                {
                    Console.WriteLine("Exception in SerialConnection. InvalidOperationException for Port " + portname);
                    serialPort = null;
                    continue;
                }
                catch (System.IO.IOException e)
                {
                    Console.WriteLine("Exception in SerialConnection. IOException for Port " + portname);
                    serialPort = null;
                    continue;
                }
                
                string line = serialPort.ReadLine();

                if (line.Contains("A"))
                {

                    System.Threading.Thread.Sleep(100);
                    serialPort.DiscardOutBuffer();
                    serialPort.DiscardInBuffer();
                    serialPort.Write("B");

                    Console.WriteLine("Found Arduino on Port " + portname);
                    break;
                }
                else
                {
                    serialPort.Close(); serialPort = null;
                }
            }
        }

So sometimes this code won’t work and Arduino won’t be able to receive the “B” byte. We would really like to have a system where it just works without us having to keep unpluggin/replugging the Arduino.

                serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

You define a handler to be called when there is serial data to read.

                string line = serialPort.ReadLine();

                if (line.Contains("A"))
                {

Then, you expect to do the handlers job.

I don't get it. ONE way of reading the data is appropriate.

You could attach the handler after you have decided that it is the correct port...

PaulS:                 serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

You define a handler to be called when there is serial data to read.

                string line = serialPort.ReadLine();

                if (line.Contains("A"))                 {



Then, you expect to do the handlers job.

I don't get it. ONE way of reading the data is appropriate.

You could attach the handler after you have decided that it is the correct port...

I guess this is a design flaw, thanks. Only adding the handler afterwards doesn't solve our problem unfortunately.

If you post ALL of your code, for the Arduino and the C# app, I'll investigate further when I'm home.