我正在创建一个程序,使用串行端口使用某些设备。我有文档详细说明如何通过端口发送命令。它工作得很好,但我应该得到关于设备状态的一些信息。我尝试了一切,但我对这些类型的开发没有信心。可能是我错过了一些东西。SerialPort发送命令并获得响应
从文档:
总共有21级的命令,20个命令是开口的,1个命令是读取状态
打开命令:
地址命令固定值(0x55的)锁号码
地址0XF2 0X55 0X01
地址小号0XF2 0x55的0X02
地址0XF2 0x55的0X03
......
以上命令执行
成功返回: 地址+ 0×59 + 0×59
故障恢复:地址+ 0X5E + 0X5E
/// <summary>
/// Send open lokcer door command
/// </summary>
/// <param name="boardAddress">0 means open left slave cabinet,1 means open right slave cabinet</param>
/// <param name="command"></param>
/// <returns></returns>
public byte[] OpenBox(byte boardAddress, byte command)
{
var openCommand = new byte[5];
openCommand[0] = (byte)(255 - boardAddress);
openCommand[0] = 0xF2;
openCommand[1] = 0x55;
openCommand[2] = command;
openCommand[3] = 0X00;
openCommand[4] = 0X00;
try
{
if (!serialPort.IsOpen)
{
//serialPort.WriteBufferSize = 5;
serialPort.Open();
}
serialPort.DiscardInBuffer();
serialPort.Write(openCommand, 0, 3);
return openCommand;
}
catch (ArgumentException ex)
{
throw new InvalidOperationException("Locker cell can not be opened.", ex);
}
}
它工作得很好,但最后2个字节没有返回。他们总是0X00。另外我使用SerialPortDataReceived,但我总是得到0。
public void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
DBException.WriteLog("");
DBException.WriteLog("Serial port data received");
var sp = (SerialPort)sender;
DBException.WriteLog("Read existing = " + sp.ReadExisting());
try
{
DBException.WriteLog("Length = " + sp.BytesToRead);
if (serialPort.BytesToRead == 4)
{
var readBuffer = new byte[4];
sp.Read(readBuffer, 0, serialPort.BytesToRead);
DBException.WriteLog("Read serial port :" + readBuffer.ByteArrayToString());
// RaiseLockerStatusEvent(readBuffer.ByteArrayToString());
}
}
catch (Exception ex)
{
DBException.WriteLog(ex);
}
}
问题1如何获得成功或失败的回报?我认为他们应该在最后2个字节。
问题2 如何获取所有状态?目前我什么也没有得到。
文档:
读锁定状态的命令:地址+数据1 +数据2 +数据3 地址:0XF10X55 数据1数据2数据3 0000 lock20 ... lock17 lock16 ... lock9 lock8 ...锁1 的前4位是固定的数字0000 样本: 0000 0000 0000 0001 0000 0001表示锁定1,锁定9打开,其他关闭 注意:对于某些类型的电子锁定,“1”表示关闭,“0”表示打开。
我的片段
/// <summary>
/// Send check machine(cabinet) status command
/// </summary>
/// <param name="address">0 means check left cabinet, 1 means check right cabinet </param>
/// <returns></returns>
public byte[] SendCheckLockControlStatueCommand(byte address)
{
lock (this)
{
var checkCommand = new byte[6];
checkCommand[0] = Convert.ToByte(255 - address);
checkCommand[1] = 0xF1;
checkCommand[2] = 0x55;
checkCommand[3] = 0x00;
checkCommand[4] = 0x00;
checkCommand[5] = 0x00;
try
{
if (!serialPort.IsOpen)
{
// serialPort.WriteBufferSize = 5;
serialPort.Open();
}
//Send inquiry command
serialPort.DiscardInBuffer();
// serialPort.DiscardOutBuffer();
serialPort.Write(checkCommand, 0, 6);
return checkCommand;
}
catch (ArgumentException ex)
{
throw new InvalidOperationException("Locker cell can not be opened.", ex);
}
}
}
非常感谢你。我想我正在进入它。但实际上我更喜欢同步沟通。我想我应该在SendingCommand方法中等待一段时间,然后再读取数据。你能解释一下吗?我会很感激。 –
我想我已经找到了从串口读取数据的正确答案。它会使用AutoResetEvent所有细节都在这里。 http://stackoverflow.com/questions/11782053/serialport-wait-for-response再次感谢。 –
如果你想同步交流,你可能想在Write之后调用Read,直到你有了答案。请注意,如果没有答案,这可能会永远阻止您的应用程序。超时使用WaitHandle确实是最好的解决方案。 –