Skip to content

MCP3008 Application Overview

Elliot Ford edited this page Feb 1, 2021 · 1 revision

What

The MCP3008 is a 8-channel ADC chip with 10-bits of resolution that communicates digitally over a SPI-bus. It's performance is similar to the Arduino Uno.

Why

This was evaluated as a potential chip for data-sampling on the 2019-2020 Neurotech Headset board. We ultimately decided that due to the lack of sub-sampling and filtering that it wasn't a good fit for our needs. It was suspected (but never actually confirmed) that we were hindered by the max speed of the raspberry pi spi bus. At the time of writing, the work found in the mcp3008lsl folder in the repo is a simple driver for collecting data from the MCP3008 and communicating with a LabStreamingLayer supporting data collector.

Application Notes

Setup

We followed Adafruit's guide on the MCP3008 (link here) for initial setup of the chip with our Raspberry Pi. Alternatively, the mcp3008lsl project's README has good documentation of how to setup for use with that specific driver.

Serial Communication with the MCP3008

Section 5 is the useful section with much of the following based on the diagram 6-1: Spec.

the MCP3008 samples on a request basis from the SPI server device (it being the client)[1]. The server's request message consists of a start bit, a bit that determines the operating mode, signal/differential and then 3 bits indicating the channel to sample.

Bits # 0 1 2 3 4
Use Start SGL/DIFF D2 D1 D0

The after a period of delay the MCP3008 will respond with the data in LSB format, starting with a Null bit followed by 10 bits of data each clock cycle.

Bits # 0 1 2 3 4 5 6 7 8 9 10
Use Null B9 B8 B7 B6 B5 B4 B3 B2 B1 B0

The spec-doc for the MCP3008 advises that the sender use 3 bytes when sending a request to the chip, giving the chip a chance to warm up and then keep the bus clock running for the responding data (fyi, this is my assumption I'm not 100% sure as to this). A rough C snippet for such a message (using SPIdev and assuming operating in Single sided mode and that channel is the channel #) is as follows:

/**
 * 0 0 0 0 0 0 0 1
 * S D D D 0 0 0 0
 * 0 0 0 0 0 0 0 0
 */
uint8_t buf[3] = {0b00000001,
                  0b10000000 | (channel << 4)
                  0b00000000};

  1. The classical terminology you'll find w.r.t. SPI is Master for Server and Slave for Client. However there has been a push lately away from this language as the connotations aren't great. As such I'm using the terms Server in place of Master and Client in place of Slave.

Clone this wiki locally