Click here to Skip to main content
15,889,176 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I am developing an desktop application for serial port communication.The hardware connected to serial port sends the data in packet.

But the numbers of bytes in that packet is unknown,hence use of ring buffer.

there is no default implementation of circular/Ring Buffer in C#,that's why i am using one provided on GitHub https://github.com/xorxornop/RingBuffer/blob/master/PartiallyConcurrent/RingBuffer.cs

I want to save data into Ring Buffer as received and then parse it(like checking for header bytes,for device id,for status byte etc) and if it's not there then discard it.

I have tried various implementation but was unable to have an correct implementation.

What I have tried:

using CircularBuffer;
using CircularBufferCommunicationModification;
using OpenJobScheduler;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RingByteBuffer;

namespace SerialPortCommunicationWithStateMachines
{
    public class 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 = new byte[MAX_PACKET_LENGTH];

        public static byte[] rxPackage = new byte[MAX_PACKET_LENGTH];

        public static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            if (e.EventType != SerialData.Chars) return;

            SerialPort port = (SerialPort)sender;

            int bytesCount = port.BytesToRead;

            //reading all the bytes from port 
            int bufferSize = port.ReadByte();

            SequentialRingBuffer rBuffer = new SequentialRingBuffer(4096, rxBuffer, true);

            //puting the bytes from ports into ring buffer
            rBuffer.Put((byte)bufferSize);

            //ring buffer with two pointers so rxWrite will be pinting towards the poistion in ring buffer where there is last byte writing is done.
            //and if it is  end of circular buffer then should go back to first poistion and start writing there 
            rxWrite=rBuffer.CurrentLength;

            //now the rxRead should read byte from ring buffer one by one so to parse it.
            
            byte[] tempArray = new byte[256];
            tempArray=rBuffer.ToArray();
        }
    }
}
Posted
Updated 7-Jun-18 22:20pm
v2

I still don't think that there is a need for a ring buffer here.

However, if you want to use one, it must be defined at class level and not within your receive handler where it goes out of scope after each event.

You already have a buffer: rxBuffer. To make that a ring buffer all you have to do is handling the write access using rxOffset accordingly:
C#
// Check if we have to wrap to the begin of the buffer
int bytesToRead = min(bytesCount, rxBuffer.Length - rxOffset);
port.Read(rxBuffer, rxOffset, bytesToRead); 
rxOffset += bytesToRead;
if (rxOffset >= rxBuffer.Length)
{
    bytesToRead = bytesCount - bytesToRead;
    port.Read(rxBuffer, 0, bytesToRead); 
    rxOffset = bytesToRead;
}
Now you have a ring buffer. Depending on what to do with that you might implement a reader having another class level variable defining the current read position (and checking that rxOffset will not overrun that read position).

But implementing the above you might recognise that it does not solve your problem. Your problem is actually not how to implement a ring buffer but to define how the received data has to be handled (processed). That is a task which must be done before writing any line of code. Once you have defined that, you can think about possible implementations.
 
Share this answer
 
Quote:
there is no default implementation of circular/Ring Buffer in C#
And what do you think the Queue Class[^] is?
Quote:
This class implements a queue as a circular array. Objects stored in a Queue are inserted at one end and removed from the other.

Queues and stacks are useful when you need temporary storage for information; that is, when you might want to discard an element after retrieving its value. Use Queue if you need to access the information in the same order that it is stored in the collection ...
 
Share this answer
 
Comments
Richard MacCutchan 8-Jun-18 3:48am    
Repost, and you gave the same answer before.
OriginalGriff 8-Jun-18 4:10am    
Isn't copy'n'paste great?
I noticed the repost after I posted this, but I then forgot to delete the "new" version ... I need more coffee ...
I'll dispose of it now.
You already posted this at Using circular buffer for reading data from serial port[^], and received an answer. Please do not repost.
 
Share this answer
 
Comments
Richard Deeming 8-Jun-18 12:40pm    
You do know you can use the little red flag at the bottom-right of the question to report it as a repost, right? :)

(Mine was the first report.)
Richard MacCutchan 9-Jun-18 3:16am    
Yes, of course, but being "of a certain age", I do sometimes forget things. :(
Richard Deeming 9-Jun-18 10:10am    
Been there, got the t-shirt. Now if only I could remember where I put it! :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900