Circuitos_1

Usando um IC MCP3008 iremos acrescentar a capacidade de ler valores analógicos a um Raspberry Pi. O Raspberry Pi ao contrário dos Arduinos não tem nativamente nenhuma forma de ler dados analógicos. Ao acrescentar um integrado como o MCP3008 podemos dar-lhe esta capacidade.

O MCP3008 é um ADC (Analog-to-Digital Converter) de 10-bits com 8 canais. Isto significa que pode ler informação analógica de 8 pinos distintos com resolução de 10-bit (1024 valores distintos). O chip comunica através do protocolo SPI.

Para efeitos de exemplificação de obtenção de dados iremos colocar dois sensores de temperatura, um LDR, que é uma resistência sensível à Luz, e um potenciómetro.
Para a comunicação com o Raspberry Pi iremos usar 4 pinos (CLK, DOUT, DIN, CS).

Para sensor de temperatura usámos o LM335. Para o circuito deste componente é necessário uma resistência cujo valor depende da Tensão do circuito. Para que se obtenham resultados óptimos é necessário que passe no sensor cerca de 1mA. Para obter o valor da resistência, a formula que se deve usar é a seguinte: R1 = (Vcc - Vlm335)/ (0.4 to 5mA). Por cada grau que aumenta a temperatura a leitura aumentará 10mV ou 0.01 Volt. O valor lido é a temperatura em Kelvins.

Para se converter de graus Kelvins para Celsius é subtrair ao valor obtido a constante 273.15 .

Se considerarmos que o Vcc é de 3.3 volts e a temperatura de referência é 25 ºC (correspondentes a cerca de 2.98V de saida no LM335) podemos obter os seguintes valores:

  • 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)

Assim sendo para a temperatura ambiente (25ºC) o valor sugerido será entre os 64 e os 800 ohms - iremos usar uma resistência de 330 ohms.

A Formula para se obter o valor da temperatura em graus Celsius é: Temp ºC = (rawADC * 3.3 * 100 / 1023) - 273.15

Sendo o rawADC correspondente ao valor lido do MCP3008.

Esquemático

Circuitos_3_Schematics

Componentes (BOM)

Circuito:

  • 1x IC MCP3008 (U3)
  • 2x IC LM335 (U1 e U2)
  • 1x Resistência Variável de 10K Ohms (RV1)
  • 2x Resistência de 330 Ohms (R1 e R2)
  • 1x LDR (R3)
  • 1x Resistência de 10K Ohms (R4)

Pin-out dos IC/Componentes

Circuitos_4_Pinout

O Pinout do Raspberry PI é o seguinte:

Circuitos_4_Pinout

Código

O sistema usado para se correr o código apresentado foi o raspbian jessie de 2015-09-24 e foi usado um Raspberry PI 2. Pode ser descarregado daqui.
Foi ativado o interface SPI através do comando sudo raspi-config - Advanced options - SPI - Enable - Yes. Para mais informação consultar o seguinte link.

Para se lerem os valores dos 4 inputs foi usado um programa em python. Este usa a biblioteca spidev.

Para o programa correr é necessário instalar a biblioteca de python spidev:

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

Depois cria-se o seguinte programa 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)

Este pode ser executado como python3 mcp3008.py e o resultado da execução será o seguinte:

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