Использование кольцевого буфера для считывания данных из последовательного порта
В настоящее время я использую байт[] для хранения ответа, отправленного последовательным портом.
Но необходимо хранить данные в круговом буфере (используя круговой буфер, предоставленный на GitHub) и по мере поступления данных в него
1.если данные получены не полностью, отбросьте их.
2.взять какие-то данные
3.и разберите его так, как E0 означает начало данных.
В основном круговая буферная операция-это то, что я ищу?
Что я уже пробовал:
Вот это буфера
using CircularBuffer; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SerialPortCommunicationWithStateMachines { public class DataReceiveHandle { public static int MAX_PACKET_LENGTH = ChannelDataCount.count; public bool newData = false; public int rxOffset = 0; public byte[] rxBuffer = new byte[MAX_PACKET_LENGTH]; public byte[] rxPackage = new byte[MAX_PACKET_LENGTH]; public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { // var xbuffer = new CircularBuffer<byte>(10); if (e.EventType != SerialData.Chars) return; SerialPort port = (SerialPort)sender; int bytesCount = port.BytesToRead; port.Read(rxBuffer, rxOffset, bytesCount); rxOffset = rxOffset + bytesCount; if (HasCompletePackage()) { Console.WriteLine("Full packet has been received"); rxBuffer.CopyTo(rxPackage, 0); rxOffset = 0; newData = true; } if (newData == true) { if (rxPackage[0] == 224 && rxPackage[1] == 242 && rxPackage[2] == 1 && rxPackage[3] == 0 && rxPackage[4] == 60 && rxPackage[5] == 37 && rxPackage[6] == 133 && rxPackage[7] == 0 && rxPackage[8] == 0) { Console.WriteLine("Header Content is:"); for (int i = 0; i <= 8; i++) { Console.WriteLine(rxPackage[i]); } } Console.WriteLine("Message Content is: "); for (int i = 9; i < MAX_PACKET_LENGTH; i++) { Console.WriteLine(rxPackage[i]); } } } private bool HasCompletePackage() { if (rxOffset == 60) return true; else return false; } } }
Mehdi Gholam
А ваш вопрос таков?
Nishikant Tayade
@MehdiGholam, поскольку по умолчанию отсутствует реализация циклического буфера
Как я могу прочитать данные,отправленные последовательным портом в циклический буфер(предоставленный на Git), чтобы прочитать их, разобрать их?
относительно деталей:
https://stackoverflow.com/questions/49593013/how-can-i-read-and-calculate-serial-port-with-circular-buffer-c-sharp
Nishikant Tayade
@MehdiGholam не могли бы вы поделиться решением или другим выходом из этой проблемы прямо сейчас?
Richard MacCutchan
Вам нужно ответить человеку, с которым вы хотите связаться.
Patrice T
Чтобы ответить на комментарий, используйте кнопку "ответить" слева от имени пользователя (поверх комментария).
Nishikant Tayade
Хорошо.Не могли бы вы помочь мне сейчас?
Eric Lynch
Looking at your attempted implementation, you are missing a few elements. With a circular buffer, one would expect your pointer rxOffset to proceed towards the end of the buffer (at buffer size) wrapping (or resetting) to the start. You seem to be missing logic to consider this case. Typically, a circular buffer would also have two pointers, which "chase" each other. One indicates where you next add data to the buffer and the other indicates where you next remove data from the buffer (aka read/write). You would also need to add logic to handle buffer overflow, mb making sure the write pointer doesn't overtake the read pointer. Finally, you probably need to handle a partial read at the buffer boundary (when a wrap occurs)...dividing your read into two parts. I have bad connectivity right now, or I'd include some sample code. I'd just Google it. It's a well-established, fairly simple pattern. There should be truckloads of samples / explanations available.
Смотрите: https://en.m.wikipedia.org/wiki/Circular_buffer
Смотрите также: http://geekswithblogs.net/blackrob/archive/2014/09/01/circular-buffer-in-c.aspx
Nishikant Tayade
@EricLynch решение,которое вы предоставили, совершенно верно, в моем классе связи последовательного порта я использую новую реализацию кольцевого буфера, предоставленную на GitHub
https://github.com/xorxornop/RingBuffer/blob/master/PartiallyConcurrent/RingBuffer.cs
Я не знаю, сколько байт пакета я получу, и это главная проблема, поэтому я пытаюсь использовать круговой/кольцевой буфер,
открытый класс DataReceiveHandle
{
public static int MAX_PACKET_LENGTH = ChannelDataCount.count;
public static bool newData = false;
public static int rxOffset = 0;
public static int rxWrite = 0;
public static int rxRead = 0;
public static byte[] rxBuffer = новый байт[MAX_PACKET_LENGTH];
public static byte[] rxPackage = новый байт[MAX_PACKET_LENGTH];
общественная статический недействительным DataReceivedHandler(объект отправителя, SerialDataReceivedEventArgs е)
{
if (e.EventType != SerialData.Chars) возврат;
Последовательный порт Порт = (последовательный порт)отправителя;
int bytesCount = порт.BytesToRead;
port.Read(rxBuffer, rxOffset, bytesCount);
SequentialRingBuffer rBuffer = новый SequentialRingBuffer(4096, rxBuffer, true);
rxWrite=rBuffer.CurrentLength;
// rxOffset = rxOffset + bytesCount;
byte[] tempArray = новый байт[256];
tempArray=rBuffer.Метод toArray();
foreach (байтовый элемент в tempArray)
{
Приставка.WriteLine(item);
}
}
Я попробовал другой способ, но не смог сделать правильную реализацию, не могли бы вы взглянуть на него?
Gerry Schmitz
И точка вашего "кругового буфера" - это...?
Я нахожу много "интересных" предметов в Princess Auto, хотя и не всегда знаю, для чего они предназначены.