I'm working on some bluetooth-based arduino to c# (on computer) communication. A lot of the code I've been using was taken from examples, but here's the current situation.
When I send messages from my arduino to my computer, by writing to serial, they show up--I generally need to include a newline character, but that's not a big deal.
However, when I send messages to my arduino, it never even acknowledges that it got them. Any ideas on why this might be? Here's the relevant code.
(Note, I'm using an Arduino uno, and a basic serial bluetooth modem).
char inChar; // Where to store the character read
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
inChar = Serial.read();
Serial.write("processing message...\n");
}
}
Nothing is ever written to serial in this program, indicating that it never sees that it has stuff to read.
EDIT: Forgot to post the C# code. Whoops.
string message;
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
Thread readThread = new Thread(Read);
// Create a new SerialPort object with default settings.
_serialPort = new SerialPort();
// Allow the user to set the appropriate properties.
_serialPort.PortName = SetPortName(_serialPort.PortName);
_serialPort.BaudRate = SetPortBaudRate(_serialPort.BaudRate);
_serialPort.Parity = SetPortParity(_serialPort.Parity);
_serialPort.DataBits = SetPortDataBits(_serialPort.DataBits);
_serialPort.StopBits = SetPortStopBits(_serialPort.StopBits);
_serialPort.Handshake = SetPortHandshake(_serialPort.Handshake);
// Set the read/write timeouts
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_continue = true;
readThread.Start();
Console.WriteLine("Type QUIT to exit");
while (_continue)
{
message = Console.ReadLine();
if (stringComparer.Equals("quit", message))
{
_continue = false;
}
else
{
_serialPort.WriteLine(
String.Format(message));
}
}
readThread.Join();
_serialPort.Close();
}
The arduino code as it is will only read one byte from serial and continue the flow. You might want to replace your if statement with a while statement like so:
while (Serial.available() > 0)
{
inChar[i] = Serial.read();
i++;
}
Serial.write("processing message...\n");
This will put the received message in a char array. (You'd also need to declare inChar as an array e.g. - char inChar[8]; )
Other than that it should work unless there is something wrong with your C# code which I can't test right now but it looks fine.
Hope this helps.
Related
I am using .net 4.5 and since i got aware about some internet discussion about .net having wrong code implementation to rad serial data, i went with the code below.
The problems is however even despite i can see i create a COM port connection (to the right com port number), its never firing on data received.
The data receiving is based upon a simple Arduino app, (Arduino monitor does show data gets send over serial), but .net never seams to fire upon serial events.
I've put breakpoints on eventread, it never gets hit
i've looked at other discussions here like .NET SerialPort DataReceived event not firing but so far they don't resolve the issue i have. I tried various combination of serial line setups, and believe the below ones are correct.
as for Arduino part the line is setup as:
Serial.begin(9600);
I call my class like : `InfraredSensor mySens = new InfraredSensor("COM4",9600);'
class InfraredSensor
{
private string Eventlogapp = "IRlogging";
private SerialPort Port;
public InfraredSensor(string COMport, int baudrate) //constructor
{
if (applicationlog != "") this.EventlogSapec = applicationlog;
WriteEventLog(EventlogSapec, EventSource, "Initializing-IR:" + COMport, info, EventIRStarted);
// I found that the .net standard implementation for com port reading is not OK (.net doesnt follow win32 api).
// There are numerous readings about it, but a good way to read seams to be to use Serial BaseStream.ReadAsync
// code below is based upon : http://www.c-sharpcorner.com/code/2880/serial-port-with-efficient-data-reading-in-c-sharp.aspx
this.comport = COMport;
SerialPort Port = new SerialPort(comport);
Port.BaudRate = baudrate;
Port.DataBits = 8;
Port.Parity = Parity.None;
Port.StopBits = StopBits.One;
Port.Handshake = Handshake.None;
Port.NewLine = Environment.NewLine;
Port.ReceivedBytesThreshold = 2; // + linefeed
Port.DataReceived += ReadEvent;
Port.Open();
Port.DtrEnable = true;
// i've tested from here i do have an open connection
// its just dat ReadEvent never fires...
}
private void ReadEvent(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[2];//todo i only send "A" or "B", for the debug moment
Action kickoffRead = null;
kickoffRead = (Action)(() => Port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
{
try
{
int count = Port.BaseStream.EndRead(ar);
byte[] dst = new byte[count];
Buffer.BlockCopy(buffer, 0, dst, 0, count);
RaiseAppSerialDataEvent(dst);
}
catch (Exception ex)
{
WriteEventLog(Eventlogapp, "IR", "Failure-IR:" + ex.Message, info, 204);
}
kickoffRead();
}, null)); kickoffRead();
}
private void RaiseAppSerialDataEvent(byte[] Data)
{
// code never gets to here
string msg = Encoding.Default.GetString(Data);
int breakpointhere = 0;
if (msg.Contains('A')) WriteEventLog(Eventlogapp, "IR", "Sensor A", info, 213);
if (msg.Contains('B')) WriteEventLog(Eventlogapp, "IR", "Sensor B", info, 214);
}
}
I ran out of ideas (and hair as its driving me nuts) what could cause this behaviour ?
finally this took me 2 days ...
in arduino code i now use
serial.print("Mytext\n"); // using \n to be sure of escape character
for the serial line config i now use
this.comport = COMport;
this.Port = new SerialPort(comport);
this.Port.BaudRate = baudrate;
this.Port.DataBits = 8;
this.Port.Parity = Parity.None;
this.Port.StopBits = StopBits.One;
this.Port.Handshake = Handshake.None;
this.Port.RtsEnable = true;
// Port.NewLine = "\n";
// Port.ReceivedBytesThreshold = 2; // + linefeed
this.Port.DataReceived += new new SerialDataReceivedEventHandler(ReadEvent);
....
..
SerialDataReceivedEventHandler(ReadEvent);
//code didnt change inside but the method has changed see the +=
The DataReceived event fires when there is data coming through the serial port, but it can fire randomly. So you could get part of the message in one event and the other half of the message in another event. You should have some sort of key to know when you have the whole message. So build your string until you have the whole message then do something based on the message.
For example, my device's message is done when there is a Line Feed. So my code looks something like:
char ESC = (char)27;
char CR = (char)13;
char LF = (char)10;
StringBuilder sb = new StringBuilder();
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string Data = serialPort1.ReadExisting();
foreach (char c in Data)
{
if (c == LF)
{
sb.Append(c);
//we have our message, do something, maybe like
if (sb.ToString().Contains("A"))
{
//print A
}
else
{
//print B
}
}
else
{
sb.Append(c);
}
}
}
I am developing program which need to interact with COM ports.
By learning from this Q&A: .NET SerialPort DataReceived event not firing, I make my code like that.
namespace ConsoleApplication1
{
class Program
{
static SerialPort ComPort;
public static void OnSerialDataReceived(object sender, SerialDataReceivedEventArgs args)
{
string data = ComPort.ReadExisting();
Console.Write(data.Replace("\r", "\n"));
}
static void Main(string[] args)
{
string port = "COM4";
int baud = 9600;
if (args.Length >= 1)
{
port = args[0];
}
if (args.Length >= 2)
{
baud = int.Parse(args[1]);
}
InitializeComPort(port, baud);
string text;
do
{
String[] mystring = System.IO.Ports.SerialPort.GetPortNames();
text = Console.ReadLine();
int STX = 0x2;
int ETX = 0x3;
ComPort.Write(Char.ConvertFromUtf32(STX) + text + Char.ConvertFromUtf32(ETX));
} while (text.ToLower() != "q");
}
private static void InitializeComPort(string port, int baud)
{
ComPort = new SerialPort(port, baud);
ComPort.PortName = port;
ComPort.BaudRate = baud;
ComPort.Parity = Parity.None;
ComPort.StopBits = StopBits.One;
ComPort.DataBits = 8;
ComPort.ReceivedBytesThreshold = 9;
ComPort.RtsEnable = true;
ComPort.DtrEnable = true;
ComPort.Handshake = System.IO.Ports.Handshake.XOnXOff;
ComPort.DataReceived += OnSerialDataReceived;
OpenPort(ComPort);
}
public static void OpenPort(SerialPort ComPort)
{
try
{
if (!ComPort.IsOpen)
{
ComPort.Open();
}
}
catch (Exception e)
{
throw e;
}
}
}
}
My problem is DataReceived event never gets fired.
My program specifications are:
Just .net console programming
I use VSPE from http://www.eterlogic.com
My computer has COM1 and COM2 ports already.
I created COM2 and COM4 by using VSPE.
I get output result from mystring array (COM1, COM2, COM3, COM4)
But I still don't know why DataReceived event is not fired.
Updated
Unfortunately, I still could not make to fire DataReceived event in any way.
So, I created new project by hoping that I will face a way to solve.
At that new project [just console application], I created a class...
public class MyTest
{
public SerialPort SPCOM4;
public MyTest()
{
SPCOM4 = new SerialPort();
if(this.SerialPortOpen(SPCOM4, "4"))
{
this.SendToPort(SPCOM4, "com test...");
}
}
private bool SerialPortOpen(System.IO.Ports.SerialPort objCom, string portName)
{
bool blnOpenStatus = false;
try
{
objCom.PortName = "COM" + portName;
objCom.BaudRate = 9600;
objCom.DataBits = 8;
int SerParity = 2;
int SerStop = 0;
switch (SerParity)
{
case 0:
objCom.Parity = System.IO.Ports.Parity.Even;
break;
case 1:
objCom.Parity = System.IO.Ports.Parity.Odd;
break;
case 2:
objCom.Parity = System.IO.Ports.Parity.None;
break;
case 3:
objCom.Parity = System.IO.Ports.Parity.Mark;
break;
}
switch (SerStop)
{
case 0:
objCom.StopBits = System.IO.Ports.StopBits.One;
break;
case 1:
objCom.StopBits = System.IO.Ports.StopBits.Two;
break;
}
objCom.RtsEnable = false;
objCom.DtrEnable = false;
objCom.Handshake = System.IO.Ports.Handshake.XOnXOff;
objCom.Open();
blnOpenStatus = true;
}
catch (Exception ex)
{
throw ex;
}
return blnOpenStatus;
}
private bool SendToPort(System.IO.Ports.SerialPort objCom, string strText)
{
try
{
int STX = 0x2;
int ETX = 0x3;
if (objCom.IsOpen && strText != "")
{
objCom.Write(Char.ConvertFromUtf32(STX) + strText + Char.ConvertFromUtf32(ETX));
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
}
I am not sure that I face good luck or bad luck because this new class could make fire DataReceived event which is from older console application that is still running. It is miracle to me which I have no idea how this happen.
Let me tell you more detail so that you could give me suggestion for better way.
Finally I created 2 console projects.
First project is the class which I posted as a question yesterday.
Second project is the class called MyTest which could make fire DataReceived event from First project, at the same time when two of the project is running.
Could anyone give me suggestions on how could I combine these two projects as a single project?
ComPort.Handshake = Handshake.None;
The problem is not that the DataReceived event doesn't fire, the problem is that the serial port isn't receiving any data. There are very, very few serial devices that use no handshaking at all. If you set it to None then the driver won't turn on the DTR (Data Terminal Ready) and RTS (Request To Send) signals. Which a serial port device interprets as "the machine is turned off (DTR)" or "the machine isn't ready to receive data (RTS)". So it won't send anything and your DataReceived event won't fire.
If you really want None then set the DTREnable and RTSEnable properties to true. But it is likely you want HandShake.RequestToSend since the device appears to be paying attention to the handshake signals.
If you still have trouble then use another serial port program like Putty or HyperTerminal to ensure the connection and communication parameters are good and the device is responsive. SysInternals' PortMon utility gives a low-level view of the driver interaction so you can compare good vs bad.
I have never worked with VSPE so I'm not sure if that causes the problem. I have worked with a COM port before and I looked up my code. The only main difference is the way you declare the event. You have:
ComPort.DataReceived += OnSerialDataReceived;
I have it like this:
ComPort.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);
OnSerialDataReceived is your eventhandler. I'm not sure if this will make any difference, but you can try it. I hope this helps!
I had a quite similar problem. In a graphical application (C# win form) I had a class which encapsulate a SerialPort component. The DataReceived event was firing only one time, but then any following data received didn't fire any event. I solved the problem by calling the Close method in my principal form Closed event function.
No idea of why that changes anything, but now it's working.
Using Microsoft Visual Expres, Win Form Application
In my application I am sending data from PC to microcontroller via serial communication. It works like that: App from PC send data - microcontroller do his program - in the end of microcontrollers program send character to application - application receive character and send another data.
My problem is, when I wait for the character from microcontroller, whole App(in PC) becomes inactive(cant press any button or close the program).
Friend told me to try Threads. I tried to do it with thread(I am pretty new in threads). When I run my app it throw an exception: Acces to the port "COM6" is denied. It looks like that serial port is opened in one thread, before other thread close the port.
Is there any way to set the port as open for all threads?
Or any better ideas how to make my App active while waiting for response frommicrocontroller?
There are some lines of code with threads:
.
.
.
poslat(data_all); //sending data function
Thread t = new Thread(cakaj);
t.Start(); // start of thread cakaj
.
.
.
there is function for sending data
static void poslat(string data)
{
SerialPort COMport = new SerialPort();
COMport.PortName = "COM6";
COMport.BaudRate = 1200;
COMport.DataBits = 8;
COMport.Parity = Parity.None;
COMport.StopBits = StopBits.One;
COMport.Open();
COMport.Write(data);
COMport.WriteTimeout = 500;
COMport.Close();
}
function for waiting for a character from microcotroller
void cakaj()
{
SerialPort COMport = new SerialPort();
int byteRead;
COMport.PortName = "COM6"; //
COMport.BaudRate = 1200;
COMport.DataBits = 8;
COMport.Parity = Parity.None;
COMport.StopBits = StopBits.One;
COMport.Open(); //**Program points there with error message:Acces to the port "COM6" is denied.**
do
{
byteRead = COMport.ReadByte();
} while (byteRead != 75); // ASCII K = 75
t.Abort();
COMport.Close();
return;
}
You're creating two different instances of SerialPort COMport using the same port COM6. What you can do is make the COMport variable as a field for your class and access that in poslat and cakaj.
Also, you can instead use the DataReceived event instead of making another thread.
Your code will look something like this.
class YourClass
{
static SerialPort _COMport;
int byteRead; //make byteRead a field so you can also share it outside cakaj
SerialPort COMport //share COMport for poslat and cakaj
{
get
{
if(_COMport == null)
{
CreateCOMport();
}
return _COMport;
}
}
void CreateCOMport()
{
_COMport = new SerialPort();
_COMport.PortName = "COM6";
_COMport.BaudRate = 1200;
_COMport.DataBits = 8;
_COMport.Parity = Parity.None;
_COMport.StopBits = StopBits.One;
_COMport.DataReceived += cakaj;
//COMport will listen for any incoming data
//when there is data available, method cakaj will run
}
void poslat(string data)
{
if (!COMport.IsOpen)
{
COMport.Open();
}
COMport.Write(data);
COMport.WriteTimeout = 500;
}
void cakaj(object sender, SerialDataReceivedEventArgs e)
{
do
{
byteRead = COMport.ReadByte();
} while (byteRead != 75);
COMport.Close();
}
}
EDIT: remember to call COMport.Close() somewhere within this class.
I changed the approach and there are many ways to improve it but I think it will do the work...
If you want your Forms application's main thread to wait in a loop you have to make sure to give it the opportunity to handle events.
You can do that by modifying your waiting loop like this:
do
{
Application.DoEvents(); // handle Windows Forms events
byteRead = COMport.ReadByte();
} while (byteRead != 75); // ASCII K = 75
This will make sure your app can still respond to events while waiting.
Of course this is only necessary when it is your application's main thread that's waiting. Background threads don't have to do this and in fact they must not do it.
I am developing program which need to interact with COM ports.
By learning from this Q&A: .NET SerialPort DataReceived event not firing, I make my code like that.
namespace ConsoleApplication1
{
class Program
{
static SerialPort ComPort;
public static void OnSerialDataReceived(object sender, SerialDataReceivedEventArgs args)
{
string data = ComPort.ReadExisting();
Console.Write(data.Replace("\r", "\n"));
}
static void Main(string[] args)
{
string port = "COM4";
int baud = 9600;
if (args.Length >= 1)
{
port = args[0];
}
if (args.Length >= 2)
{
baud = int.Parse(args[1]);
}
InitializeComPort(port, baud);
string text;
do
{
String[] mystring = System.IO.Ports.SerialPort.GetPortNames();
text = Console.ReadLine();
int STX = 0x2;
int ETX = 0x3;
ComPort.Write(Char.ConvertFromUtf32(STX) + text + Char.ConvertFromUtf32(ETX));
} while (text.ToLower() != "q");
}
private static void InitializeComPort(string port, int baud)
{
ComPort = new SerialPort(port, baud);
ComPort.PortName = port;
ComPort.BaudRate = baud;
ComPort.Parity = Parity.None;
ComPort.StopBits = StopBits.One;
ComPort.DataBits = 8;
ComPort.ReceivedBytesThreshold = 9;
ComPort.RtsEnable = true;
ComPort.DtrEnable = true;
ComPort.Handshake = System.IO.Ports.Handshake.XOnXOff;
ComPort.DataReceived += OnSerialDataReceived;
OpenPort(ComPort);
}
public static void OpenPort(SerialPort ComPort)
{
try
{
if (!ComPort.IsOpen)
{
ComPort.Open();
}
}
catch (Exception e)
{
throw e;
}
}
}
}
My problem is DataReceived event never gets fired.
My program specifications are:
Just .net console programming
I use VSPE from http://www.eterlogic.com
My computer has COM1 and COM2 ports already.
I created COM2 and COM4 by using VSPE.
I get output result from mystring array (COM1, COM2, COM3, COM4)
But I still don't know why DataReceived event is not fired.
Updated
Unfortunately, I still could not make to fire DataReceived event in any way.
So, I created new project by hoping that I will face a way to solve.
At that new project [just console application], I created a class...
public class MyTest
{
public SerialPort SPCOM4;
public MyTest()
{
SPCOM4 = new SerialPort();
if(this.SerialPortOpen(SPCOM4, "4"))
{
this.SendToPort(SPCOM4, "com test...");
}
}
private bool SerialPortOpen(System.IO.Ports.SerialPort objCom, string portName)
{
bool blnOpenStatus = false;
try
{
objCom.PortName = "COM" + portName;
objCom.BaudRate = 9600;
objCom.DataBits = 8;
int SerParity = 2;
int SerStop = 0;
switch (SerParity)
{
case 0:
objCom.Parity = System.IO.Ports.Parity.Even;
break;
case 1:
objCom.Parity = System.IO.Ports.Parity.Odd;
break;
case 2:
objCom.Parity = System.IO.Ports.Parity.None;
break;
case 3:
objCom.Parity = System.IO.Ports.Parity.Mark;
break;
}
switch (SerStop)
{
case 0:
objCom.StopBits = System.IO.Ports.StopBits.One;
break;
case 1:
objCom.StopBits = System.IO.Ports.StopBits.Two;
break;
}
objCom.RtsEnable = false;
objCom.DtrEnable = false;
objCom.Handshake = System.IO.Ports.Handshake.XOnXOff;
objCom.Open();
blnOpenStatus = true;
}
catch (Exception ex)
{
throw ex;
}
return blnOpenStatus;
}
private bool SendToPort(System.IO.Ports.SerialPort objCom, string strText)
{
try
{
int STX = 0x2;
int ETX = 0x3;
if (objCom.IsOpen && strText != "")
{
objCom.Write(Char.ConvertFromUtf32(STX) + strText + Char.ConvertFromUtf32(ETX));
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
}
I am not sure that I face good luck or bad luck because this new class could make fire DataReceived event which is from older console application that is still running. It is miracle to me which I have no idea how this happen.
Let me tell you more detail so that you could give me suggestion for better way.
Finally I created 2 console projects.
First project is the class which I posted as a question yesterday.
Second project is the class called MyTest which could make fire DataReceived event from First project, at the same time when two of the project is running.
Could anyone give me suggestions on how could I combine these two projects as a single project?
ComPort.Handshake = Handshake.None;
The problem is not that the DataReceived event doesn't fire, the problem is that the serial port isn't receiving any data. There are very, very few serial devices that use no handshaking at all. If you set it to None then the driver won't turn on the DTR (Data Terminal Ready) and RTS (Request To Send) signals. Which a serial port device interprets as "the machine is turned off (DTR)" or "the machine isn't ready to receive data (RTS)". So it won't send anything and your DataReceived event won't fire.
If you really want None then set the DTREnable and RTSEnable properties to true. But it is likely you want HandShake.RequestToSend since the device appears to be paying attention to the handshake signals.
If you still have trouble then use another serial port program like Putty or HyperTerminal to ensure the connection and communication parameters are good and the device is responsive. SysInternals' PortMon utility gives a low-level view of the driver interaction so you can compare good vs bad.
I have never worked with VSPE so I'm not sure if that causes the problem. I have worked with a COM port before and I looked up my code. The only main difference is the way you declare the event. You have:
ComPort.DataReceived += OnSerialDataReceived;
I have it like this:
ComPort.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);
OnSerialDataReceived is your eventhandler. I'm not sure if this will make any difference, but you can try it. I hope this helps!
I had a quite similar problem. In a graphical application (C# win form) I had a class which encapsulate a SerialPort component. The DataReceived event was firing only one time, but then any following data received didn't fire any event. I solved the problem by calling the Close method in my principal form Closed event function.
No idea of why that changes anything, but now it's working.
I am developing program which need to interact with COM ports.
By learning from this Q&A: .NET SerialPort DataReceived event not firing, I make my code like that.
namespace ConsoleApplication1
{
class Program
{
static SerialPort ComPort;
public static void OnSerialDataReceived(object sender, SerialDataReceivedEventArgs args)
{
string data = ComPort.ReadExisting();
Console.Write(data.Replace("\r", "\n"));
}
static void Main(string[] args)
{
string port = "COM4";
int baud = 9600;
if (args.Length >= 1)
{
port = args[0];
}
if (args.Length >= 2)
{
baud = int.Parse(args[1]);
}
InitializeComPort(port, baud);
string text;
do
{
String[] mystring = System.IO.Ports.SerialPort.GetPortNames();
text = Console.ReadLine();
int STX = 0x2;
int ETX = 0x3;
ComPort.Write(Char.ConvertFromUtf32(STX) + text + Char.ConvertFromUtf32(ETX));
} while (text.ToLower() != "q");
}
private static void InitializeComPort(string port, int baud)
{
ComPort = new SerialPort(port, baud);
ComPort.PortName = port;
ComPort.BaudRate = baud;
ComPort.Parity = Parity.None;
ComPort.StopBits = StopBits.One;
ComPort.DataBits = 8;
ComPort.ReceivedBytesThreshold = 9;
ComPort.RtsEnable = true;
ComPort.DtrEnable = true;
ComPort.Handshake = System.IO.Ports.Handshake.XOnXOff;
ComPort.DataReceived += OnSerialDataReceived;
OpenPort(ComPort);
}
public static void OpenPort(SerialPort ComPort)
{
try
{
if (!ComPort.IsOpen)
{
ComPort.Open();
}
}
catch (Exception e)
{
throw e;
}
}
}
}
My problem is DataReceived event never gets fired.
My program specifications are:
Just .net console programming
I use VSPE from http://www.eterlogic.com
My computer has COM1 and COM2 ports already.
I created COM2 and COM4 by using VSPE.
I get output result from mystring array (COM1, COM2, COM3, COM4)
But I still don't know why DataReceived event is not fired.
Updated
Unfortunately, I still could not make to fire DataReceived event in any way.
So, I created new project by hoping that I will face a way to solve.
At that new project [just console application], I created a class...
public class MyTest
{
public SerialPort SPCOM4;
public MyTest()
{
SPCOM4 = new SerialPort();
if(this.SerialPortOpen(SPCOM4, "4"))
{
this.SendToPort(SPCOM4, "com test...");
}
}
private bool SerialPortOpen(System.IO.Ports.SerialPort objCom, string portName)
{
bool blnOpenStatus = false;
try
{
objCom.PortName = "COM" + portName;
objCom.BaudRate = 9600;
objCom.DataBits = 8;
int SerParity = 2;
int SerStop = 0;
switch (SerParity)
{
case 0:
objCom.Parity = System.IO.Ports.Parity.Even;
break;
case 1:
objCom.Parity = System.IO.Ports.Parity.Odd;
break;
case 2:
objCom.Parity = System.IO.Ports.Parity.None;
break;
case 3:
objCom.Parity = System.IO.Ports.Parity.Mark;
break;
}
switch (SerStop)
{
case 0:
objCom.StopBits = System.IO.Ports.StopBits.One;
break;
case 1:
objCom.StopBits = System.IO.Ports.StopBits.Two;
break;
}
objCom.RtsEnable = false;
objCom.DtrEnable = false;
objCom.Handshake = System.IO.Ports.Handshake.XOnXOff;
objCom.Open();
blnOpenStatus = true;
}
catch (Exception ex)
{
throw ex;
}
return blnOpenStatus;
}
private bool SendToPort(System.IO.Ports.SerialPort objCom, string strText)
{
try
{
int STX = 0x2;
int ETX = 0x3;
if (objCom.IsOpen && strText != "")
{
objCom.Write(Char.ConvertFromUtf32(STX) + strText + Char.ConvertFromUtf32(ETX));
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
}
I am not sure that I face good luck or bad luck because this new class could make fire DataReceived event which is from older console application that is still running. It is miracle to me which I have no idea how this happen.
Let me tell you more detail so that you could give me suggestion for better way.
Finally I created 2 console projects.
First project is the class which I posted as a question yesterday.
Second project is the class called MyTest which could make fire DataReceived event from First project, at the same time when two of the project is running.
Could anyone give me suggestions on how could I combine these two projects as a single project?
ComPort.Handshake = Handshake.None;
The problem is not that the DataReceived event doesn't fire, the problem is that the serial port isn't receiving any data. There are very, very few serial devices that use no handshaking at all. If you set it to None then the driver won't turn on the DTR (Data Terminal Ready) and RTS (Request To Send) signals. Which a serial port device interprets as "the machine is turned off (DTR)" or "the machine isn't ready to receive data (RTS)". So it won't send anything and your DataReceived event won't fire.
If you really want None then set the DTREnable and RTSEnable properties to true. But it is likely you want HandShake.RequestToSend since the device appears to be paying attention to the handshake signals.
If you still have trouble then use another serial port program like Putty or HyperTerminal to ensure the connection and communication parameters are good and the device is responsive. SysInternals' PortMon utility gives a low-level view of the driver interaction so you can compare good vs bad.
I have never worked with VSPE so I'm not sure if that causes the problem. I have worked with a COM port before and I looked up my code. The only main difference is the way you declare the event. You have:
ComPort.DataReceived += OnSerialDataReceived;
I have it like this:
ComPort.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);
OnSerialDataReceived is your eventhandler. I'm not sure if this will make any difference, but you can try it. I hope this helps!
I had a quite similar problem. In a graphical application (C# win form) I had a class which encapsulate a SerialPort component. The DataReceived event was firing only one time, but then any following data received didn't fire any event. I solved the problem by calling the Close method in my principal form Closed event function.
No idea of why that changes anything, but now it's working.