Go Down

Topic: Serial communication with C# program: SerialDataReceivedEventHandler doesnt work (Read 6 times) previous topic - next topic

muslera

Hello all, I've problems with the serial communication between my Arduino Leonardo and my PC. I've developed a C# program which interfaces with my Arduino.

The C#~program writes perfectly in the serial interface. Then the Arduino reads this communication and puts a HIGH or a LOW level in a digital output. However it does not receive the data sent by the Arduino  :|

I've checked that the Arduino sends the data propperly, both using the Serial monitor in the Arduino Environment, and Hyperterminal in my PC. Hyperterminal reads perfectly the strings sent by Arduino.

I've used the class SerialPort. I use a SerialDataReceivedEventHandler to process the data received through the serial port. This event is never activated so this handler function is never executed...

I've read in internet that it is necessary to use an independent thread to read the serial port. I thought that using this handler was enough...  is not?

I also used a different program available in internet, with the same result. I could write to Arduino, but not read. The program is available in the site http://msmvps.com/blogs/coad/archive/2005/03/23/SerialPort-_2800_RS_2D00_232-Serial-COM-Port_2900_-in-C_2300_-.NET.aspx

Here is my code:

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;  // Serial port
//using System.Threading;

namespace PruebasArduino02
{
   public partial class Form1 : Form
   {
       // Timer para la comunicación serie
       System.Windows.Forms.Timer ComTimer = new System.Windows.Forms.Timer();

       // The main control for communicating through the RS-232 port
       private SerialPort comport = new SerialPort();

       public Form1()
       {
           InitializeComponent();

           comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
       }

       private void Form1_Load(object sender, EventArgs e)
       {
           comport.PortName = "COM12";
           comport.BaudRate = Convert.ToInt16(9600);
           comport.Open();
                       
           ComTimer.Tick += new EventHandler(TimerFcn);
           ComTimer.Interval = 2000;
           //ComTimer.Start();
       }

       private void TimerFcn(Object myObject, EventArgs myEventArgs)
       {
           label1.Text = "Hello";
           //serialPort1.Open();
           //label1.Text = serialPort1.ReadLine().ToString();
           //serialPort1.Close();
       }

       private void button1_Click(object sender, EventArgs e)
       {
           comport.Write("1");
       }

       private void button2_Click(object sender, EventArgs e)
       {
           comport.Write("0");
       }

       private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
       {
           // Read all the data waiting in the buffer
           string data = comport.ReadExisting();

           // Display the text to the user in the terminal
           Log(data);
       }

       private void Log(string msg)
       {
           label1.Invoke(new EventHandler(delegate
               {
                   label1.Text = msg;
               }));
       }

   }
}


Form1.Designer.cs

namespace PruebasArduino02
{
   partial class Form1
   {
       /// <summary>
       /// Variable del diseñador requerida.
       /// </summary>
       private System.ComponentModel.IContainer components = null;

       /// <summary>
       /// Limpiar los recursos que se estén utilizando.
       /// </summary>
       /// <param name="disposing">true si los recursos administrados se deben eliminar; false en caso contrario, false.</param>
       protected override void Dispose(bool disposing)
       {
           if (disposing && (components != null))
           {
               components.Dispose();
           }
           base.Dispose(disposing);
       }

       #region Código generado por el Diseñador de Windows Forms

       /// <summary>
       /// Método necesario para admitir el Diseñador. No se puede modificar
       /// el contenido del método con el editor de código.
       /// </summary>
       private void InitializeComponent()
       {
           this.button1 = new System.Windows.Forms.Button();
           this.button2 = new System.Windows.Forms.Button();
           this.label1 = new System.Windows.Forms.Label();
           this.SuspendLayout();
           //
           // button1
           //
           this.button1.Location = new System.Drawing.Point(53, 70);
           this.button1.Name = "button1";
           this.button1.Size = new System.Drawing.Size(75, 23);
           this.button1.TabIndex = 0;
           this.button1.Text = "button1";
           this.button1.UseVisualStyleBackColor = true;
           this.button1.Click += new System.EventHandler(this.button1_Click);
           //
           // button2
           //
           this.button2.Location = new System.Drawing.Point(163, 112);
           this.button2.Name = "button2";
           this.button2.Size = new System.Drawing.Size(75, 23);
           this.button2.TabIndex = 1;
           this.button2.Text = "button2";
           this.button2.UseVisualStyleBackColor = true;
           this.button2.Click += new System.EventHandler(this.button2_Click);
           //
           // label1
           //
           this.label1.AutoSize = true;
           this.label1.Location = new System.Drawing.Point(118, 180);
           this.label1.Name = "label1";
           this.label1.Size = new System.Drawing.Size(35, 13);
           this.label1.TabIndex = 2;
           this.label1.Text = "label1";
           this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
           //
           // Form1
           //
           this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
           this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
           this.ClientSize = new System.Drawing.Size(292, 266);
           this.Controls.Add(this.label1);
           this.Controls.Add(this.button2);
           this.Controls.Add(this.button1);
           this.Name = "Form1";
           this.Text = "Form1";
           this.Load += new System.EventHandler(this.Form1_Load);
           this.ResumeLayout(false);
           this.PerformLayout();

       }

       #endregion

       private System.Windows.Forms.Button button1;
       private System.Windows.Forms.Button button2;
       private System.Windows.Forms.Label label1;
   }
}

Program in Arduino Leonardo

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP); // not used
  pinMode(13, OUTPUT);
}

char incomingChar;

void loop() {
  int buttonState = digitalRead(2); // not used
  if(Serial.available() > 0)
  {
    incomingChar = Serial.read();
    switch(incomingChar){
      case '1':
        // led is ON
        digitalWrite(13, HIGH);
        break;
      case '0':
        // led is OFF
        digitalWrite(13, LOW);
        break;
    }
    delay(10);
  }
 
  if(1)
  {
    Serial.println("Hello!\n");
    delay(10);
  }
 
}

Do you have any idea? I'm getting crazy with this issue... Thank you in advance!  :)


CustomDev

I finally got it working, after reading a large number of postings. The issue is with the DTREnable and RTSEnable properties set to false, they need to be set to true, even though there is no handshake (HandShake: none), the virtual port requires this to trigger the data retrieval.
I hope this helps you as it helped me.

muslera

Now it works!! What a "stupid" issue... I hadn't read anything about these properties in any forum, millions of thank-yous CustomDev, you're the best!  :)


muslera

Your program is very interesting, thank you very much for your comment  :).


framauro

thanks, it worked also for me  :)
board: arduino micro
PC: xp sp3
program: written in WPF using class SerialPort, 9600,8,n,1
configured with Handshake None but RtsEnable and DtsEnable both set to true!

PaulS

Quote
I finally got it working, after reading a large number of postings. The issue is with the DTREnable and RTSEnable properties set to false, they need to be set to true, even though there is no handshake (HandShake: none), the virtual port requires this to trigger the data retrieval.
I hope this helps you as it helped me.

This is ONLY true for the Leonardo. All earlier versions of Arduinos do not require that DtrEnable be true.


Go Up