Click here to Skip to main content
15,877,754 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am currently using an byte[] to store the response send by the serial port.

But the need is to store the data into an circular buffer (using the Circular Buffer provided on GitHub) and as data come into it

1.if data is not fully received discard it.
2.take some data
3.and parse it like E0 means start of data.


Basically the Circular buffer operation is what I am looking for?

What I have tried:

Here is the Circular buffer

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;
        }
    }
    }
Posted
Updated 7-Jun-18 22:44pm
Comments
Mehdi Gholam 5-Jun-18 2:31am    
And your question is?
Nishikant Tayade 5-Jun-18 2:36am    
@MehdiGholam As there is no circular buffer implementation provided by default

How can i read the data send by serial port into Circular buffer(provided on Git) so to read it,parse it?

for details:
https://stackoverflow.com/questions/49593013/how-can-i-read-and-calculate-serial-port-with-circular-buffer-c-sharp
Nishikant Tayade 5-Jun-18 2:49am    
@MehdiGholam can you please share an solution or another way out of this problem now?
Richard MacCutchan 5-Jun-18 3:06am    
You need to Reply to the person you want to contact.
Patrice T 5-Jun-18 3:47am    
To reply to a comment, use the 'Reply' button on left of user name (on top of comment).

Note:
Answered this on a repost of this question but going to add it here as well because the repost might get deleted. Added also some more information.

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

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.

Assuming that you have a start sequence and a length field do this with each receiving:
  • Locate the start seqence if not detected so far
  • If start detected and enough following bytes has been received (length field present), get that
  • If length present, receive until all package bytes has been received
  • If a complete package data has been received, process the data
Note also that the above defines "states" as mentioned in an answer to your previous question.

If you think now about a possible implementation you might recognise that there is no need for a circular buffer. Using a "normal" buffer two times the size of the max. package length would be sufficient. All you need are class member variables (in bold because that is important here) for the current receive position (rxOffset), the start sequence position, the length, and optionally the state. Once a package has been received and processed, reset all those variable.
 
Share this answer
 
Comments
CPallini 8-Jun-18 5:53am    
5.
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
 

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