Nota

¡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 [Aquí] y únete hoy mismo.

4.1.11 Indicador de Batería (MCP3008)

Nota

../_images/mcp3008_and_adc0834.jpg

Dependiendo de la versión de tu kit, identifica si tienes ADC0834 o MCP3008 y procede con la sección correspondiente.

Introducción

En este proyecto, crearemos un dispositivo indicador de batería que puede mostrar visualmente el nivel de la batería en una barra de LED (LED Bargraph).

Advertencia

No utilices componentes de batería que superen los 3.3V para evitar sobrecargas, lo que puede dañar el chip o la Raspberry Pi.

Componentes requeridos

En este proyecto, necesitamos los siguientes componentes.

../_images/list2_Battery_Indicator.png

Es definitivamente conveniente comprar un kit completo, aquí tienes el enlace:

Nombre

ELEMENTOS EN ESTE KIT

ENLACE

Kit Raphael

337

Raphael Kit

También puedes comprarlos por separado en los siguientes enlaces.

INTRODUCCIÓN DEL COMPONENTE

ENLACE DE COMPRA

Placa de Extensión GPIO

COMPRAR

Protoboard

COMPRAR

Cables de Puente

COMPRAR

Resistor

COMPRAR

Gráfico de Barras LED

-

MCP3008

-

Diagrama esquemático

T-Board

Físico

WiringPi

BCM

SPICE0

Pin 24

10

8

SPIMOSI

Pin 19

12

10

SPIMISO

Pin 21

13

9

SPISCLK

Pin 23

14

11

GPIO25

Pin 22

6

25

GPIO12

Pin 32

26

12

GPIO16

Pin 36

27

16

GPIO20

Pin 38

28

20

GPIO21

Pin 40

29

21

GPIO5

Pin 29

21

5

GPIO6

Pin 31

22

6

GPIO13

Pin 33

23

13

GPIO19

Pin 35

24

19

GPIO26

Pin 37

25

26

../_images/schematic_battery_indicator_mcp3008.png

Procedimientos experimentales

Paso 1: Construir el circuito.

../_images/july24_3.1.5_battery_indicator_mcp3008.png

Paso 2: Configura la interfaz SPI e instala la librería spidev (consulta Configuración de SPI para instrucciones detalladas). Si ya has completado estos pasos, puedes omitirlos.

Paso 3: Ve a la carpeta del código.

cd ~/raphael-kit/python

Paso 4: Ejecuta el archivo.

sudo python3 4.1.11-2_BatteryIndicator.py

Después de ejecutar el programa, conecta un cable desde el pin 3 del ADC0834 y otro desde GND, y conéctalos a los dos polos de una batería. Podrás ver que los LED correspondientes en la barra de LED se encienden para mostrar el nivel de energía (rango de medición: 0-5V).

Advertencia

Si aparece el error RuntimeError: Cannot determine SOC peripheral base address, por favor consulta Si «gpiozero» no funciona.

Código

Nota

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. Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import spidev
import time

# Pines GPIO conectados a 10 LEDs, ordenados de izquierda a derecha
led_pins = [25, 12, 16, 20, 21, 5, 6, 13, 19, 26]  # Numeración BCM

# Configuración de GPIO
GPIO.setmode(GPIO.BCM)
for pin in led_pins:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, GPIO.LOW)

# Inicializar SPI
spi = spidev.SpiDev()
spi.open(0, 0)  # Bus 0, CE0
spi.max_speed_hz = 1000000  # 1 MHz

# Leer valor del canal MCP3008
def read_adc(channel):
    if channel < 0 or channel > 7:
        return -1
    r = spi.xfer2([1, (8 + channel) << 4, 0])
    value = ((r[1] & 0x03) << 8) | r[2]
    return value

# Encender barra de LED según el valor leído
def led_bar_graph(level):
    for i, pin in enumerate(led_pins):
        if i < level:
            GPIO.output(pin, GPIO.HIGH)
        else:
            GPIO.output(pin, GPIO.LOW)

# Bucle principal
try:
    while True:
        analog_val = read_adc(0)  # Leer del canal 0 de MCP3008
        level = int(analog_val * 10 / 1023)
        led_bar_graph(level)
        print(f"ADC: {analog_val}, Nivel: {level}")
        time.sleep(0.2)

except KeyboardInterrupt:
    pass

finally:
    for pin in led_pins:
        GPIO.output(pin, GPIO.LOW)
    GPIO.cleanup()
    spi.close()

Explicación del código

Este programa lee el voltaje analógico desde un ADC MCP3008 y muestra el resultado en una barra de 10 LEDs usando una Raspberry Pi (numeración BCM).

  1. Importar módulos

    • RPi.GPIO controla los pines GPIO de la Raspberry Pi.

    • spidev se comunica con MCP3008 mediante SPI.

    • time proporciona funciones de retardo/pausa.

    #!/usr/bin/env python3
    
    import RPi.GPIO as GPIO
    import spidev
    import time
    
  2. Configuración de los LEDs GPIO

    Se define una lista de 10 pines GPIO para el control de LEDs. Estos pines se configuran como salida y se inicializan en bajo (apagados).

    # Pines GPIO conectados a 10 LEDs, ordenados de izquierda a derecha
    led_pins = [25, 12, 16, 20, 21, 5, 6, 13, 19, 26]  # Numeración BCM
    
    GPIO.setmode(GPIO.BCM)
    for pin in led_pins:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.output(pin, GPIO.LOW)
    
  3. Inicialización SPI

    Inicializa el bus SPI 0 y el chip habilitado CE0 para comunicarse con MCP3008. La velocidad de comunicación se establece en 1 MHz.

    spi = spidev.SpiDev()
    spi.open(0, 0)  # Bus 0, CE0
    spi.max_speed_hz = 1000000  # 1 MHz
    
  4. Función de lectura ADC

    Lee un valor analógico de un canal MCP3008 (0–7). La función envía un comando SPI de 3 bytes y decodifica el resultado de 10 bits.

    def read_adc(channel):
        if channel < 0 or channel > 7:
            return -1
        r = spi.xfer2([1, (8 + channel) << 4, 0])
        value = ((r[1] & 0x03) << 8) | r[2]
        return value
    
  5. Función barra de LEDs

    Enciende LEDs según el nivel analógico. Si el nivel es 7, los primeros 7 LEDs estarán encendidos y el resto apagados.

    def led_bar_graph(level):
        for i, pin in enumerate(led_pins):
            if i < level:
                GPIO.output(pin, GPIO.HIGH)
            else:
                GPIO.output(pin, GPIO.LOW)
    
  6. Bucle principal

    Lee continuamente la entrada analógica del canal 0, escala el resultado a un valor de 0 a 10 y actualiza la pantalla de LEDs en consecuencia. Imprime los valores de ADC y nivel para su monitoreo.

    try:
        while True:
            analog_val = read_adc(0)
            level = int(analog_val * 10 / 1023)
            led_bar_graph(level)
            print(f"ADC: {analog_val}, Nivel: {level}")
            time.sleep(0.2)
    
  7. Limpieza al salir

    Cuando se presiona Ctrl+C, el programa apaga todos los LEDs, limpia el estado GPIO y cierra la interfaz SPI.

    except KeyboardInterrupt:
        pass
    
    finally:
        for pin in led_pins:
            GPIO.output(pin, GPIO.LOW)
        GPIO.cleanup()
        spi.close()