.. note::
¡Hola, bienvenido a la comunidad de entusiastas de SunFounder Raspberry Pi & Arduino & ESP32 en Facebook! Sumérgete más en Raspberry Pi, Arduino y ESP32 con otros entusiastas.
**¿Por qué unirse?**
- **Soporte experto**: Resuelve problemas postventa y desafíos técnicos con la ayuda de nuestra comunidad y equipo.
- **Aprender y compartir**: Intercambia consejos y tutoriales para mejorar tus habilidades.
- **Vistas previas exclusivas**: Obtén acceso anticipado a anuncios de nuevos productos y adelantos.
- **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más nuevos.
- **Promociones y sorteos festivos**: Participa en sorteos y promociones de temporada.
👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy mismo.
.. _2.1.4_py_pi5_mcp3008:
2.1.4 Potenciómetro (MCP3008)
=============================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Dependiendo de la versión de tu kit, identifica si tienes **ADC0834** o **MCP3008** y continúa con la sección correspondiente.
Introducción
------------
La función ADC se utiliza para convertir señales analógicas en valores digitales.
En este experimento, usamos el chip ADC MCP3008 para realizar esta conversión.
Un potenciómetro se utiliza para generar un voltaje variable, que cambia la magnitud física.
El MCP3008 convierte este voltaje analógico en un valor digital que puede ser leído y procesado por la Raspberry Pi.
Componentes necesarios
----------------------
En este proyecto, necesitaremos los siguientes componentes.
.. image:: ../python_pi5/img/list2_2.1.4_potentiometer.png
Diagrama esquemático
--------------------
.. list-table::
:widths: 30 30 30 30
:header-rows: 1
* - Nombre T-Board
- Físico
- WiringPi
- BCM
* - SPICE0
- pin24
- 10
- 8
* - SPIMOSI
- pin19
- 12
- 10
* - SPIMISO
- pin21
- 13
- 9
* - SPISCLK
- pin23
- 14
- 11
* - GPIO22
- pin15
- 3
- 22
.. image:: ../python_pi5/img/schematic_2.1.7_potentiometer_mcp3008.png
Procedimiento experimental
--------------------------
**Paso 1:** Montar el circuito.
.. image:: ../python_pi5/img/july24_2.1.7_potentiometer_mcp3008.png
.. note::
Coloca el chip siguiendo la posición correspondiente indicada en la imagen.
Ten en cuenta que la ranura del chip debe quedar a la izquierda cuando se coloque.
**Paso 2:** Configura la interfaz SPI e instala la biblioteca ``spidev`` (consulta :ref:`spi_configuration` para ver instrucciones detalladas). Si ya completaste estos pasos, puedes omitirlos.
**Paso 3:** Abre el archivo de código.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/python-pi5
**Paso 4:** Ejecuta.
.. raw:: html
.. code-block::
sudo python3 2.1.4-2_Potentiometer_zero.py
Después de que el código se ejecute, al girar la perilla del potenciómetro, la intensidad del LED cambiará en consecuencia.
.. warning::
Si aparece el mensaje de error ``RuntimeError: Cannot determine SOC peripheral base address``, consulta :ref:`faq_soc`
**Código**
.. note::
Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el código a continuación.
Pero antes de eso, debes ir a la ruta del código fuente como ``davinci-kit-for-raspberry-pi/python-pi5``.
Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import spidev
import time
from gpiozero import PWMLED
# Inicializar LED PWM en GPIO22
led = PWMLED(22)
# Inicializar SPI
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CS0 (CE0)
spi.max_speed_hz = 1000000
def read_adc(channel):
"""
Leer valor analógico desde MCP3008
:param channel: canal ADC (0-7)
:return: entero de 10 bits (0-1023)
"""
if channel < 0 or channel > 7:
return -1
# Protocolo MCP3008
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 3) << 8) | adc[2]
return value
def MAP(x, in_min, in_max, out_min, out_max):
"""
Mapear un valor de un rango a otro
"""
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
try:
while True:
# Leer del canal 0 de MCP3008
res = read_adc(0)
print('res = %d' % res)
# Mapear 0–1023 a 0–100%
R_val = MAP(res, 0, 1023, 0, 100)
# Ajustar brillo del LED
led.value = R_val / 100.0
time.sleep(0.2)
except KeyboardInterrupt:
led.value = 0 # Apagar el LED
**Explicación del código**
#. ``gpiozero`` para el control PWM del LED, ``spidev`` para la comunicación SPI con el MCP3008, y ``time`` para implementar retardos.
.. code-block:: python
#!/usr/bin/env python3
import spidev
import time
from gpiozero import PWMLED
#. Inicializa un objeto PWMLED conectado al pin GPIO 22 y configura la comunicación SPI (Bus 0, CE0) con el MCP3008.
.. code-block:: python
# Inicializar LED PWM en GPIO22
led = PWMLED(22)
# Inicializar SPI
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CS0 (CE0)
spi.max_speed_hz = 1000000
#. Define una función llamada ``read_adc`` para comunicarse con el MCP3008 y leer valores analógicos del canal especificado (0–7).
.. code-block:: python
def read_adc(channel):
"""
Leer valor analógico desde MCP3008
:param channel: canal ADC (0-7)
:return: entero de 10 bits (0-1023)
"""
if channel < 0 or channel > 7:
return -1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 3) << 8) | adc[2]
return value
#. Define una función llamada ``MAP`` para convertir un rango de valores en otro, útil para mapear valores del ADC a niveles de brillo adecuados para el LED.
.. code-block:: python
def MAP(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
#. Lee continuamente el valor del ADC en un bucle, mapeando el valor ADC de 10 bits (0–1023) a un nivel de brillo (0–100) para el LED. Ajusta el brillo del LED en consecuencia. Espera 0.2 segundos entre cada lectura.
.. code-block:: python
try:
while True:
# Leer del canal 0 de MCP3008
res = read_adc(0)
print('res = %d' % res)
# Mapear 0–1023 a 0–100%
R_val = MAP(res, 0, 1023, 0, 100)
# Ajustar brillo del LED
led.value = R_val / 100.0
time.sleep(0.2)
except KeyboardInterrupt:
led.value = 0 # Apagar el LED