cancel
Showing results for 
Search instead for 
Did you mean: 

Displaying the values read by ADC (ADC, DAC, sinewave, PLL...)

antoine
Associate II
Posted on July 05, 2016 at 16:18

Hi.

My DAC is able to output a sine, and I would like to configure my ADC. Someone told me it was ridiculous to send a sine to the ADC, because the ADC performs a sine, so I would have the sine of a sine. Is it true ?

There is an example about looping the DAC on the ADC, but it uses the output of the ADC as an input for the DAC, and DAC output as ADC input. I would like to control what happens in there, what are the values the ADC read. My printf already works. How can I have a readable display? I mean, the DAC gets values like 4095, 1.. Is it possible for me to have something this clear from the ADC?

In fact, I'm absolutely not sure if I'm doing this right, and if it possible I would like to have some advice.

Here is the thing: I want to do more or less half of a PLL: I receive two signals on two ADCs , they're potentially filtered if needed, and they're compared by a phase detector which outputs the delta of the two phases. This value is later used as an input in a VCO, which sends the signal to the DAC, which outputs a sinewave.

So, is it in fact possible to write a phase detector in C?

Do i have to use the integrated PLL? If so, how does it work? From my observation, it is used as a clock , so is it possible to use one of its function, like the PID or/and the phase detector?

Also, in order to read the output of the ADC, I studied an old code that uses 4 LEDs to display the output in binary. I don't have 4 LEDs on my stm32 F334R8. I want to adapt it for printf, if it's still relevant regarding my previous question, but just considering the ADC_Config part I have many errors.

ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Interleave;

// 2 ADC Interleaved

ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

// 72 MHz / 2 = 36 MHz ADCCLK

ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;

// ADC 1 then 2

ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_18Cycles;

// 2 MSps (36/18 = 2)

ADC_CommonInit(&ADC_CommonInitStructure);

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

ADC_InitStructure.ADC_ScanConvMode = DISABLE;

// 1 Channel

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

// Hard timed with ADCCLK

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

// Ignored

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

// Ignored

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfConversion = 1;

ADC_Init(ADC1, &ADC_InitStructure);

/* ADC1 regular channel 12 configuration */

ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_15Cycles);

// PC2 (3 or 15 cycles, less than 18-2)

ADC_Init(ADC2, &ADC_InitStructure);

/* ADC2 regular channel 12 configuration */

ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_15Cycles);

// PC2

For example, ADC_Prescaler doesn't exist. I think I can replace it with ADC_Clock.

But for the TwoSamplingDelay part, the example gives me ''ADC_TwoSamplingDelay_18Cycles;'', while the definition of the structure says it accepts values between 0x0 and 0xF. What is the link between these two?

Thank you.

8 REPLIES 8
Posted on July 05, 2016 at 18:22

I'm pretty sure that printf'ing data across a USART/SWD link is not going to have enough bandwidth to show anything useful real-time. You could send a buffer of a few thousand samples and plot that in Excel or something. For a device with an LCD plot the signal on that. ie sample data you have copied to a buffer, and isn't going to be overwritten by new data.

Feeding the data from the ADC to a DAC output should give you perspective you can view on a scope, you'd expect some phase shift based on the delays introduced by the system/processing.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antoine
Associate II
Posted on July 05, 2016 at 18:33

I don't have an LCD, so you tell me to fprintf in a file and then put the thousands of values in Excel? My, I now know how to perform simple printf, but not to write in a file...

Also, what about the PLL and the phase detector? Should I use it since I'm basically trying to realize a digital/analog PLL?

Posted on July 05, 2016 at 18:55

Not exactly, I'm telling you to buffer enough of the waveform real-time that you can then send to the host, enmass, and view it in a manner that you are familiar with  (Excel, GNU Plot, etc). Sending one sample at a time, as the ADC delivers them, is not a good strategy.

The ADC/DAC can be combined to achieve all manner of functionality, and signal processing, I'm not looking to wade into that here.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antoine
Associate II
Posted on July 06, 2016 at 13:56

Ok, and... any hint on how to perform this buffer thing?

Also, to be clear: are we talking about putting values in a buffer, then unload the buffer into a file, then reading the file with Excel etc., or is it buffering the values and reading them directly with the chosen program (in which case I didn't know it was even possible)?

Posted on July 06, 2016 at 19:39

Allocate an array with several thousand entries, point the DMA from the ADC into this array. Send the data in the array from the embedded system to the terminal of your host. Record this data stream to a file, or cut-n-paste it from the terminal window. Format it in a way that is usable by you, using tools you understand (Excel, LabView, MatLab, ...)

The embedded system doesn't have a concept of files, or storage mediums, unless you explicitly implement them.

I'd probably use an ASCII comma delimited data format, like .CSV, the sort of thing Excel would import, or you could get a Perl or Python script to read and process.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antoine
Associate II
Posted on July 08, 2016 at 16:57

Hi, 

I used a mix of the two examples [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/stm32f4%20adc%20dma%2014%20analog%20inputs&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=260]you provided in this topic, but the result is... I don't really know.

I have an array of 3000 slots, with the DMA linking the ADC to the array. That was the first example, with the LEDs. The second example used printf instead with no DMA, so I put the printf part in the while loop in the main function. I have hexa value (in the format 000), but I only have 2921 values in the end, and after several attempts I can confirm that I have a value with four characters (instead of 3) that pops in the middle of the list, but always at the same place.

Also, after displaying the 2921 values the code keeps running but stays in the HardFault_Handler(void) function. 

So obviously there is something I've done wrong. Can you guide me?

I did this because I was unable to go further to the path you hinted me.

About that, can you give me more information about the .csv you were talking about, how to create it...?

Posted on July 08, 2016 at 17:11

https://en.wikipedia.org/wiki/Comma-separated_values

May be you can specify what data analysis and programming/processing tools you have familiarity with? Do your colleagues have any preferences or recommendations?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antoine
Associate II
Posted on July 08, 2016 at 17:51

Oh, thank you. 

Well, I know nothing about python or perl. My colleagues aren't involved, it is just for me to be sure the data are handled as they're supposed to be. It is just so I can control what actually happened after the ADC since I can't use a visual process like an oscilloscope like I did for the DAC.

I... know nothing about data analysis. I use Excel like a highschooler and I'm not good with Matlab. 

I wanted to do that because I thought it could be quite easy (after all, printf in debugger is just about some typical lines to implement), but it looks like it's more difficult than I expected...

The purpose of all this is to know what goes inside the phase detector (yet to be written) and what comes out.