.. 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.1.7_py_mcp3008: 2.1.7 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 procede 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, utilizamos el chip ADC MCP3008 para realizar esta conversión. Se utiliza un potenciómetro 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 requeridos ---------------------- En este proyecto necesitamos los siguientes componentes. .. image:: ../img/list2_2.1.4_potentiometer.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 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_potentiometer` - |link_potentiometer_buy| * - :ref:`cpn_mcp3008` - \- Diagrama esquemático -------------------- .. 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.1.7_potentiometer_mcp3008.png Procedimiento experimental -------------------------- **Paso 1:** Construye el circuito. .. image:: ../img/july24_2.1.7_potentiometer_mcp3008.png .. note:: Coloca el chip siguiendo la posición indicada en la imagen. Ten en cuenta que la ranura del chip debe estar hacia la izquierda cuando se coloca. **Paso 2:** Configura la interfaz SPI e instala la librería ``spidev`` (ver :ref:`spi_configuration` para instrucciones detalladas). Si ya realizaste estos pasos, puedes omitirlos. **Paso 3:** Abre el archivo de código .. raw:: html .. code-block:: cd ~/raphael-kit/python **Paso 4:** Ejecuta. .. raw:: html .. code-block:: sudo python3 2.1.7-2_Potentiometer.py Después de ejecutar el código, gira el mando del potenciómetro y la intensidad del LED cambiará en consecuencia. .. 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 spidev import time import RPi.GPIO as GPIO # Pin GPIO para salida PWM PWM_PIN = 22 # Configuración de GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(PWM_PIN, GPIO.OUT) # Inicializar PWM en GPIO22 a 1000Hz pwm = GPIO.PWM(PWM_PIN, 1000) pwm.start(0) # Comienza con un ciclo de trabajo del 0% # Inicializar SPI spi = spidev.SpiDev() spi.open(0, 0) # Bus 0, CE0 spi.max_speed_hz = 1000000 def read_adc(channel): """ Leer valor analógico desde el 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 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 valor analógico del CH0 res = read_adc(0) print('res = %d' % res) # Convertir a ciclo de trabajo 0–100% duty_cycle = MAP(res, 0, 1023, 0, 100) # Actualizar el ciclo de trabajo del PWM pwm.ChangeDutyCycle(duty_cycle) time.sleep(0.2) except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup() spi.close() Explicación del código ---------------------- #. ``RPi.GPIO`` se utiliza para generar señales PWM y controlar un LED. ``spidev`` se usa para la comunicación SPI con el MCP3008. ``time`` se usa para añadir retrasos en el bucle. .. code-block:: python #!/usr/bin/env python3 import spidev import time import RPi.GPIO as GPIO #. Se configura el pin GPIO 22 para salida PWM usando ``RPi.GPIO``. Se establece la comunicación SPI con el MCP3008 (Bus 0, CE0) a 1 MHz. .. code-block:: python PWM_PIN = 22 GPIO.setmode(GPIO.BCM) GPIO.setup(PWM_PIN, GPIO.OUT) pwm = GPIO.PWM(PWM_PIN, 1000) # Frecuencia de 1kHz pwm.start(0) # Comienza con un ciclo de trabajo del 0% spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000 #. Esta función lee datos analógicos desde el MCP3008 en el canal especificado (0–7) utilizando el protocolo SPI. El resultado es un entero de 10 bits que va de 0 a 1023. .. code-block:: python def read_adc(channel): 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 #. Esta función mapea un valor de un rango numérico a otro. Se utiliza para escalar los valores del ADC al porcentaje del ciclo de trabajo 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 #. En el bucle principal, el programa lee continuamente datos analógicos del canal 0 del MCP3008, mapea el valor al rango de PWM (0–100) y ajusta el brillo del LED en consecuencia. El bucle se actualiza cada 0.2 segundos. Si se interrumpe (por ejemplo, Ctrl+C), el programa detiene la señal PWM y limpia la configuración de los GPIO. .. code-block:: python try: while True: res = read_adc(0) print('res = %d' % res) duty_cycle = MAP(res, 0, 1023, 0, 100) pwm.ChangeDutyCycle(duty_cycle) time.sleep(0.2) except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup() spi.close()