cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F401 Interpreting DMA data over serial

gulagman145
Associate II

Hi all,

I am pretty new to ST so bear with me.

The controller is reading in voltage values into the ADC and sending to PC over serial with

CDC_Transmit_FS((uint8_t*), buffer, buffer_length)

I'm getting the data stream, but the values as read in python for instance are b'\x03', b'\x04' with every other value being b'\x03'.

I am trying to figure out how to 'decode' the data for lack of a better word. What format is the data being sent? I'm assuming since it is direct from memory it is bytes (binary)? The code is set up to trigger the transmit function when the ADC conversion is completed, and the parameters I give would indicate the value is in 8-bit bytes for the entire buffer, but I am stymied by the formatting on the receive end.

Some reading indicates that the values shown may either be ascii or something presenting in that way due to how python interprets the data but this has been very difficult for me to figure out since I know next to nothing about direct memory access or ST functionality. When viewing the data in a serial monitor it comes through as a bunch of strange characters different from what I have in python too, not much help there.

Any guidance would be greatly appreciated!

 

 

8 REPLIES 8
PGump.1
Senior III

Hi,

Perhaps, encoding your ADC reading into either a hexadecimal or decimal string with a Null between each reading.

I hope that helps.

Kind regards
Pedro

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.
Ozone
Lead II

I would agree to PGump.1, avoid binary.
Serial communication is prone to data corruption, and you proably don't want one missed or corrupted character to spoil an entire transmission.

Using ASCII (i.e. printf()) introduces redundancy, which allows you to detect a lot of data corruption. Binary does not, i.e. every byte values would be possible.
And using lines separated with '\n', '\0' (or both) helps in this regard as well.

> Some reading indicates that the values shown may either be ascii or something presenting in that way due to how python interprets the data  ...

Not to mention, you would come across the endianness problem sooner or later.
I'm not much into Python, but reading/parsing ASCII data from a serial line is identical to reading them from a file.
If you use Unix/Linux as host OS, you would realize both are treated as files, and use the same functions (at least in C code).

Hi,

"Serial communication is prone to data corruption" I disagree with that statement.

Use a hexadecimal string with leading zeros, to maintain framing.

ALWAYS send hexadecimal string in bigendian format.

I hope that helps.

Kind regards
Pedro

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.

Hi Pedro,

Thanks for the reply.

Do you know if the transmit function would add any start or stop bits by itself?

If I assume not, then the data stream should be just the adc-converted data from memory.

In theory I should already have framing because the analog data input to the adc has its own framing due to the elements it is reading. 

Each discrete conversion from the adc should be sixteen bits values right? (12+4 zeroes)?


@gulagman145 wrote:

I am pretty new to ST 


Do you have experience with any other microcontrollers?

With programming in general ?

 


@gulagman145 wrote:

sending to PC over serial with

CDC_Transmit_FS((uint8_t*), buffer, buffer_length)


So that's USB?

Although the 'S' in "USB" does, indeed, stand for "Serial", when people say "serial" like that, it usually means UART...

 


@gulagman145 wrote:

Do you know if the transmit function would add any start or stop bits by itself??


You're using USB,  so: no.

 

PS:

Another advantage of sending your data as text is that you can view it in any terminal - without needing any special software at all.

Hi,

If sending via USB CDC, start and stops bits are not included. Neither is parity and baud.

 


In theory I should already have framing because the analog data input to the adc has its own framing due to the elements it is reading. 

I have no idea what you mean with the above statement.

 


Each discrete conversion from the adc should be sixteen bits values right? (12+4 zeroes)?

That will depend on how you have configured the ADC. The reason I suggested using a hexadecimal string with leading zeros is - the length of the string will be a constant (4 for a 16 bit conversion, 3 for a 12 bit conversion or 2 for a 8 bit conversion).

Kind regards
Pedro

 

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.
Techn
Senior III

Are you reading only one channel or multiple channels? When do you call the function CDC_Transmit_FS((uint8_t*), buffer, buffer_length)? how do you know that the convertion is completed before you call the cdc***

Usually for debugging purposes you can use sprintf with some message like "ADC value %d etc to show the demarcation, If your adc is 16bit wide you get two bytes , you need to interpret it either in stm32 or in python, It is better that you do the math in stm32, send the ascii to python, so it is easy to decode. 

If you feel a post has answered your question, please click "Accept as Solution".

Quick update:

I found part of the issue, the board I was using was at least partially damaged, I used a new one and I'm at least seeing values which roughly correspond to expectation

Still have some issues though namely that the values are sometimes erratic or behave almost as though the buffer values being sent over cdc_transmit_fs() are somehow being jumbled out of order.

Still have not ruled out PC-side problems.

Does anyone have experience with continuous single channel ADC DMA who could lend some insight? Board is stm32f401. I'm sending over UART (virtual com) using the adc conversion complete callback to initiate cdc_transmit_fs().

 

I'll supply some code when I'm back at my PC.