Leer señales analógicas en Raspberry Pi
Publicado por Loli Diéguez en
Muchos de los sensores desarrollados originalmente para Arduino no ofrecen una interfaz digital y solo pueden leerse analógicamente y la Raspberry Pi con sus GPIO no puede leer ninguna señal analógica, por lo que necesita un convertidor analógico-digital (ADC) como el MCP3008. Esto significa que se pueden leer hasta 8 entradas analógicas a través del bus SPI en la Raspberry Pi.
En este artículo, te doy una explicación y te muestro una clase de Python, con la que se pueden leer las señales de todos los sensores y módulos analógicos.
Una posibilidad es, por supuesto, conectar un Arduino a la Raspberry Pi, ya que también tiene pines IO analógicos y, por lo tanto, puede leer esas señales sin ADC. Sin embargo, la desventaja de esto es que, tiene otro microcontrolador y no se puede atacar desde Python.
Material necesario
Además del MCP3008 ADC, también debes tener cables de puente y una placa de pruebas.
Debes saber que hay una gran cantidad de sensores o módulos que solo se pueden leer en analógico, como por ejemplo:
- Joysticks
- Sensores de distancia infrarrojos
- Sensores de pulso / frecuencia cardíaca
- Sensores de sonido
- Sensores de humedad
- Sensores fotográficos
- Codificadores rotatorios
- Sensores de gas MQ
- y muchos más
Diferencias entre analógico y digital
En una señaldigital solo existen dos posibles valores: ON / HIGH o OFF / LOW, lo que se traduce en 0 o 1.
Si suponemos un voltaje de entrada digital máximo de 5 V, cualquier valor entre 0 V y 0,4 V se reconocerá como un nivel BAJO o LOW y un valor entre 2,4 V y 5 V como un nivel ALTO o HIGH. Todos los valores intermedios no están definidos.
A diferencia de las señales digitales, una señal analógica puede tomar valores intermedios entre un maximo y un minimo. Asi, continuando con el ejemplo anterior, con un maximo de 5v y un minimo de 0v, una señal analogica podria tomas valores de 0, 1.2, 3.4, 4.5,...y cualquier otro valor intermedio entre 0 y 5.
Para leer este voltaje en la Raspberry Pi, se debe usar un convertidor analógico-digital como el MCP3008. Sin embargo, ese conversor no especifica valores en voltios, sino un número entre 0 y 1023, que corresponde a 10 bits (2^10) y para determinar el voltaje leído se necesita usar la siguiente fórmula:
(ADC Value ÷ 1023) * Voltaje
Si el sensor analógico funciona con una tensión de 3,3 V y se ha leído un valor de 789, la tensión aplicada corresponde a 2,54 voltios.
Conexión entre Raspberry Pi y MCP3008
Los 8 canales analógicos legibles se encuentran en el lado izquierdo del MCP3008.
La forma más sencilla de direccionar un convertidor analógico-digital es utilizar el bus SPI. Las 8 señales se pueden leer con una consulta y convertir.
Como se puede ver en la hoja de datos, el ADC tolera un voltaje de entrada entre 2.7V y 5V. Dado que los GPIO funcionan con 3.3V y podrían romperse a voltajes más altos, el MCP3008 solo debe operarse con 3.3V.
Si utiliza un módulo analógico que tiene un voltaje de entrada superior a 3,3 V, debes asegurarte de que no llegue al conversor para lo cual puedes emplear divisores de tensión con resistencias.
La conexión a la Raspberry Pi es bastante simple, ya que solo se utilizan aquellos GPIO que también son para el bus SPI:
Raspberry Pi | MCP3008 |
---|---|
Pin 1 (3,3 V) | Pin 16 (VDD) |
Pin 1 (3,3 V) | Pin 15 (VREF) |
Pin 6 (GND) | Pin 14 (AGND) |
Pin 23 (SCLK) | Pin 13 (CLK) |
Pin 21 (MISO) | Pin 12 (DOUT) |
Pin 19 (MOSI) | Pin 11 (DIN) |
Pin 24 (CE0) | Pin 10 (CS / SHDN) |
Pin 6 (GND) | Pin 9 (DGND) |
La conexión sería como muestra la siguiente foto, aunque explícitamente no he colocado un sensor en el lado derecho, ya que todas las señales digitales se pueden leer de esta manera:
Preparación
Antes de que se puedan leer los valores, se deben actualizar las fuentes de los paquetes y se debe instalar una biblioteca para SPI y, por supuesto, se debe activar el bus SPI, ya que está desactivado en Raspbian de forma predeterminada.
Hay que comenzar actualizando los paquetes e instalando las herramientas de desarrollo de Python:
sudo apt-get update sudo apt-get upgrade sudo apt-get install python-dev
Luego podemos descargar, descomprimir e instalar la biblioteca SpiDev :
wget https://github.com/doceme/py-spidev/archive/master.zip descomprimir master.zip cd py-spidev-master sudo python setup.py instalar
Y por último, pero no menos importante, el bus SPI aún debe estar activado si aún no se ha hecho. En Raspbian (y otros sistemas operativos basados en él), la configuración de Raspberry Pi se puede cambiar usando:
sudo raspi-config
.
La opción "SPI" se puede encontrar en "Opciones avanzadas". Aquí activa SPI y luego reinicia el sistema (si no llega la consulta correspondiente):
sudo reboot
.
Clase Python para Raspberry Pi ADC MCP3008
La siguiente clase te permite acceder fácilmente al ADC MCP3008.
Puedes descargar el archivo o crearlo usando: sudo nano MCP3008.py
e insertar el siguiente código:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
from spidev import SpiDev
class MCP3008:
def __init__(self, bus = 0, device = 0):
self.bus, self.device = bus, device
self.spi = SpiDev()
self.open()
self.spi.max_speed_hz = 1000000 # 1MHz
def open(self):
self.spi.open(self.bus, self.device)
self.spi.max_speed_hz = 1000000 # 1MHz
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()
|
Ahora puedes insertar este archivo en todas las carpetas de tu proyecto y simplemente integrarlo:
1
|
from MCP3008 import MCP3008
|
A continuación, la clase debe inicializarse una vez y se pueden leer los 8 canales analógicos:
3
4
5
|
adc = MCP3008()
value = adc.read( channel = 0 ) # puedes ajustar el canal en el que lees
print("Applied voltage: %.2f" % (value / 1023.0 * 3.3) )
|
Ahora nada debería interponerse en el camino de operar todos los posibles módulos Arduino / Genuino en la Raspberry Pi.