MCP3008 and Analogue Sensors

Posted on 2019-11-29

The MCP3008 is an analogue to digital signal converter. The RPi only understands digital signals, while the photoresistor, water-level sensor, and moisture sensor all provide an analogue signal.

The MCP3008 can communicate with the Serial Peripheral Interface, or SPI. For SPI to work, it needs to be enabled (which I forgot to do…). This can be done via the raspi config

raspi-config > 5 Interfacing options > P4 SPI > Yes 

The datasheet of the MCP3008 is here. I was mostly following this tutorial while writing this.

Wiring up.

The tutorial here has a fritzing diagram I followed.

Orientating the MCP3008 in portrait with pins sideways and with the “D” shaped indent at the bottom, we wire up the left hand side as follows. Starting from the top:

  1. DGND –> GRD
  2. CS –> CE0 (pin 24)
  3. MOSI –> MOSI (pin 19)
  4. MISO –> MISO (pin 21)
  5. SCLK –> SCLK (pin 23)
  6. AGND –> GRD
  7. VREF –> 3.3V
  8. VDD –> 3.3V

The left hand side receives the signal from the analogue sensors.

Software

Requirements:

sudo apt-get install python3-dev

We’ll also need py-spidev

wget https://github.com/doceme/py-spidev/archive/master.zip 
unzip master.zip
cd py-spidev-master
sudo python3 setup.py install

This is the simple script from the tutorial, which almost worked but… see below.

from spidev import SpiDev
 
class MCP3008:
    def __init__(self, bus = 0, device = 0):
        self.bus, self.device = bus, device
        self.spi = SpiDev()
        self.open()
 
    def open(self):
        self.spi.open(self.bus, self.device)
    
    def read(self, channel = 0):
        adc = self.spi.xfer2([1, (8 + channel) << 4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        return data
            
    def close(self):
        self.spi.close()

Issues!

I was not getting the right results. The values being returned were sort of sporadic. Initially it would be all 0. Then a few occurrences of 64, or more rarely a 127, 60 and 63 appeared. Then an almost steady oscillation between 0 and 64, and then a bias of one or the other and back again.

After looking at a load of blogs, and checking the wiring a bazillion times, I found this. The solution was to add the following line:

spi.max_speed_hz = 1350000

After spi.open()

Photoresistor

The photoresistor, or light dependent resistor, is a resistor whose resistance decreases as the exposure to light increases.

I followed the fritzing diagram in this tutorial. Most of the time putting it together was taken up with finding the photoresistor in the box amongst all the wires.

This is just the software for the MCP3008, polling the right pin.

With the 10k Ohm resistor, under the usb light, it can go up to 1023. Covering the sensor caused the reading to drop to about 200. Altering the resistor you can change the range and sensitivity observed.

Results

I have a generic water-level sensor and capacitive moisture sensor that wire up in a similar fashion to the photoresistor. The pi is now able to poll three separate analogue sensors via the MCP3008.