Circuitos_1

Using an MCP3008 IC we will add the ability to read analog values on a Raspberry Pi. The Raspberry Pi unlike the Arduinos natively has no way of reading analog data. By adding an integrated as the MCP3008 we can give you this capability.

The MCP3008 is a 10-bit Analog-to-Digital Converter (ADC) with 8 channels. This means you can read analog information from 8 different pins with 10-bit resolution (1024 different values). The chip communicates through the SPI protocol.

For the purpose of exemplifying data collection we will place two temperature sensors, one LDR, which is a light-sensitive resistor, and a potentiometer.
For communicating with Raspberry Pi we will use 4 pins (CLK, DOUT, DIN, CS).

For temperature sensor we used the LM335. For the circuit of this component it is necessary a resistor whose value depends on the Voltage of the circuit. In order to obtain optimal results it is necessary to pass to the sensor about 1mA. To obtain the resistor value, the formula to be used is as follows: R1 = (Vcc - Vlm335) / (0.4 to 5mA). For each degree that increases the temperature the reading will increase 10mV or 0.01 Volt. The read value is the Kelvins temperature.

To convert from Kelvins to Celsius is to subtract from the value obtained the constant 273.15.

If we consider that the Vcc is 3.3 volts and the reference temperature is 25 ° C (corresponding to about 2.98V of output in the LM335) we can obtain the following values:

  • R1 = (3.3V - 2.98V) / 0.0004A = 800 ohms (400μA = 0.0004A)
  • R1 = (3.3V - 2.98V) / 0.005A = 64 ohms (5mA = 0.005A)

So at room temperature (25° C) the suggested value will be between 64 and 800 ohms - we will use a resistor of 330 ohms.

The Formula to obtain the temperature value in degrees Celsius is: Temp ºC = (rawADC * 3.3 * 100/1023) - 273.15

Being rawADC is the read value of the MCP3008.

Schematic

Circuitos_3_Schematics

Bill of materials (BOM)

Circuit:

  • 1x IC MCP3008 (U3)
  • 2x IC LM335 (U1 e U2)
  • 1x 10K Ohms Variable Resistor (RV1)
  • 2x 330 Ohms Resistor (R1 e R2)
  • 1x LDR (R3)
  • 1x 10K Ohms Resistor (R4)

IC/Components Pin-out

Circuitos_4_Pinout

The Raspberry PI Pinout is as follows:

Circuitos_4_Pinout

Code

The system used to run the code presented here was a Raspberry PI 2 running raspbian jessie from 2015-09-24. It can be downloaded from here.
The SPI interface has been activated through the sudo raspi-config command - Advanced options - SPI - Enable - Yes. For more information, see the following link.

In order to read the values of the 4 inputs a python program was used. This uses the spidev library.

For the program run it is necessary to install the library spidev of python :

cd ~
git clone https://github.com/doceme/py-spidev.git
cd py-spidev
sudo python3 setup.py install

Then you create the following program mcp3008.py:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
import spidev
import time

spi = spidev.SpiDev()
spi.open(0, 0)


# read SPI data from one of the MCP3008's eight possible inputs (0 thru 7)

def readadc(adcnum):
    if adcnum > 7 or adcnum < 0:
        return -1
    readout = spi.xfer2([1, 8 + adcnum << 4, 0])
    adcout = ((readout[1] & 3) << 8) + readout[2]
    return adcout


def raw2temp(raw):
    millivolts = raw * (3.3 * 100 / 1023.0)
    tempk = millivolts
    tempc = millivolts - 273.15
    tempf = tempc * 9.0 / 5.0 + 32
    return (tempk, tempc, tempf)


sensor0pin = 0
sensor1pin = 1
sensor2pin = 2
sensor3pin = 3

try:
    while True:
        rawval0 = readadc(sensor0pin)
        rawval1 = readadc(sensor1pin)
        rawval2 = readadc(sensor2pin)
        rawval3 = readadc(sensor3pin)

        # Convert the raw ADC input to milliVolts,
        #   degrees Celsius and Fahrenheit

        (temp_kelvins, tempcelsius, tempfahrenheit) = raw2temp(rawval0)
        print (
            'LM335 Sensor0:',
            'raw=',
            rawval0,
            'Kelvins=',
            '{0:.1f}'.format(temp_kelvins),
            'Celsius=',
            '{0:.1f}'.format(tempcelsius),
            'Fahrenheit=',
            '{0:.1f}'.format(tempfahrenheit),
            )

        (tempkelvins, tempcelsius, tempfahrenheit) = raw2temp(rawval1)
        print (
            'LM335 Sensor1:',
            'raw=',
            rawval1,
            'Kelvins=',
            '{0:.1f}'.format(tempkelvins),
            'Celsius=',
            '{0:.1f}'.format(tempcelsius),
            'Fahrenheit=',
            '{0:.1f}'.format(tempfahrenheit),
            )

        print (
            'LDR   Sensor2:',
            'raw=',
            rawval2
            )

        print (
            'TRIM  Sensor3:',
            'raw=',
            rawval3
            )

        print ()

        time.sleep(1)
except KeyboardInterrupt:
    spi.close()
    sys.exit(0)

This can be run as python3 mcp3008.py and the result of the execution will be as follows:

LM335 Sensor0: raw= 957 Kelvins= 308.7 Celsius= 35.6 Fahrenheit= 96.0
LM335 Sensor1: raw= 955 Kelvins= 308.1 Celsius= 34.9 Fahrenheit= 94.8
LDR   Sensor2: raw= 769
TRIM  Sensor3: raw= 537

LM335 Sensor0: raw= 957 Kelvins= 308.7 Celsius= 35.6 Fahrenheit= 96.0
LM335 Sensor1: raw= 955 Kelvins= 308.1 Celsius= 34.9 Fahrenheit= 94.8
LDR   Sensor2: raw= 771
TRIM  Sensor3: raw= 536

LM335 Sensor0: raw= 957 Kelvins= 308.7 Celsius= 35.6 Fahrenheit= 96.0
LM335 Sensor1: raw= 955 Kelvins= 308.1 Celsius= 34.9 Fahrenheit= 94.8
LDR   Sensor2: raw= 771
TRIM  Sensor3: raw= 537