У меня есть входящий байтовый массив в реальном времени, который имеет следующий формат:
Заголовок: 3 байта
Сообщение: 10 байтов
Заголовок: 3 байта
сообщение: 10 байт
и т. Д.
Проблема в том, что это непрерывный поток, который я не могу предсказать, когда придет заголовок, поскольку я мог бы начать читать входящие байты с часть сообщения или заголовка. Поэтому я был бы признателен, если бы кто-нибудь мог помочь мне в том, как перехватить заголовок и затем остаться в синхронизации c, используя событие dataReceived.
Редактировать: я пытался использовать счетчик для проверки каждого входящего байта в качестве заголовка, затем установите порог срабатывания после получения полезной нагрузки.
- Установите входной порог срабатывания на 1 байт
- Проверьте первый, второй заголовки
- Получите полезную нагрузку, если заголовки обнаруживаются и устанавливаются триггер входящего порогового значения для полезной нагрузки.
- Анализируют полезную нагрузку, снова устанавливают пороговое значение равным 1 байту.
Несмотря на то, что это не плохо, это не надежно с каждым входящим кадры в отличие от программного обеспечения, такие как serialplot
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte data = 0;
if (_syncCounter < 3)
{
data = (byte)_serialPort.ReadByte();
}
switch (_syncCounter)
{
case 0: // First Byte in Header
_syncCounter = data == (byte)0xAA ? (byte) 1 : (byte) 0;
break;
case 1: // Second Byte in Header
_syncCounter = data == (byte)0xBB ? (byte)2 : (byte)0;
break;
case 2:
// Payload
_syncCounter = data == (byte)data ? (byte)3 : (byte)0;
if (_syncCounter == 3)
{
_serialPort.ReceivedBytesThreshold = data;
_payload = data;
}
break;
case 3:
// Packet
var packet = Enumerable.Repeat((byte)0x00, _payload).ToArray();
byte[] fieldBytes;
float fieldFloat;
_serialPort.Read(packet, 0, _payload);
if (packet.Length < _payload)
{
_serialPort.ReceivedBytesThreshold = 1;
_syncCounter = 0;
_payload = 0;
}
else
{
if (_isFirstPayload)
{
_syncCounter = 0;
_payload = 0;
_isFirstPayload = false;
break;
}
for (uint i = 0; i <= (_payload-1); i += 4)
{
fieldBytes = Slice(packet, i, i+4);
fieldFloat = ReadSingleBigEndian(fieldBytes, 0);
if (fieldFloat < 0)
fieldFloat = 0;
_sb.Append(fieldFloat.ToString(CultureInfo.InvariantCulture));
_sb.Append(",");
}
IncomingFrame.BeginInvoke(() =>
{
IncomingFrame.Text = ByteArrayToString(packet);
if (_sb.Length > 0)
{
_sb.Remove(_sb.Length - 1, 1);
FloatFields.Text = _sb.ToString();
}
_sb.Clear();
_serialPort.ReceivedBytesThreshold = 1;
_syncCounter = 0;
});
}
break;
}
}
Проблема в том, что иногда я получаю заголовок как часть полезной нагрузки, хотя из кода, который я написал, он должен быть отфильтрован перед чтением полезной нагрузки .
Я проверил тот же ответ, используя serialplot, и он синхронизируется, что означает, что аппаратное обеспечение отправляет данные в соответствии с ожиданиями и анализируется правильно.