m0xpd
Posts: 9
Joined: Sun Jan 06, 2013 2:27 pm

AD Conversion Speed

Sat Mar 23, 2013 8:34 am

I have been experimenting with a Microchip MCP3002 ADC, seeking to achieve sample rates appropriate for (low quality) audio frequency applications - perhaps in the ballpark of 20ksamples per second.

The 3002 is inherently capable of such rates - but I can get nowhere near them with Python on the RPi.

I started with "bit-banging", but could only achieve around 1k samples per second.

Then I switched to SPI, using 'spidev' - my code is here...

Code: Select all

#!/usr/local/bin/python
# MCP3002_SPI2.py
# learning to drive the MCP3002 Analog to Digital Converter...

import spidev
import os

spi=spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=4000000
a=[0]*1024
r=[0]*1024

# grab a block of 1024 samples (from channel 0)... 
for j in range (0,1024):
     r[j]=spi.xfer2([0x60,0])

# now convert the raw sample tuples into useful numbers...
for j in range (0,1024):
    rj=r[j]
    a[j]=((rj[0] & 3)<< 8) + rj[1]
    
print(a)
My code i) takes 1024 samples and then ii) converts them to numerical formal in the two "for" loops.

It works - but I still only achieve approximately 7k samples per second.

Changing the value of 'spi.max_speed_hz' does little to influence the conversion rate - so I conclude that I'm not limited by the SPI clock.

So - can anybody help me by explaining...

i) what is the origin of my speed limit? Is it Python? Is it the latency of calls to spidev? Is it RPi? Or is there some other fundamental limit?
ii) what speed might I realistically hope for?

and - perhaps most importantly -

iii) where do I find decent, usable documentation for spidev?

Thanks,
m0xpd

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5261
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: AD Conversion Speed

Sun Mar 24, 2013 8:12 pm

Hi m0xpd,
Since I'm not a python user so I can't help much but, because I hope to experiment with a "cousin" of your device, the MCP3008, your post "caught my eye". As a 'C' programmer I'm intending to make use of Gordon's Wiring Pi library's support for SPI (https://projects.drogon.net/raspberry-p ... i-library/) especially as I've already found other parts of that useful for an I2C device. I'm not sure whether python code is "interpreted" or "compiled". If it is the former then I would expect equivalent 'C' code, after compilation, to be faster, but that's not guaranteed, since some interpreted languages can end up being very "close to the machine code" eg. Forth running on a Z80-based Jupiter Ace (thus giving away my age :) ).
Trev.
Still running Raspbian Jessie or Stretch on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W, 2xP3A+, P3B+, P3B, B+, A+ and a B2) but Buster on the P4B's. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
[email protected]
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: AD Conversion Speed

Mon Mar 25, 2013 1:42 pm

The issue in the current kernels is latency over the SPI bus when using the spidev interface.

You will not get much more than 8000 samples/sec - I achieved that using the A/D on the Gertboard to sample a microphone.

You may get it faster if you poke the SPI hardware directly and avoid the kernel, however for sampling audio, you're really pushing it as without a proper "clock"/"interrupt" system to help you, you will not achieve a constant sampling rate.

However, I recently did this:

http://www.youtube.com/watch?v=uSCBj6rabIU

That's actually sampling at 4K samples/sec. for varous reasons.

-Gordon
--
Gordons projects: https://projects.drogon.net/

m0xpd
Posts: 9
Joined: Sun Jan 06, 2013 2:27 pm

Re: AD Conversion Speed

Mon Mar 25, 2013 2:38 pm

Gordon & Trevor

Seems my 7k samples per second was a creditable attempt. But its no good for my application - so I've given up and gone over to the Arduino (or, at least, to my Wotduino).

Many thanks for your replies - much appreciated,

m0xpd

joaoneves1
Posts: 2
Joined: Thu Apr 04, 2013 12:04 pm

Re: AD Conversion Speed

Mon Apr 08, 2013 7:49 pm

Gordon
So you are saying that the ~72 kSamples/s of the MCP3002 on the Gertboard is not achievable?
Another question: for multichannel A/D is the sampling rate divided between the channels, or can I achieve 200 kSamples/s per channel on the MCP3002 (supplying it with 5.0 V, and using a level shifter)?

Thanks in advance.

User avatar
[email protected]
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: AD Conversion Speed

Mon Apr 08, 2013 8:15 pm

joaoneves1 wrote:Gordon
So you are saying that the ~72 kSamples/s of the MCP3002 on the Gertboard is not achievable?
Another question: for multichannel A/D is the sampling rate divided between the channels, or can I achieve 200 kSamples/s per channel on the MCP3002 (supplying it with 5.0 V, and using a level shifter)?

Thanks in advance.
My experiences suggest that just over 8K samples/sec are possible via the SPI bus - that's exchanging 2 bytes per sample.

The issues AIUI is not the clock speed, but the kernel latency in setting up the transfer in the first place - something that I think is being worked on. You may get faster by bypassing the kernel and accessing the SPI hardware directly.

And the sampling rate is divided between channels. So to sample 2 channels, then the resulting speed would drop to just over 4K samples/sec.

-Gordon
--
Gordons projects: https://projects.drogon.net/

Macmanum
Posts: 4
Joined: Sat Aug 02, 2014 5:12 pm

Re: AD Conversion Speed

Mon Sep 01, 2014 2:43 pm

Hi Gordon,
i'm working with the MCP3208 which has a samplerate of 100 kS/s.
I started with your wiringPiSPI library (really good work, thanks for that !).
I want do read 3 Channels direct in a row, so i putted this in my C - Code:

Code: Select all

     wiringPiSPIDataRW(0,data0,3);
     wiringPiSPIDataRW(0,data1,3);
     wiringPiSPIDataRW(0,data2,3);
The MCP3208 needs a Chip-Select to read a new channel, so i had to seperate the reading processes.
i measured the frequency with an oscilloscope and i noticed long gaps between this communication processes.
One process has a duration of only about 12 us (2 Mhz SPI Clock Speed), but then follows a gap of 34 us. So the rate resultet in about 20 kS/s.
The Pi is running at 1GHz and i have no ideas why there is this gap.

Are there still problems with Kernellatency in the SPIDriver (i'm using Kernel 3.6.11) ?

Do you have any ideas to speed this up?
I tried bit banging with writing direct to the GPIOs (did the timing with a LKM and the Cycle Counter of the ARM1176) and achieved 100 kS/s but the problem is, there are lot of errors cause of unstable SPI Clock, probably because it runs in userspace...

Perhaps this could help?
http://www.raspberrypi.org/forums/viewt ... 44&t=19489

You also mentioned to get direct access to SPI Device without the Kernel, but i didn't understand that.

Thanks for help!

User avatar
[email protected]
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: AD Conversion Speed

Mon Sep 01, 2014 3:09 pm

It's probably still the kernel latency - but it's not something I've tried for a long time. Maybe time to dust off my tester code and see what it does with the current kernel (which is 3.12.2x btw)

You can bit-bang it by literally emulating SPI in software - that will work, but the max. clock you'll get is about 5Mhz - at the cost of 100% cpu usage, or you can semi-bit-bang it by poking the SPI registers directly - but I've no idea how much better (if at all) that is than just using the kernel driver.

-Gordon
--
Gordons projects: https://projects.drogon.net/

danjperron
Posts: 3431
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: AD Conversion Speed

Wed Sep 03, 2014 12:57 am

A year ago , I did use a small cpu to speed up things.

Using a fifo buffer to limit latency problem from the RPI.

It is possible to do the same thing with the SPI. This way you should be able to increase the transfer rate using group transfer and taking care of RPi SPI latency.

This is the post http://www.raspberrypi.org/forums/viewt ... 01#p341501

Only problem is that you will have to program a small cpu. Arduino mini will do the Job.
Control the A/D converter with a small cpu which you implement a fifo buffer to transfer data at the raspberry PI.

Daniel

Return to “Interfacing (DSI, CSI, I2C, etc.)”