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
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
O Pinout do Raspberry PI é o seguinte:
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