Raspberry Pi IoT In C - AtoD With The SPI Bus
Written by Harry Fairhead   
Monday, 01 August 2016
Article Index
Raspberry Pi IoT In C - AtoD With The SPI Bus
Connecting And Getting Data

The SPI bus can be difficult to make work at first but once you know what to look for about how the slave claims to work it gets easier. To demonstrate how its done let's add eight channels of 12 bit AtoD using the MCP3008.


Raspberry Pi And The IoT In C

By Harry Fairhead

The new edition of this book is now available:

 Buy from Amazon.

All of the articles in this list are in the process of being updated from the first edition to the second edition.

Chapter List


  1. Getting Started With NetBeans In this chapter we look at why C is a good language to work in when you are creating programs for the IoT and how to get started using NetBeans. Of course this is where Hello C World makes an appearance.

  2. First Steps With The GPIO
    The bcm2835C library is the easiest way to get in touch with the Pi's GPIO lines. In this chapter we take a look at the basic operations involved in using the GPIO lines with an emphasis on output. How fast can you change a GPIO line, how do you generate pulses of a given duration and how can you change multiple lines in sync with each other? 

  3. Input and Interrupts

  4. Memory Mapped I/O 

  5. Near Realtime Linux
    You can write real time programs using standard Linux as long as you know how to control scheduling. In fact it turns out to be relatively easy and it enables the Raspberry Pi to do things you might not think it capable of. There are also some surprising differences between the one and quad core Pis that make you think again about real time Linux programming.

  6. PWM

  7. I2C

  8. I2C Temperature Measurement

  9. A Custom Protocol - The DHT11/22
    In this chapter we make use of all of the ideas introduced in earlier chapters to create a raw interface with the low cost DHT11/22 temperature and humidity sensor. It is an exercise in implementing a custom protocol directly in C. 

  10. Getting On The Web - After All It Is The IoT  Coming Soon

  11. One Wire Bus Basics
    The Raspberry Pi is fast enough to be used to directly interface to 1-Wire bus without the need for drivers. The advantages of programming our own 1-wire bus protocol is that it doesn't depend on the uncertainties of a Linux driver.

  12. iButtons
    If you haven't discovered iButtons then you are going to find of lots of uses for them. At its simples an iButton is an electronic key providing a unique coce stored in its ROM which can be used to unlock or simply record the presence of a particular button. What is good news is that they are easy to interface to a Pi. 

  13. The DS18B20
    Using the software developed in previous chapters we show how to connect and use the very popular DS18B20 temperature sensor without the need for external drivers. 

  14. The Multidrop 1-wire bus
    Some times it it just easier from the point of view of hardware to connect a set of 1-wire devices to the same GPIO line but this makes the software more complex. Find out how to discover what devices are present on a multi-drop bus and how to select the one you want to work with.

  15. SPI Bus
    The SPI bus can be something of a problem because it doesn't have a well defined standard that every device conforms to. Even so if you only want to work with one specific device it is usually easy to find a configuration that works - as long as you understand what the possibilities are. 

  16. SPI MCP3008/4 AtoD  Coming Soon




The Raspberry Pi doesn't have any analog inputs or outputs. You can buy expansion boards, HATs, that add multiple interfaces including analog I/O but some times you just don't need that many new features. The MCP3000 family of AtoD converters provides a simple, cheap and low cost alternative to fitting an entire expansion board. Although the MCP3008 with 8 AtoD inputs and the MCP3004 with 4 AtoD inputs at 10 bits precision are the best known there are other devices in the family including 12 and 13 bit precision and differential inputs at around the same sort of cost $1 to $2.

In this chapter the MCP3008 is used because it is readily available and provides a good performance at low cost but the other devices in the family work in the same way and could be easily substituted.


The MCP3008

The MCP3008 is available in a number of different packages but the standard 16 pin PDIP is the easiest to work with using a prototyping board. You can buy it from the usual sources including Amazon if you need one in a hurry. 

Its pin outs are fairly self explanatory:

You can see that the analog inputs are on the left and the power and SPI bus connections are on the right.  The conversion accuracy is claimed to be 10 bits but how many of these bits correspond to reality and how many are noise depends on how you design the layout of the circuit.

You need to take great care if you need high accuracy. For example you will notice that there are two voltage inputs VDD and VREF. VDD is the supply voltage that runs the chip and VREF is the reference voltage that is used to compare the input voltage. Obviously if you want highest accuracy VREF, which has to be lower than or equal to VDD, should be set by an accurate low noise voltage source - however in most applications VREF and VDD are simply connected together and the usual, low quality supply voltage is used as the reference. If this isn't good enough then you can use anything from a zener diode to a precision voltage reference chip such as the TL431. At the very least however you should add a 1uF capacitor between the VDD pin and the VREF pin to ground. 

The MC3000 family is a type of AtoD called a successive approximation converter. You don't need to know how it works to use it but it isn't difficult. The idea is that first a voltage is generated equal to VREF/2 and the input voltage is compared to this. If it is less then the most significant bit is a zero and if it is more or equal then it is a one. At the next step the voltage generated is VREF/2+VREF/4 and the comparison is repeated to generate the next bit. 




You can see that successive approximation fits in well with a serial bus as each bit can be obtained in the time needed to transmit the previous bit. However the conversion is relatively slow and a sample and hold circuit has to be used to keep the input to the converter stage fixed. The sample and hold takes the form of a 20pF capacitor and a switch. The only reason you need to know about this is that the conversion has to be complete in a time that is short compared to the discharge time of the capacitor - so for accuracy there is a minimum SPI clock rate as well as a maximum. 

Also to charge the capacitor quickly enough for it to follow a changing voltage it needs to be connected to a low impedance source. In most cases this isn't a problem but if it is you need to include an op amp. If you are using an op amp buffer then you might as well implement a filter to remove frequencies from the signal that are too fast for the AtoD to respond to - an anti-aliasing filter. How all this works takes us into the realm of analog electronics and signal processing and well out of the core subject matter of this book. 

You can also use the AtoD channels in pairs - differential mode - to measure the voltage difference them. For example, in differential mode you measure the difference between CH0 and CH1 i.e. what you measure is CH1-CH0. In most cases you want to use all eight channels in single-ended mode. 

In principle you can take 200K samples per second but only at the upper limit of the supply voltage VDD=5V falling to 75K samples per second at its lower limit of  VDD=2.7V. 

The SPI clock limits are a maximum of 3.6MHz at 5V and 1.35MHz at 2.7V. The clock can go slower but because of the problem with the sample and hold mentioned earlier it shouldn't go below 10kHz.

How fast we can take samples is discussed later in this chapter.

Last Updated ( Monday, 01 August 2016 )