.. 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.
- **Aprende y comparte**: Intercambia consejos y tutoriales para mejorar tus habilidades.
- **Avances 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 festivas y sorteos**: 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.2.1_py_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 la luz ambiental.
Ayuda al controlador a reconocer el día y la noche y a realizar funciones de control de luz como una lámpara nocturna.
Este proyecto es muy similar al del potenciómetro, y puedes pensar que cambia el voltaje para detectar la luz.
Componentes requeridos
----------------------
En este proyecto, necesitamos los siguientes componentes.
.. image:: ../img/list2_2.2.1_photoresistor.png
Es definitivamente conveniente comprar un kit completo, aquí está el enlace:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - Nombre
- ARTÍCULOS EN ESTE KIT
- ENLACE
* - Kit Raphael
- 337
- |link_Raphael_kit|
También puedes comprarlos por separado desde 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:: ../img/2.2.1_photoresistor_schematic_1.png
.. list-table::
:widths: 30 30 30 30
:header-rows: 1
* - Nombre T-Board
- physical
- WiringPi
- BCM
* - SPICE0
- pin24
- 10
- 8
* - SPIMOSI
- pin19
- 12
- 10
* - SPIMISO
- pin21
- 13
- 9
* - SPISCLK
- pin23
- 14
- 11
* - GPIO22
- pin15
- 3
- 22
.. image:: ../img/schematic_2.2.1_photoresistor_mcp3008.png
Procedimientos experimentales
-----------------------------
**Paso 1:** Construye el circuito.
.. image:: ../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 instrucciones detalladas). Si ya realizaste estos pasos, puedes omitirlos.
**Paso 3:** Ve a la carpeta del código.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python
**Paso 4:** Ejecuta el archivo.
.. raw:: html
.. code-block::
sudo python3 2.2.1-2_photoresistor.py
Cuando el código está en ejecución, el brillo del LED cambiará de acuerdo con la intensidad de la 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 de abajo.
Pero antes, necesitas ir a la ruta del código fuente como ``raphael-kit/python``.
Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
# Pin GPIO para el LED PWM
PWM_PIN = 22
# Configuración de GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(PWM_PIN, GPIO.OUT)
# Inicializar PWM (frecuencia = 1000Hz)
pwm = GPIO.PWM(PWM_PIN, 1000)
pwm.start(0) # Inicia con un ciclo de trabajo del 0%
# Inicializar SPI (MCP3008 en Bus 0, CE0)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000 # 1 MHz
# Función para leer valor ADC de MCP3008
def read_adc(channel):
"""
Lee el valor analógico del MCP3008 (canal 0–7)
Retorna: valor de 10 bits (0–1023)
"""
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
# Bucle principal para leer ADC y ajustar el brillo del PWM
try:
while True:
analogVal = read_adc(0)
print(f"value = {analogVal}")
# Escalar valor ADC (0–1023) a ciclo de trabajo (0–100)
duty_cycle = analogVal * 100 / 1023
pwm.ChangeDutyCycle(duty_cycle)
time.sleep(0.2)
except KeyboardInterrupt:
pass
finally:
pwm.stop()
GPIO.cleanup()
spi.close()
Explicación del código
----------------------
#. Importar librerías necesarias:
- ``RPi.GPIO`` para controlar pines GPIO y generar señal PWM.
- ``spidev`` para comunicarse con el MCP3008 a través de SPI.
- ``time`` para gestionar temporización y retardos.
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
#. Configurar el pin GPIO 22 como salida PWM usando el modo BCM.
Inicializar el PWM por software a 1000 Hz con un ciclo de trabajo inicial del 0%.
.. code-block:: python
PWM_PIN = 22
GPIO.setmode(GPIO.BCM)
GPIO.setup(PWM_PIN, GPIO.OUT)
pwm = GPIO.PWM(PWM_PIN, 1000)
pwm.start(0)
#. Configurar la interfaz SPI para comunicarse con el MCP3008 en el bus 0, CE0, y establecer la velocidad SPI en 1 MHz.
.. code-block:: python
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
#. Definir una función ``read_adc(channel)`` para leer valores analógicos desde el MCP3008.
Envía tres bytes al chip y reconstruye un valor analógico de 10 bits (0–1023) a partir de la respuesta.
.. 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
#. Este es el bucle principal que:
- Lee la entrada analógica del canal 0 del MCP3008.
- Convierte el valor a un ciclo de trabajo PWM (0–100%).
- Ajusta el brillo del LED usando ``pwm.ChangeDutyCycle()``.
- Se repite cada 0,2 segundos.
.. code-block:: python
try:
while True:
analogVal = read_adc(0)
print(f"value = {analogVal}")
duty_cycle = analogVal * 100 / 1023
pwm.ChangeDutyCycle(duty_cycle)
time.sleep(0.2)
#. Cuando el usuario interrumpe el programa con Ctrl+C, el PWM y los GPIO se limpian correctamente, y la interfaz SPI se cierra.
.. code-block:: python
except KeyboardInterrupt:
pass
finally:
pwm.stop()
GPIO.cleanup()
spi.close()