MCP3008 ADC

This is an 8 channel A/D converter that can be tied to the Raspberry Pi through an SPI interface.

    • 10 bits output resolution (output value goes from 0-2047) -- Arduino page has a typo here - their code assumes max value of 1023 (2^10, not (2^11)-1)!!

    • MCP3008 will run on 3.3V supply!!

    • Pullup resistors not needed.

    • Note - Data timing restriction: Max time from end of sample period to all data bits read out is 1.2mSec.

Notes for MCP3008 usage

CS* pin is active low. Must by high initially for conversion to start.

INPUT Data: Set while clock is low. Read by ADC when clock goes high.

OUTPUT Data: Read after clock goes high.

Input data stream: <start=1> <single=1> <d2> <d1> <d0>

The start bit will be the first time Din==1 on a high clock, this is followed by 4 data bits.

The First of the 4 data bits should be 1 to designate single ended A/D conversion mode.

The next 3 bits (MSB first) designate the channel to be selected.

Once the above sequence is clocked in, another clock is issued for the sample/hold period.

Then another clock will start the null bit.

Finally, the next 10 clocks will clock out the data (MSB first) from the A/D chip.

If clocking continues, the data will clock out a second time LSB first, followed by all zero's as long as the clock runs.

Here are two locations for data sheets for the MCP3008:

https://cdn-shop.adafruit.com/datasheets/MCP3008.pdf

http://ww1.microchip.com/downloads/en/DeviceDoc/21295C.pdf

The following Adafruit app note was referenced for wiring and sample code to exercise the ADC:

https://cdn-learn.adafruit.com/downloads/pdf/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi.pdf

The Adafruit example code was written in Python. I re-wrote the code to implement the same algorithm in Perl with system calls to bit bang the GPIO port.

Wiring:

in0 | ch0 vdd | +3.3

in1 | ch1 vref | +3.3

in2 | ch2 agnd | gnd

in3 | ch3 clk | sclk - GPIO 18

in4 | ch4 dout | miso - GPIO 23

in5 | ch5 din | mosi - GPIO 24

in6 | ch6 cs* | cs_b - GPIO 25

in7 | ch7 dgrn | gnd

The above wiring is consistent with the Adafruit example.

My full code listing is about 560 lines, including comments and standard subroutines to handle I/O, logging, GPIO, etc.

The GPIO port data is bit-banged using system calls.

Also tried using 2.5v reference for vref - it works, and should be more consistent than the 3.3 ref from the Pi, but hard to say??