Spark Logic

Problems with regular simultaneous dual ADC conversion with DMA transfer

robca Tue Nov 24, 2015 5:06 pm

EDIT: I finally solved this, please see http://www.stm32duino.com/viewtopic.php … 8474#p8474 for more info

I’m at the end of my wits :? I have read the ADC and DMA docs at least 5 times each. Looked at the RegSimul_DualMode example from ST (and that was fun enough, since it uses completely different conventions than the Arduino/Maple libraries but in the end I understand what it does)… and I still can’t make it work… help, please.

Problem statement: on a Maple Mini, using STM32duino, convert 4 analog channels (connected to pins D3-D6, i.e. IN8-5, respectively) and transfer the data in memory using DMA (I need fast and predictable timing).

I basically would need to combine “dual simultaneous mode” with “continuous scan”, in order to capture ~2000 samples from each channel. But I fear it might not be possible, and the only mention I found is here (no reply, though) https://my.st.com/public/STe2ecommuniti … x?tags=adc

The code below sets a sequence for each ADC: in SQR1 sequence length is 1 (i.e. 2 conversions), and I set the SQR2 registers to have ADC1 convert IN8 while ADC2 converts IN7, then ADC1 convert IN6 while ADC2 converts IN5. I set regular (not injected) SW triggers.

After setting the ADC1 and ADC2 registers and the DMA1 Channel 1, in theory setting ADC1->regs->CR2 |= ADC_CR2_SWSTART; should start the conversion for the master ADC1 and slave ADC2 and in parallel start the DMA (one 32 bit DMA transfer for each conversion: in dual mode the ADC1 SR register holds both the values for ADC1 and ADC2).

What I noticed, though, is that when ADC_CR2_CONT is enabled, the ADC continuously scans, and the DMA keeps sending data to my buffer. What that means is the the order of the odd and even channels in the buffer can be off. Basically, when ADC_CR2_CONT is enabled, the ADC keeps scanning all the time, and that triggers DMA transfers in a random order.

If I don’t use ADC_CR2_CONT, I can only sequence a limited number of channels (and even if I repeat the sequence, I can only still do 16 conversions per ADC max (using SQR1-3). Or I can convert 2 channels (one on ADC1, one on ADC2) continuously in parallel…

But there seems no way to do scan and dual simultaneous at the same time… am I missing something? Any suggestion? If this doesn’t work, I can use two Maple Mini synchronized to capture 4 channels, but it makes everything harder to code (one as a master, one as a slave, with the conversion triggered at the same time, and transferring data)

Here’s my non-working code (if you uncomment the delay() statement you will see the problem)

EDIT: removed non-working code, see http://www.stm32duino.com/viewtopic.php?f=3&t=757&p=8474#p8474 for working code

Replies

mrburnette Fri Nov 27, 2015 3:05 pm

RogerClark wrote:My old DS1102D is quite a nice scope (though it looks a bit dated)

I was about to write that I don’t use 75% of the features…

So I fired it up and pressed the MATH button, and … It does do FFT !!

:lol: :lol: :lol:

robca Fri Nov 27, 2015 3:58 pm

RogerClark wrote:@robca

Ah.

I see what you mean.

Can you try editing the file that includes adc.h and add an include for dma.h and let me know if it causes any build problems.

If it works, let me know and I will update the core

zmemw16 Fri Nov 27, 2015 5:33 pm

@ahull
never practised as a mech eng :D

i was tempted to reply to someone with ‘as in a sonar waterfall display’
clue was in the ’60Hz signal and propeller blade 25Hz’ comment

the cat has just sat on my laptop table, its heaving down outside and she wants to go outside!
i thought she was going to crouch covering the mouse.

stephen

ahull Fri Nov 27, 2015 11:42 pm

robca wrote:
I ran some tests, and the critical place where adc.h is defined but dma.h is not is STM32F1\cores\maple\wirish_types.h (thanks to Andy for suggesting how to look into this).

robca Sat Nov 28, 2015 12:06 am

ahull wrote:robca wrote:
I ran some tests, and the critical place where adc.h is defined but dma.h is not is STM32F1\cores\maple\wirish_types.h (thanks to Andy for suggesting how to look into this).

robca Mon Nov 30, 2015 4:13 pm

Quick update:
  • 4 channel sampling works reliably at every sampling speed
  • I managed to write reasonably fast trigger code for 4 channels triggering, and quick sampling of all 4 channels after sampling
  • As expected, RAM is very tight. So instead of implementing a faster FFT-based cross correlation algorithm, I’m using a simple general cross correlation algorithm. Basically loops and multiplications, requiring no extra array. I can cross correlate 4 channels of 2048 samples in ~3 seconds. Slow, but not a killer for me. The FFT-based algorithms (like GCC PHAT) would operate much faster and provide better correlation in the presence of noise or with low volume signals, but would require 4x the memory or so. Even on processors with more RAM, I would need to store things temporarily in flash (or SD card). Since it would be nice to store all samples on SD card (for post-processing with better tools), adding an SD card is my next step

Which brings me to my next question. Is https://github.com/victorpv/SdFat the best SD card library for STM32duino? I looked at a few older posts, and there were a lot about non-working libraries, but no real “definitive” answer on a working one. It would be nice if an “official” SD card library could be added to the existing ones

Less relevant question: clearly the cheap eBay amplified microphones have serious limitations for sound capture (but are great for cheap prototyping). Does anyone know of a microphone/preamplifier that could be used for this project? I know that there are plenty of high quality microphones, but they all cost well above $50, which is well above the price point for this experiment. I will try replacing the crappy electret capsule on those with a decent one (like http://www.jlielectronics.com/products/JLI%252d61A.html, a clone of the well known Panasonic WM-61A, now obsolete), since the amplifier used by the cheap eBay modules is actually pretty good

ahull Mon Nov 30, 2015 10:48 pm

robca wrote:
Less relevant question: clearly the cheap eBay amplified microphones have serious limitations for sound capture (but are great for cheap prototyping). Does anyone know of a microphone/preamplifier that could be used for this project? I know that there are plenty of high quality microphones, but they all cost well above $50, which is well above the price point for this experiment. I will try replacing the crappy electret capsule on those with a decent one (like http://www.jlielectronics.com/products/JLI%252d61A.html, a clone of the well known Panasonic WM-61A, now obsolete), since the amplifier used by the cheap eBay modules is actually pretty good

robca Mon Nov 30, 2015 11:15 pm

I looked at a few “microphone builders” sites, and they were mostly recommending the Panasonic until 2013, then the clone after that (for cost effective microphones… some of those people seem to know what what are doing, and spend a ton of time building the microphone body, phantom power, etc, so I assume they have tested the real life perf of the capsule). The fact that is <$3 also makes it very interesting for me :)

I mostly need a capsule with low noise. As long as all the capsules pick up the same frequencies, my code works. I’m trying to build a pretty generic location engine, but most sounds that work well tend to be impulsive in nature: gunshots, clapping, knocks, etc. I trigger based on level, not frequency (would be impossible to do it quickly enough and still capture the samples). I keep sampling 4 channels for one cycle, and whatever channel gets above or below the trigger levels, it starts the 4CH conversion with 2048 samples per channel.

EDIT: the eBay capsules are the same as used on the modules. Cheap, low quality Chinese junk. Replacing them would make no difference. I’m sure that there are high quality Chinese capsules, but we won’t find them on eBay

Then I cross correlate, and spit out the samples and the correlation values (which sample is the most likely to start the same waveform as the trigger channel). Right now I simply plot them with GNUplot:

adc4ch.PNG
adc4ch.PNG (38.86 KiB) Viewed 779 times

RogerClark Tue Dec 01, 2015 1:05 am

Re: SD Lib

There is a thread about this a while ago, by @stevestrong

He got SD working much better

So search for his postings

Also, you should update to use the development branch of the repo as it has steve’s SD fixes

Cheers

Roger

robca Tue Dec 01, 2015 8:59 am

Thanks Roger

If I download https://github.com/rogerclarkmelbourne/ … master.zip I see that the files are from Nov 21. Is there a newer development branch? The thread you referred me to was around the end of October, so the Nov 21 files should be updated, right?

EDIT: I also just noticed the below in this page https://github.com/rogerclarkmelbourne/ … /Libraries

Latest SdFat, modified version from https://github.com/victorpv/SdFat seems to work fine. If you want the best performance for large transfers, can use DMA mode, but that requires the latest SPI Library from https://github.com/victorpv/Arduino_STM … raries/SPI . Does not need the updated SPI files if you don’t use DMA mode. DMA can be enabled or disabled editing SdSpiSTM32F1.cpp, read the file to know what to modify.

Is that info still correct? If not, might be worth updating the page

robca Tue Dec 01, 2015 9:35 am

ahull wrote:To save ram, and speed your calculations, could you scale your samples to 8 bit with some sort of dynamic range compression algorithm perhaps, and still get reliable results? How many samples do you think you will actually need to do the analysis?

ahull Tue Dec 01, 2015 10:15 am

robca wrote:I looked at a few “microphone builders” sites, and they were mostly recommending the Panasonic until 2013, then the clone after that (for cost effective microphones… some of those people seem to know what what are doing, and spend a ton of time building the microphone body, phantom power, etc, so I assume they have tested the real life perf of the capsule). The fact that is <$3 also makes it very interesting for me :)

I mostly need a capsule with low noise. As long as all the capsules pick up the same frequencies, my code works. I’m trying to build a pretty generic location engine, but most sounds that work well tend to be impulsive in nature: gunshots, clapping, knocks, etc. I trigger based on level, not frequency (would be impossible to do it quickly enough and still capture the samples). I keep sampling 4 channels for one cycle, and whatever channel gets above or below the trigger levels, it starts the 4CH conversion with 2048 samples per channel.

EDIT: the eBay capsules are the same as used on the modules. Cheap, low quality Chinese junk. Replacing them would make no difference. I’m sure that there are high quality Chinese capsules, but we won’t find them on eBay

Then I cross correlate, and spit out the samples and the correlation values (which sample is the most likely to start the same waveform as the trigger channel). Right now I simply plot them with GNUplot:

adc4ch.PNG

zmemw16 Tue Dec 01, 2015 1:05 pm

@ahull
<edit> for a testing data set, </edit>
don’t you just need a single recorded input, the other 3 signals can be generated from the separation distances
for the ‘mics’, maybe chuck in a rand call as noise.

i did something similar with a user specified function in a kernel device driver at work, level sensors show variation when taxi’ing.

stephen

robca Tue Dec 01, 2015 1:37 pm

Andy, here’s a file with real data (same as the plot I shared before), CH0 was the trigger channel. As I said, that tends to bunch all samples together, so it would be easy to assume you can cut the ending… but in real life even if 2 channels can be very close (if the sound is centered on those two), the other two would be time-shifted much later (easy to simulate by adding noise for the first 1024 samples for CH2 and CH3, and shifting the samples out by that much, for example)

Thanks for your help

stevestrong Tue Feb 02, 2016 8:15 pm

@robca
sorry for posting so late, but I just read this post and though I share some information with you.
We (my friend and I) are also working on something similar, up to 8 channels are converted quasi instantaneously (via sample-and-hold) in regular intervals given by a timer and stored on SD card in contiguous 512 byte blocks, several seconds long sampling.
The storing speed is mostly limited by the card write latency, we are using class 10 cards, capable of up to 80mbps, but still is very limiting.
Thus, the higher the channel number, the less the sampling frequency for the same amount of data.
Alternatively, in order to be able to store more data, we thought to implement a kind of delta compression: for a 512 byte block only store the first samples for each channel in full 12 bit resolution, for the following samples only the delta to the previous sample should be stored. Dependent on the sampling frequency, these deltas can be stored in 8 or 4 bit wide fields, saving ~ 55% or 70% of data storage space.
Problem: there is very high noise on the analog inputs when data is being stored on the card! We couldn’t get rid of it, no matter how intensively filtered, the noise (+-40lsb !!!) is still there. Also tried to make differential value from the useful samples, no solution, because it turned out that the noise is not always evenly distributed.
That’s why our next idea is to separate sampling and SD storage in time, to use one STM32 only as converter which is sending the acquired data (after sampling) via SPI to the second STM32 responsible to store/process the data. And this is the point where I am blocked currently, the slave SPI doesn’t want to work.
Any thoughts/comments on this?
For your interest, here is our project:
https://github.com/stevstrong/Audio-sample
My repos also contain the current SDfat and STM32 versions I am using.
There is also a folder named “tools”, I coded a web-based signal monitor GUI, and processing based application for data dumping over UART with up to 500kBauds.
Steve

ahull Fri Feb 05, 2016 10:06 pm

The noise may well be due in part to the design of some of these cheap boards. Lots of decoupling capacitors and if possible a separate analog ground might help.

stevestrong Fri Feb 05, 2016 10:52 pm

I tried capacitors, separated Vcc-A, nothing helped.
Ground couldn’t separate, on these cheap boards is not possible.
I saw on the original Leaflabs maple mini there are separated grounds and Vcc for analog and digital parts, very probably not without any reason.
The Baite clones and all other chinese boards have one common power supply for analog and digital, so it seems hopeless.
That’s why we tried the separated boards, which seems to confirm our strategy.
Meanwhile, the slave SPI started to work.

RogerClark Sat Feb 06, 2016 1:21 am

Steve

I have an iTead Studio Maple, which appears to be well made.

https://www.itead.cc/iteadmaple.html

They seem to have taken designed the board well, but I’m not sure about the separate analogue grounds. You could take a look at the schematic and confirm if it looks any better than the Baite Maple Mini

Schematic: ftp://imall.iteadstudio.com/IM120411012 … dmaple.pdf

At $5.80 its competatively priced. Its just a shame they use the STM32F103RBT not the STM32F103RET, ad the RET has DAC etc, at marginally extra cost.

RogerClark Mon Feb 08, 2016 12:52 am

OK

Its a shame they didnt do that, as they seem to have gone to a lot of trouble elsewhere on the board e.g. with the power supply being far more complicated than on the Maple mini etc

Sign in to reply