I have managed to get some sensible data trough the ADC(MCP3008), but I'm struggling to find out how to set the SPI-Clock. The ADC (MCP3008) uses 24 clock-pulses to make one sample therefore I calculated that to get 200ksample/sek the clock should be at least 4,8MHz. I cant find any documentation of the module in use. I'm now using the py-spidev module the link shows the only documentation I can find. I have read at Gordons Projects that the clock has some jumps so i suppose 8MHz should be the right speed. I have measured the speed on the spi clock, on a scope. The default speed is 500kHz.

The code:

import spidev
import time
import os
import sys

spi = spidev.SpiDev()

#read SPI from MCP3008 chip, 8 possible chanels
def readadc(adcnum):
  if((adcnum > 7) or (adcnum < 0)):
    return -1
  r = spi.xfer2([1,(8+adcnum)<<4,0])
  adcout = ((r[1]&3 << 8) + r[2]
  return adcout

#chanel input on ADC
ch0 = 0;

while true:

#read chanel
pc_value = readadc(ch0)

#print data from ADC
#print pc_value

#wait do nothing for 0.20 sek
  • After I read through the molule c file i have come a bit futher in the progtamming. By adding the line: spi.max_speed_hz=(16000000) i have increased the speed of the clock to 16MHz, unfortunally the SPI-clock send 3 blocks with 8 pulses. Inside this block it takes an sample, then makes an pause of ca 220us and repeat the block again. To make 200k samples pr sek is not possible as long as this pause is present. (if i could upload an image it would be easier to understand is that possible?)
    – Odin
    Feb 7 '13 at 14:14
  • When you look at the source (the .c file) you see just above the SpiDev_xfer() (line 200 and 193) function a short text in a function called PyDoc_STRVAR() (some documentation generation stuff I guess). It mentions there a delay variable: delay specifies delay in usec between blocks. This delay value is later in this function used in the actual transfer code.
    – ikku
    Feb 7 '13 at 15:53
  • Some new update after a day, the code r = spi.xfer2([1,(8+adcnum)<<4,0]) could be altered like this r = spi.xfer2([list],speed_hz,delay_usecs,bits_per_word) if you put 0 for delay_usecs nothing happens it still 220us delay if i put 1000 in delay_usecs the delay is 1220us. This means that the pi is deciding when SPI get to communicate. Howe to work around this i still don't know.
    – Odin
    Feb 8 '13 at 13:41

I can only help you with the hardware part, Chapter 10 of the datasheets discusses the SPI bus, there is a register that is the 'SPI Master Clock Divider' (see Page 152 on the bottom).

But how you can do anything with that register in Python is for somebody else to answer, or do a search on google for Python programming, or I am also sure the Python module you use, is full of writing data to specific registers, checking that source will also provide the answer.


typedef struct {

    int fd; /* open file descriptor: /dev/spi-X.Y */
    uint8_t mode;   /* current SPI mode */
    uint8_t bits_per_word;  /* current SPI bits per word setting */
    uint32_t max_speed_hz;  /* current SPI max speed setting in Hz */
} SpiDevObject;

static PyObject *
SpiDev_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

Without any knowledge of Python, I found out that the actual communication is done using a .c source, that binds in someway to python. From Python you call functions from this .c file. I see that the SpiDev_new function (which smells like a constructor) accepts as first parameter the defined structure (as shown above), in this structure there is a field that states the maximum frequency of the SPI bus (max_speed_hz).

In your source I see a call to:

spi = spidev.SpiDev()

I guess you can add some parameters to this call to get things working like you want...

What and How I don't know yet...

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.