问题描述
我有一个VB6项目,我想在C#应用程序中迁移它。
在VB6项目中,MSCOMM.OCX用于通信。
如果我在C#应用程序中使用相同的MSCOMM控件那么它可以工作,但我想用串行类来实现它然后我没有得到正确的响应(得到?在某些字节,因此响应不正确)。
代码与mscomm
Hi,
I have one VB6 project and I want to migrate it in C# application.
In VB6 project MSCOMM.OCX is used for communication.
If I used same MSCOMM control in C# application then it works but I want to implement this with serial class then I am not getting correct response ( get ? at some bytes and so response is not correct).
code with mscomm
private void button1_Click(object sender, EventArgs e)
{
try
{
axMSComm1.Settings = "9600,N,8,1";
axMSComm1.CommPort = 1;
axMSComm1.DTREnable = true;
axMSComm1.RTSEnable = true;
axMSComm1.PortOpen = true;
send_open_session_command();
Application.DoEvents();
analyse_response();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
axMSComm1.PortOpen = false;
}
axMSComm1.PortOpen = false;
}
private void axMSComm1_OnComm(object sender, EventArgs e)
{
switch (axMSComm1.CommEvent)
{
case 0:
case 1:
break;
case 2:
readbuffer = axMSComm1.Input.ToString();
response_flg = true;
string hexOutput = "";
foreach (char _eachChar in readbuffer)
{
int value = Convert.ToInt32(_eachChar);
hexOutput += String.Format("{0:X}", value);
}
MessageBox.Show(hexOutput);
return;
}
}
public void analyse_response()
{
string check_status;
Polling_Timer.Enabled = true;
while (response_flg == false)
{
Application.DoEvents();
if (timeout_flg == true)
{
cmd_status_flg = false;
MessageBox.Show("Communication with the controller failed");
return;
}
}
Polling_Timer.Enabled = false;
}
private void Polling_Timer_Tick(object sender, EventArgs e)
{
if (retry_attempts >= no_of_trials)
{
Polling_Timer.Enabled = false;
no_of_trials = 0;
retry_attempts = 0;
timeout_flg = true;
return;
}
if (timeout_flg == false)
{
retry_attempts = retry_attempts + 1;
received_response = "";
axMSComm1.Output = sent_command;
}
}
private void send_open_session_command()
{
timeout_flg = false;
MessageBox.Show("open session command");
string command = "08011001108148";
string checksum_value = calculate_checksum(command);
command = command + checksum_value;
string comd = "";
string temp_str;
int temp_dec;
for (int counter = 0; counter < command.Length; counter += 2)
{
temp_str = command.Substring(counter, 2);
temp_str = ParseHexString(temp_str);
temp_dec = Convert.ToInt32(temp_str);
comd = comd + (char)(temp_dec);
}
command = ":" + comd ;
sent_command = command;
axMSComm1.RThreshold = 17;
axMSComm1.Output = (sent_command);
analyse_response();
if (cmd_status_flg == true)
{
session_open_flg = true;
}
}
带串口类的代码
code with serial port class
private void button1_Click(object sender, EventArgs e)
{
try
{
ObjSerilaPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
ObjSerilaPort.DtrEnable = true;
ObjSerilaPort.RtsEnable = true;
ObjSerilaPort.Open();
// ObjSerilaPort.ReceivedBytesThreshold = 1;
ObjSerilaPort.DataReceived += new SerialDataReceivedEventHandler(ObjSerilaPort_DataReceived);
send_open_session_command();
Application.DoEvents();
resetParam(); }
catch (Exception ex)
{
MessageBox.Show(ex.Message);
ObjSerilaPort.Close();
}
ObjSerilaPort.Close();
}
private void ObjSerilaPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[ObjSerilaPort.ReceivedBytesThreshold];
int bytesRead = ObjSerilaPort.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
StringBuilder hex = new StringBuilder(buffer.Length * 2);
string str = System.Text.Encoding.Default.GetString(buffer);
string hexData = "";
foreach (char c in str)
{
int tmp = c;
hexData += String.Format("{0:X2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
}
received_response = hexData;
MessageBox.Show("Data Receive event \nData = "+hexData);
response_flg = true;
}
}
public void analyse_response()
{
string check_status;
polling_timer.Enabled = true;
while (response_flg == false)
{
Application.DoEvents();
if (timeout_flg == true)
{
cmd_status_flg = false;
MessageBox.Show("Communication with the controller failed");
return;
}
}
polling_timer.Enabled = false;
if (received_response != "")
{
check_status = received_response.Substring(received_response.Length - 4, 2);
if (check_status == "2E")
{
cmd_status_flg = true;
retry_attempts = 0;
}
else
{
response_flg = false;
polling_timer.Enabled = true;
}
}
}
private void polling_timer_Tick(object sender, EventArgs e)
{
if (retry_attempts >= no_of_trials)
{
polling_timer.Enabled = false;
no_of_trials = 0;
retry_attempts = 0;
timeout_flg = true;
return;
}
if (timeout_flg == false)
{
retry_attempts = retry_attempts + 1;
received_response = "";
ObjSerilaPort.Write(sent_command);
}
}
private void send_open_session_command()
{
timeout_flg = false;
MessageBox.Show("open session command");
string command = "08011001108148";
string checksum_value = calculate_checksum(command);
command = command + checksum_value;
string comd = "";
string temp_str;
int temp_dec;
for (int counter = 0; counter < command.Length; counter += 2)
{
temp_str = command.Substring(counter, 2);
temp_str = ParseHexString(temp_str);
temp_dec = Convert.ToInt32(temp_str);
comd = comd + (char)(temp_dec);
}
command = ":" + comd;
sent_command = command;
ObjSerilaPort.ReceivedBytesThreshold = 17;
ObjSerilaPort.Write(sent_command);
analyse_response();
if (cmd_status_flg == true)
{
session_open_flg = true;
}
}
推荐答案
int bytesRead = ObjSerilaPort.Read(buffer, 0, buffer.Length);
如果你希望得到buffer.Length字节,你可能会感到失望。我没有在SerialPorts上做过这个,但网络流等确实如此。
试试这个:
If you expect that you will get buffer.Length bytes though, you may be disappointed. I haven't done this on SerialPorts, but it is certainly the case with network streams etc.
Try this:
int bytesRead = ObjSerilaPort.Read(buffer, 0, buffer.Length);
while (bytesRead < buffer.Length)
{
byteRead += ObjSerilaPort.Read(buffer, bytesRead, buffer.Length - bytesRead);
}
这篇关于我如何使用MSCOMM的serail端口类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!