.. note::
¡Hola, bienvenido a la Comunidad de Entusiastas de SunFounder Raspberry Pi & Arduino & ESP32 en Facebook! Sumérgete en el mundo de Raspberry Pi, Arduino y ESP32 junto a 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.
- **Preestrenos exclusivos**: Obtén acceso anticipado a nuevos anuncios de productos y adelantos.
- **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más recientes.
- **Promociones y sorteos festivos**: Participa en sorteos y promociones especiales de temporada.
👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy mismo.
.. _2.2.1_py_pi5_mcp3008:
2.2.1 Fotorresistor (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 procede con la sección correspondiente.
Introducción
------------
El fotorresistor es un componente comúnmente usado para medir la intensidad de luz ambiental.
Ayuda al controlador a diferenciar entre el día y la noche y a implementar funciones de control de luz, como lámparas nocturnas.
Este proyecto es muy similar al potenciómetro, ya que convierte una variación de voltaje en la detección de luz.
Componentes requeridos
----------------------
En este proyecto, necesitamos los siguientes componentes.
.. image:: ../python_pi5/img/list2_2.2.1_photoresistor.png
Es definitivamente conveniente comprar un kit completo, aquí tienes el enlace:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - Nombre
- ELEMENTOS EN ESTE KIT
- ENLACE
* - Kit Raphael
- 337
- |link_Raphael_kit|
También puedes comprarlos por separado en los siguientes enlaces.
.. list-table::
:widths: 30 20
:header-rows: 1
* - INTRODUCCIÓN DEL COMPONENTE
- ENLACE DE COMPRA
* - :ref:`cpn_gpio_board`
- |link_gpio_board_buy|
* - :ref:`cpn_breadboard`
- |link_breadboard_buy|
* - :ref:`cpn_wires`
- |link_wires_buy|
* - :ref:`cpn_resistor`
- |link_resistor_buy|
* - :ref:`cpn_led`
- |link_led_buy|
* - :ref:`cpn_mcp3008`
- \-
* - :ref:`cpn_photoresistor`
- |link_photoresistor_buy|
Diagrama esquemático
--------------------
.. .. image:: ../python_pi5/img/2.2.1_photoresistor_schematic_1.png
.. list-table::
:widths: 30 30 30 30
:header-rows: 1
* - Nombre
- T-Board
- 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.2.1_photoresistor_mcp3008.png
Procedimientos experimentales
-----------------------------
**Paso 1:** Construye el circuito.
.. image:: ../python_pi5/img/july24_2.2.1_photoresistor_mcp3008.png
**Paso 2:** Configura la interfaz SPI e instala la librería ``spidev`` (consulta :ref:`spi_configuration` para obtener instrucciones detalladas).
Si ya has completado estos pasos, puedes omitirlos.
**Paso 3:** Ve a la carpeta del código.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python-pi5
**Paso 4:** Ejecuta el archivo.
.. raw:: html
.. code-block::
sudo python3 2.2.1-2_Photoresistor_zero.py
Cuando el código se esté ejecutando, la intensidad del LED cambiará según la intensidad de luz detectada por el fotorresistor.
.. warning::
Si aparece el error ``RuntimeError: Cannot determine SOC peripheral base address``, consulta :ref:`faq_soc`
Código
------
.. note::
Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el código siguiente.
Pero antes de eso, necesitas ir a la ruta del código fuente como ``raphael-kit/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 un LED PWM en el pin GPIO 22
led = PWMLED(22)
# Inicializar la comunicación SPI (Bus 0, CE0 -> GPIO8)
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CS0
spi.max_speed_hz = 1000000 # 1 MHz
# Función para leer del canal MCP3008 (0–7)
def read_adc(channel):
"""
Leer el valor analógico del MCP3008 (0–1023)
"""
if channel < 0 or channel > 7:
return -1
# Protocolo MCP3008: bit de inicio, modo unipolar, canal (3 bits), relleno
r = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((r[1] & 3) << 8) | r[2]
return value
# Función de mapeo de valores entre rangos
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
# Bucle principal para leer el valor del ADC y controlar la intensidad del LED
def loop():
while True:
# Leer el valor analógico del canal 0 del MCP3008
analogVal = read_adc(0)
print('value = %d' % analogVal)
# Mapear 0–1023 al rango PWM 0.0–1.0
led.value = analogVal / 1023.0
# Esperar 0.2 segundos
time.sleep(0.2)
# Ejecutar el bucle principal y manejar KeyboardInterrupt para un apagado seguro
try:
loop()
except KeyboardInterrupt:
led.value = 0 # Apagar LED antes de salir
Explicación del código
----------------------
#. Se importan las clases y librerías necesarias: ``PWMLED`` de ``gpiozero`` para controlar el LED con PWM, ``spidev`` para la comunicación SPI con MCP3008 y ``time`` para las funciones de pausa.
.. code-block:: python
#!/usr/bin/env python3
import spidev
import time
from gpiozero import PWMLED
#. Se inicializa un LED PWM en el pin GPIO 22 y la interfaz SPI para MCP3008 (Bus 0, CE0). La velocidad de reloj SPI se configura a 1 MHz.
.. code-block:: python
led = PWMLED(22)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
#. Se define la función para leer un canal específico del MCP3008. Envía un comando de 3 bytes por SPI y extrae un valor de 10 bits (0–1023).
.. code-block:: python
def read_adc(channel):
if channel < 0 or channel > 7:
return -1
r = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((r[1] & 3) << 8) | r[2]
return value
#. Se define una función auxiliar ``MAP()`` que convierte un número de un rango a otro, útil para ajustar el valor del ADC al rango del PWM.
.. 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
#. Se implementa un bucle que lee el valor analógico del canal 0 del MCP3008, lo convierte al rango PWM (0.0–1.0) y ajusta la intensidad del LED en consecuencia. El bucle se ejecuta cada 0.2 segundos.
.. code-block:: python
def loop():
while True:
analogVal = read_adc(0)
print('value = %d' % analogVal)
led.value = analogVal / 1023.0
time.sleep(0.2)
#. Se ejecuta el bucle principal y se maneja la interrupción con ``KeyboardInterrupt``. Cuando el usuario detiene el programa (Ctrl+C), el LED se apaga antes de salir.
.. code-block:: python
try:
loop()
except KeyboardInterrupt:
led.value = 0