title: C# Serial Communication to Arduino
body: <p>I'm working on a project that involves my client software sending data to a Arduino microcontroller, AtMega32U4, through serial communication. I've looked through many answered questions so far yet none of them were specific to my problem. However, I believe my problem may be limited to threading issues or Arduino autoreset problems.</p>
  
  <p><strong>Code 1:</strong></p>
  
  <pre><code>public MainForm()
      {
          InitializeComponent();
          serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
          serialPort1.DtrEnable = true;
          //serialPort1.RtsEnable = true;
      }
  private void button3_Click(object sender, EventArgs e)
      {
          // Disables button while processing
          button3.Enabled = false;
  
          GetDir dir = new App.GetDir();
          dir.getCoords(Origin.Text, Destination.Text, Application.StartupPath + @"\temp2.html", "temp2.xml");
          dataBrowser.Navigate(Application.StartupPath + @"\temp2.html");
          dataBrowser.Update();
  
          waypoints = dir.coordsLat.Length;
          counter = dir.coordsLat.Length;
          coords = new double[dir.coordsLat.Length, 2];
  
          for (int i = 0; i &lt; counter; i++)
          {
              coords[i, 0] = (Convert.ToDouble(dir.coordsLat[i]));
              coords[i, 1] = (Convert.ToDouble(dir.coordsLon[i]));
          }
  
          //serialPort1.Close();
          //System.Threading.Thread.Sleep(1000);
  
  
          if (serialPort1.IsOpen &amp;&amp; !doubleClick)
          {
              serialPort1.Close();
              System.Threading.Thread.Sleep(2000);
              try
              {
                  serialPort1.Open();
              }
              catch (Exception exception)
              {
                  MessageBox.Show(exception.Message, "Cannot open serial port");
              }
              System.Threading.Thread.Sleep(2000);
          }
          else
          {
              if (!serialPort1.IsOpen)
              {
                  try
                  {
                      serialPort1.Open();
                      doubleClick = true;
                  }
                  catch (Exception exception)
                  {
                      MessageBox.Show(exception.Message, "Cannot open serial port");
                  }
                  System.Threading.Thread.Sleep(2000);
                  serialPort1.Write("^");
                  System.Threading.Thread.Sleep(1000);
                  Console.WriteLine('^');
                  //button3.Enabled = true;
              }
          }  
      }
  
      private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
          //System.Threading.Thread.Sleep(1000);
          readData = serialPort1.ReadLine();
          Console.WriteLine(readData);
          // If microcontroller sends "&amp;", it is ready to receive next piece of data
          if (readData == "&amp;")
          {
              sendRequest = true;
          }
          else
          {
              sendRequest = false;
          }
  
          // Write next piece of data to microcontroller if it is ready
          if (sendRequest)
          {
              this.BeginInvoke( new EventHandler (write_serialPort1));
          }
      }
  </code></pre>
  
  <p>In during the debugging of code 1, the event handler (serialPort1_DataReceived) never gets called. In this process, somehow button3_click gets called twice as the console outputs '^' twice. Afterwards, the client stalls since there is nothing beind received. Keep in mind that the Arduino will respond with an ampersand ('&amp;') once it has received the circumflex ('^'). The Arduino code has been tested on the Arduino IDE and appears to be working fine. I believe the problem with button3_click being called twice comes from the button3_down and button3_up.</p>
  
  <p>However, I was able to bypass this issue with Code 2. But also hit another brick wall. </p>
  
  <p><strong>Code 2 :</strong></p>
  
  <pre><code> private void button3_Click(object sender, EventArgs e)
      {
          // Disables button while processing
          button3.Enabled = false;
  
          GetDir dir = new App.GetDir();
          dir.getCoords(Origin.Text, Destination.Text, Application.StartupPath + @"\temp2.html", "temp2.xml");
          dataBrowser.Navigate(Application.StartupPath + @"\temp2.html");
          dataBrowser.Update();
  
          waypoints = dir.coordsLat.Length;
          counter = dir.coordsLat.Length;
          coords = new double[dir.coordsLat.Length, 2];
  
          for (int i = 0; i &lt; counter; i++)
          {
              coords[i, 0] = (Convert.ToDouble(dir.coordsLat[i]));
              coords[i, 1] = (Convert.ToDouble(dir.coordsLon[i]));
          }
  
          serialPort1.Close();
  
          try
          {
              serialPort1.Open();
          }
          catch (Exception exception)
          {
              MessageBox.Show(exception.Message, "Cannot open serial port");
          }
  
          if (serialPort1.IsOpen)
          {
              System.Threading.Thread.Sleep(2000);
              using (serialPort1)
              {
                  serialPort1.Write("^");
                  System.Threading.Thread.Sleep(1000);
                  Console.WriteLine("^");
                  serialPort1.Close();
                  System.Threading.Thread.Sleep(5000);
              }
          }
          else
          {
              button3.Enabled = true;
          }
  
      }
  
      private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
          //SerialPort sp = (SerialPort)sender;
  
          System.Threading.Thread.Sleep(10000);
          /*if (!serialPort1.IsOpen)
          {
              serialPort1.Close();
              System.Threading.Thread.Sleep(10000);
              serialPort1.Open();
              System.Threading.Thread.Sleep(10000);
          }*/
          //serialPort1.Open();
          //using (sp)
          using (serialPort1)
          {
              serialPort1.Open();
              System.Threading.Thread.Sleep(5000);
              readData = serialPort1.ReadExisting();
              Console.WriteLine(readData);
              // If microcontroller sends "&amp;", it is ready to receive next piece of data
              if (readData == "&amp;")
              {
                  sendRequest = true;
              }
              else
              {
                  sendRequest = false;
              }
  
              // Write next piece of data to microcontroller if it is ready
              if (sendRequest)
              {
                  this.BeginInvoke(new EventHandler(write_serialPort1));
              }
          }
      }
  </code></pre>
  
  <p>In Code 2, the event handler does get called and the button3_click only runs once. But when it tries to open the port, it returns the error '<code>Access to Port X denied</code>'. Furthermore, I wish I didn't have to close and open the ports like this, but when the event handler is called (in an earlier code) it returned the error that the COM Port was not opened. In order to satisfy that error, I had to close it and reopen it during <code>button3_click</code> and event handling. </p>
  
  <p>I've added a lot of delay in the code after I read about many problems dealing with the threading issues with serial communication. I had even tried a minute delay in hopes of a thread ending to solve the problem. However, no luck there. </p>
  
  <p>I also specified my serial port in the MainForm designer instead of declaring it in the code (At first I did both and realized it was redundant). I'm not sure if this contributes to the problem, but I've seen examples of both being used.</p>
  
  <p>Lastly, it could definitely deal with the Arduino auto resetting everytime a serial connection has been made (eg. opening and closing a port). In summary, it seems be sending data through serial, but unable to read the incoming data from serial.</p>
  
  <p>Thank you for reading this and if someone could point me in the right direction, it would be very much appreciated.</p>
  
  <p><strong>Edit #1:</strong> Even after using BeginInvoke in Code 1, it still deadlocks because the event handler was never called.</p>
  
  <p><strong>Edit #2:</strong> Edits to Code 1 as per newbie's suggestions.</p>
  
  <p><strong>Edit #3:</strong> Added mainform initialization and updated Code 1 to current state.</p>
  
  <p><strong>Edit #4:</strong> Deleted (Commented out) the sleep at the event handler. I was sleeping during the event handler, thus I couldn't receive anything that the microcontroller would send to me. Code works fine as expected now.</p>