Я создаю программу для работы с некоторым оборудованием с использованием последовательного порта. У меня есть документация, где есть сведения о том, как отправить команду через порт. Он работает очень хорошо, но я должен получить некоторую информацию о состоянии оборудования. Я пробовал все, но я не уверен в этом развитии. Может быть, я что-то пропустил.SerialPort отправить команду и получить ответ
Из документации:
Есть полностью 21 команды, 20 команд открытия, 1 команда чтения состояния
Открыть команду:
Адрес команды фиксированное значение (0x55) блокировка номер
Адрес 0XF2 0x55 0x01
Адресная s 0XF2 0x55 0X02
Адрес 0XF2 0x55 0x03
......
Над выполнение команд
Успех возвращается: Адрес + 0x59 + 0x59
неудачи возвращает: Адрес + 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 Как получить все состояния? В настоящее время я ничего не получаю.
Документация:
Команда чтения состояние блокировки: Адрес + Data1 + Data2 + Data3 Адрес: 0XF10X55 Data1 Data2 Data3 0000 lock20 ... lock17 lock16 ... lock9 lock8 ... Lock1 Первые 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 Еще раз спасибо. –
Если вы хотите синхронно общаться, вы можете позвонить 'Read' после того, как вы напишете, пока не получите свой ответ. Обратите внимание, что это может заблокировать ваше приложение навсегда, если ответа нет. Использование WaitHandle с таймаутом действительно может быть лучшим решением. –