1
\$\begingroup\$

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:

  1. A 12-BIT ADC measurement value is stored in a 16-bit unsigned integer.
  2. During transmission, the 16-bit unsigned integer is transmitted as two 8-bit integers.
  3. 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.

asked Sep 2, 2022 at 10:23
\$\endgroup\$
9
  • 4
    \$\begingroup\$ I don't think the question is answerable as it is right now. We don't know how the data is sent by your STM, so we can't tell you how to parse it. Normally if you send 16 bit values over serial, you decide if they are sent high byte first, or low byte first (big endian or little endian). This determines how you combine them back together afterwards. If I were you, I would first connect a normal serial terminal program to the serial port and look at the data coming from the STM. chances are good you can see there how it is sent. \$\endgroup\$ Commented Sep 2, 2022 at 10:38
  • 7
    \$\begingroup\$ Your variables are not declared as macros (whatever that means). You have an array of 6000 16-bit integers. If you want to know the size in bytes, use sizeof(). It will likely be 12000. \$\endgroup\$ Commented Sep 2, 2022 at 10:49
  • 1
    \$\begingroup\$ Create a test buffer and send/receive it. It should contain sections you can use to identify the bit order, byte order etc, and data related in some simple way to the address. This lets you identify and correct any misunderstandings. \$\endgroup\$ Commented Sep 2, 2022 at 11:01
  • 1
    \$\begingroup\$ "During transmission, the 16-bit unsigned integer is transmitted as two 8-bit integers." - how? \$\endgroup\$ Commented Sep 2, 2022 at 11:22
  • 4
    \$\begingroup\$ "Variables declared as macros" doesn't make any sense. Macros in the C programming language work entirely by text substitution, and entirely at compile-time. The 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 written volatile uint16_t CCDPixelBuffer[6000]; \$\endgroup\$ Commented Sep 2, 2022 at 13:56

2 Answers 2

3
\$\begingroup\$

#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

answered Sep 2, 2022 at 23:35
\$\endgroup\$
1
  • \$\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\$ Commented Oct 4, 2022 at 11:42
1
\$\begingroup\$

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.

answered Sep 3, 2022 at 0:05
\$\endgroup\$
1
  • \$\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\$ Commented Oct 4, 2022 at 11:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.