I'm trying to interface with MCP3002 ADC using SPI and it's working nicely except for the amount of the samples I'm able to collect per second. I'm using WiringPi and the code is very simple:

wiringPiSPISetup(0, 2 * 1000 * 1000);

unsigned char buf[2];

for (;;) {
  buf[0] = 104; // x start_bit single_mode ch1 msbf xxx
  buf[1] = 0;

  wiringPiSPIDataRW(0, buf, 2);

  // convert buf to an int and print to stdout

The problem is that regardless of the clock speed set, the wiringPiSPIDataRW call takes about 70us which limits the speed of the whole system to 14k samples / sec.

Has anyone had better luck with SPI on Raspberry Pi with very short messages?

The MCP3002 can conservatively handle 80k samples at 3.3V which then assuming some extra clock cycles for asserting the CS line should run at 1.6Mhz clock and perform a RW call in 12.5 usec. Is then the speed limited by WiringPi overhead?

EDIT: I tried using spidev directly using SPI_IOC_MESSAGE and the speed is the same so it's not WiringPi. I forgot to mention I'm using a slightly older Raspberry board, v1 rev.B if I'm not mistaken. lsmod shows that spi_bcm2835 is loaded, so that should be fine. Using SPI_IOC_MESSAGE with an array of 128 messages gets the speed up to 45k samples / sec, but that's about as high as it will go.

I appreciate any pointers. Thanks.


My pigpio and the bcm2835 library will both be faster as they don't use the Linux SPI driver.

I think the Linux SPI driver tops out at about 20k calls per second on all but the Pi3 where it reaches about 70k calls per second. I don't understand why the Pi3 seems so much better.


#include <stdio.h>
#include <stdlib.h>

#include <pigpio.h>

   gcc -pthread -o spi-speed spi-speed.c -lpigpio

int main(int argc, char *argv[])
   int i;
   int h;
   int loops;
   int speed;
   double start, diff, sps;
   unsigned char buf[2];

   if (argc > 1) loops = atoi(argv[1]);
   else loops = 1000000;

   if (argc > 2) speed = atoi(argv[2]);
   else speed = 1000000;

   if (gpioInitialise() < 0) return 1;

   h = spiOpen(0, speed, 0);

   if (h < 0) return 2;

   start = time_time();

   for (i=0; i<loops; i++)
      buf[0] = 104; // x start_bit single_mode ch1 msbf xxx
      buf[1] = 0;

      spiXfer(h, buf, buf, 2);

   diff = time_time() - start;

   printf("sps=%.1f @ %d bps (%d/%.1f)\n",
      (double)loops / diff, speed, loops, diff);



   return 0;

pigpio results at various SPI bit rates (run on a Pi B+).

$ sudo ./spi-speed  1000000 500000
sps=24184.0 @ 500000 bps (1000000/41.3)

$ sudo ./spi-speed  1000000 1000000
sps=47018.5 @ 1000000 bps (1000000/21.3)

$ sudo ./spi-speed  1000000 2000000
sps=89840.5 @ 2000000 bps (1000000/11.1)

$ sudo ./spi-speed  1000000 3000000
sps=128846.8 @ 3000000 bps (1000000/7.8)

$ sudo ./spi-speed  1000000 4000000
sps=164745.8 @ 4000000 bps (1000000/6.1)
  • Awesome, with pigpio I could easily get 80k samples / sec before the CPU hit 100%. Thank you!
    – Gunchars
    Apr 10 '16 at 21:40
  • Does pigpio use bit-banging or the boards hardware SPI? If the latter, is there any way to get the DMA enabled to keep the CPU down? The capture rate is good enough, but I'd like to do some processing with the data too..
    – Gunchars
    Apr 11 '16 at 14:08
  • 1
    @Gunchars The library spiXfer function uses the SPI hardware. The only thing you could do on that is increase the SPI bitrate to the maximum your ADC can handle (at the voltage you are using). That will release the maximum amount of time for processing. Bit bang SPI with DMA is highly specialised. That allows circa 25 k samples per second for each ADC. So if you wanted to sample 8 channels you could have 8 ADCs and they would all be sampled simultaneously. That has advantages. The other advantage of DMA SPI bit bang is the samples will be uniformly spaced in time.
    – joan
    Apr 11 '16 at 15:36
  • Just wanted to add that I upgraded to Pi 3 to get some extra cycles for processing the data (the 4 cores is a godsend to me) and I'm easily pushing 200k samples on a single core with pigpio. Nice work!
    – Gunchars
    Apr 17 '16 at 22:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.