Hi,
I am having problem with reading data from multiple serial ports on same form.
I have 1 form with 2 serial port objects on that. Both serial ports connected to diffrent printing devices and handles send and receive of data for devices. These printing device expects data to be print in such a way that once you send data you have to wait for response from device and then and only then you can send next data.
Here is summary of my code:
I am assigning port details to both ports in form initialization
On button click I am sending data to both ports one by one.
There are two functions SendDatatoVIN() (which sends data to first serial port and waits for response and once it receives response it will send next data.) and SendDatatoHeadstock() (which sends data to secound serial port and waits for response and once it receives response it will send next data)
public
enum VINPortStatus { None, LaunchCode, VINNumber, Para1, Para2, Para3, Para4, Para5, VINDone };private
enum HeadstockPortStatus { None, LaunchCode, HeadstockNumber, Para1, Para2, Para3, Para4, Para5, HeadstockDone };private
SerialPort VINcomport = new SerialPort(); private SerialPort Headstockcomport = new SerialPort();public
VINPortStatus objVINPortStatus; private HeadstockPortStatus objHeadstockPortStatus;private
byte[] m_IncomingRawData = new byte[280]; private byte[] m_IncomingData = new byte[280]; private int m_IncomingRawDataCount = 0;public
frmVINScan(){
InitializeComponent();
setscreen();
checkPortAvailability();
}
private void checkPortAvailability()
{
if (VINcomport.IsOpen) VINcomport.Close();//MarkerIO is a XML file which have parameter details of ports
MarkerIO objmarkerIO = new MarkerIO(); // Set the port's settingsVINcomport.NewLine =
"\r";VINcomport.BaudRate =
int.Parse(objmarkerIO.iBaudVIN);VINcomport.DataBits =
int.Parse(objmarkerIO.iDataBitsVIN);VINcomport.StopBits = (
StopBits)Enum.Parse(typeof(StopBits), objmarkerIO.iStopBitsVIN);VINcomport.Parity = (
Parity)Enum.Parse(typeof(Parity), objmarkerIO.iParityVIN);VINcomport.PortName = objmarkerIO.sComPortVIN;
if (Headstockcomport.IsOpen) Headstockcomport.Close();
Headstockcomport.NewLine =
"\r";Headstockcomport.BaudRate =
int.Parse(objmarkerIO.iDataBitsChassis);Headstockcomport.DataBits =
int.Parse(objmarkerIO.iDataBitsChassis);Headstockcomport.StopBits = (
StopBits)Enum.Parse(typeof(StopBits), objmarkerIO.iStopBitsChassis);Headstockcomport.Parity = (
Parity)Enum.Parse(typeof(Parity), objmarkerIO.iParityChassis);Headstockcomport.PortName = objmarkerIO.sComPortChassis;
}private
void btnAccept_Click(object sender, EventArgs e){
StampandPrint();
}
private
void StampandPrint(){
btnAccept.Enabled =
false;btnReject.Enabled =
false;Log(
LogMsgType.Outgoing, "##############################################################" + "\n");Log(
LogMsgType.Outgoing, "Stamp and print function starting " + "\n");Log(
LogMsgType.Outgoing, "Time Stamp : " + DateTime.Now.ToString() + "\n");Log(
LogMsgType.Outgoing, "##############################################################" + "\n"); if (objMarkingType == MarkingType.VIN || objMarkingType == MarkingType.VINandLable){
try{
VINcomport.Open();
Log(
LogMsgType.Outgoing, "VIN port test successfully..." + "\n");}
catch (Exception ex){
Log(
LogMsgType.Outgoing, "VIN port test unsucessful... reason : " + ex.Message.ToString() + "\n");}
SendDataToVIN();
lblStatusData.Text = m_ResourceMain.GetString(
"VINSTAMPCOMPLETED", LoginUserInfo.iCultureInfo); //if (VINcomport.IsOpen) VINcomport.Close();}
if (objMarkingType == MarkingType.Lable || objMarkingType == MarkingType.VINandLable){
SendDatToPrinter();
}
objMarkingType =
MarkingType.Headstock;try
{
Headstockcomport.Open();
Log(
LogMsgType.Outgoing, "Headstock port test successfully..." + "\n");}
catch (Exception ex){
Log(
LogMsgType.Outgoing, "Headstock port test unsucessful... reason : " + ex.Message.ToString() + "\n");}
SendDataToHeadstock();
if (Headstockcomport.IsOpen) Headstockcomport.Close();Log(
LogMsgType.Outgoing, "##############################################################" + "\n");Log(
LogMsgType.Outgoing, "Stamp and print function finished " + "\n");Log(
LogMsgType.Outgoing, "Time Stamp : " + DateTime.Now.ToString() + "\n");Log(
LogMsgType.Outgoing, "##############################################################" + "\n");lblStatusData.Text = m_ResourceMain.GetString(
"HEADSTOCKCOMPLETED", LoginUserInfo.iCultureInfo);setscreen();
}
private
void SendDataToVIN(){
// Send the user's program selection command to device string s1 = "\x1B" + "\x05" + "\x30" + "\x31" + "\x0D"; if (objItemmast.Count > 0){
try{
Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");Log(
LogMsgType.Outgoing, "Starting VIN Stamping " + "\n");Log(
LogMsgType.Outgoing, "Port Name : " + VINcomport.PortName.ToString() + "\n");Log(
LogMsgType.Outgoing, "Port Status : " + VINcomport.IsOpen.ToString() + "\n");Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");VINcomport.Write(s1);
Log(
LogMsgType.Outgoing, "Program selection command sent to comport: " + s1 + "\n");objVINPortStatus =
VINPortStatus.LaunchCode; while (objVINPortStatus != VINPortStatus.None){
System.Threading.
Thread.Sleep(500);System.Windows.Forms.
Application.DoEvents(); if (VINcomport.IsOpen && VINcomport.BytesToRead > 0){
m_IncomingRawDataCount = VINcomport.BytesToRead;
VINcomport.Read(m_IncomingRawData, 0, m_IncomingRawDataCount);
// show the hex bytes received string s = ""; for (int i = 0; i < m_IncomingRawDataCount; i++)s += m_IncomingRawData
.ToString(
t += (
char)int.Parse(m_IncomingRawDataLog(
LogMsgType.Outgoing, "Data received from port: " + s + " " + t + "\n"); if (objVINPortStatus == VINPortStatus.LaunchCode){
string s2 = "\x1B" + "\x07" + "\x0D";VINcomport.Write(s2);
Log(
LogMsgType.Outgoing, "Launch code sent to comport: \n");objVINPortStatus =
VINPortStatus.VINNumber;}
else if (objVINPortStatus == VINPortStatus.VINNumber){
VINcomport.WriteLine(lblVIN.Text);Log(
LogMsgType.Outgoing, "VIN Number sent to comport: " + lblVIN.Text + "\n");objVINPortStatus =
VINPortStatus.Para1; } else if (objVINPortStatus == VINPortStatus.Para1){
VINcomport.WriteLine(objItemmast[0].PARA_1);Log(
LogMsgType.Outgoing, "Para - 1 sent to comport: " + objItemmast[0].PARA_1 + "\n");objVINPortStatus =
VINPortStatus.Para2;}
else if (objVINPortStatus == VINPortStatus.Para2){
VINcomport.WriteLine(objItemmast[0].PARA_2);Log(
LogMsgType.Outgoing, "Para - 2 sent to comport: " + objItemmast[0].PARA_2 + "\n");objVINPortStatus =
VINPortStatus.Para3;}
else if (objVINPortStatus == VINPortStatus.Para3){
VINcomport.WriteLine(objItemmast[0].PARA_3);Log(
LogMsgType.Outgoing, "Para - 3 sent to comport: " + objItemmast[0].PARA_3 + "\n");objVINPortStatus =
VINPortStatus.Para4;}
else if (objVINPortStatus == VINPortStatus.Para4){
VINcomport.WriteLine(objItemmast[0].PARA_4);Log(
LogMsgType.Outgoing, "Para - 4 sent to comport: " + objItemmast[0].PARA_4 + "\n");objVINPortStatus =
VINPortStatus.Para5;}
else if (objVINPortStatus == VINPortStatus.Para5){
VINcomport.WriteLine(objItemmast[0].PARA_5);Log(
LogMsgType.Outgoing, "Para - 5 sent to comport: " + objItemmast[0].PARA_5 + "\n");objVINPortStatus =
VINPortStatus.VINDone;}
else if (objVINPortStatus == VINPortStatus.VINDone){
Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");Log(
LogMsgType.Outgoing, "VIN Stamping finish" + "\n");Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");objVINPortStatus =
VINPortStatus.None;}
}
}
}
catch (Exception ex){
Log(
LogMsgType.Outgoing, "VIN stamp exception : " + ex.Message.ToString() + "\n");}
}
}
private
void SendDataToHeadstock(){
try{
// Program selection command for device
string s1 = "\x1B" + "\x05" + "\x30" + "\x34" + "\x0D"; if (objTemplateIO.ProgramSelection == "")Log(
LogMsgType.Outgoing, "unable to read selection program from template.ini\n"); else{
Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");Log(
LogMsgType.Outgoing, "Starting Headstock stamping " + "\n");Log(
LogMsgType.Outgoing, "Port Name : " + Headstockcomport.PortName.ToString() + "\n");Log(
LogMsgType.Outgoing, "Port Status : " + Headstockcomport.IsOpen.ToString() + "\n");Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");Headstockcomport.Write(s1);
Log(
LogMsgType.Outgoing, "Program selection command sent to comport: " + s1 + "\n");objHeadstockPortStatus =
HeadstockPortStatus.LaunchCode; while (objHeadstockPortStatus != HeadstockPortStatus.None){
System.Threading.
Thread.Sleep(500);Log(
LogMsgType.Outgoing, "waiting for device response" + "\n");Log(
LogMsgType.Outgoing, "Port Status : " + Headstockcomport.IsOpen.ToString() + "\n");Log(
LogMsgType.Outgoing, "Bytes in Buffer : " + Headstockcomport.BytesToRead.ToString() + "\n"); if (Headstockcomport.IsOpen && Headstockcomport.BytesToRead > 0){
m_IncomingRawDataCount = Headstockcomport.BytesToRead;
Headstockcomport.Read(m_IncomingRawData, 0, m_IncomingRawDataCount);
// show the hex bytes received string s = ""; for (int i = 0; i < m_IncomingRawDataCount; i++)s += m_IncomingRawData
.ToString(
t += (
char)int.Parse(m_IncomingRawDataLog(
LogMsgType.Outgoing, "Data received from port: " + s + " " + t + "\n"); if (objHeadstockPortStatus == HeadstockPortStatus.LaunchCode){
string s2 = "\x1B" + "\x07" + "\x0D";Headstockcomport.Write(s2);
Log(
LogMsgType.Outgoing, "Launch code sent to comport: " + "1B " + "07 " + "0D" + " " + s2 + "\n");objHeadstockPortStatus =
HeadstockPortStatus.HeadstockNumber;}
else if (objHeadstockPortStatus == HeadstockPortStatus.HeadstockNumber){
Headstockcomport.WriteLine(lblVIN.Text);
Log(
LogMsgType.Outgoing, "(Headstock)VIN Number sent to comport: " + lblVIN.Text + "\n");objHeadstockPortStatus =
HeadstockPortStatus.HeadstockDone;}
else if (objHeadstockPortStatus == HeadstockPortStatus.HeadstockDone){
Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");Log(
LogMsgType.Outgoing, "Headstock Stamping finish" + "\n");Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");objHeadstockPortStatus =
HeadstockPortStatus.None;}
}
}
}
}
catch (Exception ex){
Log(
LogMsgType.Outgoing, "Headstock stamp exception : " + ex.Message.ToString() + "\n");}
}
private
void frmVINScan_FormClosing(object sender, FormClosingEventArgs e){
if (VINcomport.IsOpen)VINcomport.Close();
if (Headstockcomport.IsOpen)Headstockcomport.Close();
}
Now My problem is that first serial port communication (SendDatatoVIN) is done fine and device successfully doing the printing. But secound serial port communicaiton (SendDatatoHeadstock) is not working. No data is received from device at all.
Please can anybody tell me what is the problem here(is anything to deal with threading or any problem with multiple port communication)
Looking forward for response.

problem with multiple serial ports
U_T_A
Personally I would create a class for each port you want to communicate that encapsulates the port itself. I would also use events to communicate info back to your form. Create the ports and attach to the events you decare for each on the form and then connect and start sending and hopefully reciving.
So each class would have a structure something like this
public delegate void OnMessageRecieved(object sender, some data you want to pass.....);
public event OnMessageRecieved MessageRecieved;
public void Connect()
{
try
{
// Create new serial port on selected comm
mPort = new SerialPort(mPortName, mBaudRate, mParity, mDataBits,mStopBits);
// Add the event Handler
mPort.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);
// Open the port
mMPS2000Port.Open();
}
catch (Exception exception)
{
// re - throw with more info
throw new Exception("Cannot connect to " + mPortName, exception);
}
}
private void OnDataReceived(object sender, SerialDataReceivedEventArgs received)
{
// Read all the data from the port
string messageData = mPort.ReadExisting();
// Concatenate with any existsing data --
mMessage += messageData;
// Check you have a complete message - you can't guarentee all info has been recieved.
if (check for end of message)
{
// Do what you want to do with the message data......
// Raise events back to the form
if (this.MessageRecieved != null)
{
MessageRecieved(this, the message data);
}
// Clean the message buffer
mMessage = "";
}
}
public bool Send(string message)
{
// Create the return
bool sent = false;
Byte[] messageBytes = System.Text.Encoding.ASCII.GetBytes(message.ToCharArray());
// Write the message onto the port
mPort.Write(messageBytes, 0, messageBytes.Length);
// set the sent flag
sent = true;
// return
return sent;
}
RemcoJVG
These may sound like silly questions, but...
Have you tried without sending anything to VIN
Have you tried running 2 copies with 1 talking to VIN the other to Headstock
Have you definitiately got someting connected to the port you are talking on Opening the port does not require anything to be connected to it like other protocols (On numerous occasions I have started debugging only to realise that the port I connected to was not the one I though it was :) )
You have a lot of debug info in there which could provide more detail as to what is going on, unless someone else can spot an obvious error.
tizza2k
Thanks for response. I have already tried VINcomport_DataReceived and Headstockcomport_DataReceived events but I had big problem with event not getting fired everytime.
For you reference see this code which I have implemented before doing this.
private
void VINcomport_DataReceived(object sender, SerialDataReceivedEventArgs e){
this.Invoke(new EventHandler(Handle_VINcomport_DataReceived));}
private
void Handle_VINcomport_DataReceived(object sender, EventArgs e){
string VINPortResponse = VINcomport.ReadExisting();Log(
LogMsgType.Incoming, "Data received from port: " + VINPortResponse); if (objVINPortStatus == VINPortStatus.LaunchCode){
string s1 = "\x1B" + "\x07" + "\x0D";VINcomport.Write(s1);
Log(
LogMsgType.Outgoing, "Launch code sent to comport: \n");objVINPortStatus =
VINPortStatus.VINNumber;objWait.DisplayMessage =
"Sending launch code to VIN controller...";objWait.Status =
PortStatus.VINNumber;}
else if (objVINPortStatus == VINPortStatus.VINNumber){
VINcomport.WriteLine(lblVIN.Text);
Log(
LogMsgType.Outgoing, "VIN Number sent to comport: " + lblVIN.Text + "\n");objVINPortStatus =
VINPortStatus.Para1;objWait.DisplayMessage =
"Sending VIN number to VIN controller...";objWait.Status =
PortStatus.VINPara1;}
else if (objVINPortStatus == VINPortStatus.Para1){
VINcomport.WriteLine(objItemmast[0].PARA_1);Log(
LogMsgType.Outgoing, "Para - 1 sent to comport: " + objItemmast[0].PARA_1 + "\n");objVINPortStatus =
VINPortStatus.Para2;objWait.DisplayMessage =
"Sending parameter-1 to VIN controller...";objWait.Status =
PortStatus.VINPara2;}
else if (objVINPortStatus == VINPortStatus.Para2){
VINcomport.WriteLine(objItemmast[0].PARA_2);Log(
LogMsgType.Outgoing, "Para - 2 sent to comport: " + objItemmast[0].PARA_2 + "\n");objVINPortStatus =
VINPortStatus.Para3;objWait.DisplayMessage =
"Sending parameter-2 to VIN controller...";objWait.Status =
PortStatus.VINPara3;}
else if (objVINPortStatus == VINPortStatus.Para3){
VINcomport.WriteLine(objItemmast[0].PARA_3);Log(
LogMsgType.Outgoing, "Para - 3 sent to comport: " + objItemmast[0].PARA_3 + "\n");objVINPortStatus =
VINPortStatus.Para4;objWait.DisplayMessage =
"Sending parameter-3 to VIN controller...";objWait.Status =
PortStatus.VINPara4;}
else if (objVINPortStatus == VINPortStatus.Para4){
VINcomport.WriteLine(objItemmast[0].PARA_4);Log(
LogMsgType.Outgoing, "Para - 4 sent to comport: " + objItemmast[0].PARA_4 + "\n");objVINPortStatus =
VINPortStatus.Para5;objWait.DisplayMessage =
"Sending parameter-4 to VIN controller...";objWait.Status =
PortStatus.VINPara5;}
else if (objVINPortStatus == VINPortStatus.Para5){
VINcomport.WriteLine(objItemmast[0].PARA_5);Log(
LogMsgType.Outgoing, "Para - 5 sent to comport: " + objItemmast[0].PARA_5 + "\n");Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");Log(
LogMsgType.Outgoing, "VIN Stamping finish" + "\n");Log(
LogMsgType.Outgoing, "------------------------------------------" + "\n");objVINPortStatus =
VINPortStatus.None;objWait.DisplayMessage =
"Sending parameter-5 to VIN controller...";objWait.Status =
PortStatus.VINDone;}
}
In this case problem I got is that event gets fired for Program selection and then for VINNumber but after that event is not getting fired and my program didn't work any more.
I have noticed that at a time only 1 device is able to respond to my current implementation. As I am able to communicate with VIN or Headstock but not both
Tell me if you need more information...
William Lowers
Yes I can send data to 2nd port and receive from it if I connect one port to application and another to hyper terminal.
I got some success and now I am able to send and receive data from both ports but not simultaneously. I have to Open first port and complete the cycle ot it first and close ot. Then I can open 2nd port and complete cycle for that.
Important thing is I can not open both ports together....and process data together as I have told you that DataReceived event are not getting fired.
c_shah
Thanks for response. As I said in last message that I have tried attaching events to both serial ports. But as I said datareceived events are not getting fired everytime and that is why I have done code without datareceived events.
I agree with you that I must create a separate class but this is test applicaiton which must run successfully, after that I will create separate class for each port as you suggested.
FOCUS: Problem is that when I open both ports and send data to first port it is working fine and for 2nd port I am not receiving data. BytesToRead always show 0 ....
If I open just 1 port and test single device everything working fine.... but when I try to open 2 ports and want to send data to then one by one ... first port response perfectly but 2nd port is not responsing.....
Looking forward for your response
osamaT
I'm at a bit of a loss I'm afraid, so more questions...
Are the message you send on the 2nd port deing recieved by the device
Does this work fine if you have one port attached via your code and send/recieve to the other over hyper terminal
Hopefully someone else might chip in with some other ideas.