How to stream bytes from SerialPort (System.IO.Ports) into a chart.
I'm using WPF on .NET Framework 4.8.
The packet that I'm trying to catch is sent at 250Hz.
I was under the assumption
My current basic implementation is as follow:
On port.DataReceived, I will collect the data then store it to another buffer to further process it later (to deal with potential last unfinished packet by just queueing them).
I personally think this is hacky and non-efficient, is there a better existing approach that I'm not aware of?
10 Replies
this is pretty standard
how would you improve it
i got some problem with implementing it and had some trouble finding an existing implementation online, but it kinda sorted out for now.
i was thinking maybe there was already some way to just pull it packet by packet from the existing buffer of the port but I guess it is inherently this way.
the fact is serial is pretty raw so determining a strategy for reading from it may heavily depend on the protocol
for example if the first 2 bytes were the size of the message you would already know how big to allocate it
other than that, usually manifacturer should provide a client that implements the protocol
(but serial stuff is old or it is used in cheap devices so at most they give a pdf (if you are lucky) which hopefully tells you something about it)
The one I'm currently dealing with is pretty simple, first byte will be used as a header (documented in a PDF file) for each packet (data range from 0 to 7 bytes).
This one is pretty overwhelming to me tho, I asked for a demonstration app/source code from the supplier and all they said were "we currently only have the instruction set":
- Request data format
Command head + command word + length word + data filed + check word
Command head: two bytes, Default is 0X55, 0XAA
Command word: one byte
Length word: two bytes, indicate this command start from length word to check
words bytes (not include check word),low-order in front
Data filed: this option can be 0
Check word: Byte-by-byte XOR value from the command head to the last byte of the
data field
- Reply data format
Command head + command word + identifier word + length word + data field + check
word
Command head: two bytes, Default is 0x55,0xAA
Command head: one byte
Identifier word:one byte, 0x00 means response successfully, others means defeated
or error
Length word:two bytes,indicate this command start from length word to check
words’ bytes (not include check word),low-order in front
Data filed: this option can be 0
Check word: Byte-by-byte XOR value from the command head to the last byte of the
data field
seems pretty straightforward, there isn't even escaping needed
i would tell you just do it that it works, read data, parse the fields, even in the ugliest and fastest way you know of, but just verify that it works
then do it well
there are not details about the endianness of the fields, but hopefully it's the correct one already
(ps if you need help taking primitive types from byte[] there's
BitConverter.ToInt16
etc.; if you need to be aware of the endianness there is System.Buffers.Binary.BinaryPrimitives.ReadInt16LittleEndian
etc.)About parsing, my current flow is
1. loop through the buffer scanning for header
2. process/store the data based on the packet definition
3. (haven't implemented validation, but i guess i should put it here)
4. just prune everything til the last processed packet in the buffer.
That's it, right?
why the 4
It's queue, so I just delete anything I processed, no?
so you are saying you keep the packets in a queue instead of processing them immediately?
yeah. because it's the snippet to read from the port buffer
I keep this snippet as it is because I didn't know what else can I do.