I am currently trying to receive and process serial data from an STM32F401CCU6. I am receiving binary data from the STM over USB and I would like to re-assemble the raw data into what was originally transmitted. Here is how the data is broken down before transmission over USB:
- A 12-BIT ADC measurement value is stored in a 16-bit unsigned integer.
- During transmission, the 16-bit unsigned integer is transmitted as two 8-bit integers.
- The source of the data is a linear array sensor which outputs an array of readings - array size is 3694 (CCD) pixels
The following is how I have declared the buffer variable for holding the ADC data on the STM32:
#define CCDBuffer 6000
volatile uint16_t CCDPixelBuffer[CCDBuffer];
On the receiving end, I am using Python and the PySerial library to read the serial port. I am able to read individual bytes using the ser.read() function in PySerial. I want to know how to read the data in the right way.
- Considering the buffer variable declaration on the STM32, how many bytes should I read in one iteration in Python?
- How do I know which bytes to parse together to form the 16-bit integer?
- How do I know the index of the value that I will be parsing together? i.e. which pixel this number is from?
- Should I read 2 consecutive bytes, storing them in separate variables and then perform a shift operation on the first byte before concatenating?
I am really confused and could really use some guidance. Thanks in advance for taking the time to read.
2 Answers 2
#define CCDBuffer 6000
doesn't have any size by itself it just means 6000
every time you use it.
volatile uint16_t CCDPixelBuffer[CCDBuffer];
uint16_t
is guaranteed 16 bits, 6000 of them will be 6000 times larger.
Considering the buffer variable declaration on the STM32, how many bytes should I read in one iteration in Python?
12000
How do I know which bytes to parse together to form the 16-bit integer?
you need to figure out when the data starts and ends somehow... from there it's just counting.
How do I know the index of the value that I will be parsing together? i.e. which pixel this number is from?
by counting.
Should I read 2 consecutive bytes, storing them in separate variables and then perform a shift operation on the first byte before concatenating?
use struct.unpack
https://docs.python.org/3/library/struct.html
-
\$\begingroup\$ Thank you for the structured answer! I appreciate the time you have put into answering this. I will resume working on this now. I will look at the docs for struct.unpack. Thanks a lot! \$\endgroup\$Harit– Harit2022年10月04日 11:42:20 +00:00Commented Oct 4, 2022 at 11:42
I can't solve your problem for you, but I have a few comments that are too big to fit in the "comments" section:
How do I know which bytes to parse together to form the 16-bit integer?
If I had programmed your microcontroller, I either would have been given a protocol specification to implement, or else I would have invented a protocol and produced its specification and checked it into git alongside the source code.
A protocol specification should tell you everything you need to know about the bytes that flow back and forth on the wire. If you haven't got one, then you should ask for one. Who programmed the microcontroller? If it was you, then you are the only person who can answer your own question. If it was somebody else, then that's who you need to talk to. If you can't talk to them, then you probably can "reverse engineer" it by reading the source code. If you can't get the source code, but you have some other device that successfully talks to the microcontroller, then maybe you can reverse engineer the protocol by spying on the bytes that go over the wire between the two devices.
How do I know the index of the value that I will be parsing together? i.e. which pixel this number is from?
Jasen said, "...it's just counting." That's probably true. What's guaranteed true is that the protocol specification tells you how you know which bytes are from which pixels. Jasen probably is right: The protocol spec probably says that you will have to count the bytes.
Should I read 2 consecutive bytes, storing them in separate variables and then perform a shift operation on the first byte before concatenating?
That's entirely up to you. You almost certainly will have to read bytes two at a time, and you will have to shift one member of each pair* before adding them together. But it doesn't really matter where you store the intermediate values. That's just a matter of style.
* Maybe you'll shift the first byte received if the bytes are transmitted in big endian order. Or, maybe you'll shift the second one if the bytes are sent in little endian order. It's in the protocol specification.
-
\$\begingroup\$ Thanks so much for the detailed and structured response! I will try to determine the protocol specification. I appreciate the time you have put into answering my question. Thanks a lot! \$\endgroup\$Harit– Harit2022年10月04日 11:43:48 +00:00Commented Oct 4, 2022 at 11:43
CCDBuffer
in your example is not a variable whose value is the number,6000
. It is an alias for the text, "6000". The compiler interprets the second line of your example exactly as if you had writtenvolatile uint16_t CCDPixelBuffer[6000];
\$\endgroup\$