Serial communication with C# program: SerialDataReceivedEventHandler doesnt work

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 :expressionless:

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
{
///


/// Variable del diseñador requerida.
///

private System.ComponentModel.IContainer components = null;

///


/// Limpiar los recursos que se estén utilizando.
///

/// true si los recursos administrados se deben eliminar; false en caso contrario, false.
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

///


/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
///

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! :slight_smile:

I am having exactly the same issue, no responses?

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.

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! :slight_smile:

Had a similar issue, read through the reasons and discussion here (SQL update using data collected by C# from Arduino Serial - Stack Overflow) for more information.

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

Happy to help...

thanks, it worked also for me :slight_smile:
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!

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.

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.

This solution worked really fine,

Just added serialPort1.RtsEnable = true; and serialPort1.DtrEnable = true; before opening the serial port on C# program.

Thanks a lot!

Absolute champ! I had this problem with the Arduino 101, this solved it!