Nota

¡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 navideñas.

👉 ¿Listo para explorar y crear con nosotros? Haz clic en [Aquí] y únete hoy.

2.1.4 Potenciómetro (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

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 emplea un potenciómetro para generar un voltaje variable, que cambia la cantidad 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, necesitamos los siguientes componentes.

../_images/list2_2.1.4_potentiometer.png

Principio

MCP3008

El MCP3008 es un convertidor analógico-digital (ADC) de aproximaciones sucesivas de 10 bits con 8 canales de entrada y protocolo de comunicación SPI (Serial Peripheral Interface). Es capaz de conectarse a un microcontrolador para convertir señales analógicas de entrada en datos digitales para su posterior procesamiento.

../_images/MCP3008.jpg

Secuencia de funcionamiento

Una conversión en el MCP3008 comienza configurando el pin CS (chip select) en bajo, lo que activa la comunicación con el dispositivo. El microcontrolador envía luego una secuencia de control de 3 bytes vía SPI para especificar la configuración y seleccionar el canal de entrada.

El primer byte contiene el bit de inicio y el bit de selección simple/diferencial. Los siguientes bits indican cuál de los 8 canales (CH0–CH7) leer. Los datos se desplazan al dispositivo en cada flanco de subida del reloj SPI (SCLK), y simultáneamente se devuelve el resultado de la conversión.

Se incluye internamente un breve retardo para que el canal de entrada seleccionado se estabilice antes de comenzar la conversión. El MCP3008 realiza entonces una conversión ADC de 10 bits usando un circuito de muestreo y retención y un comparador SAR (registro de aproximaciones sucesivas).

El resultado de la conversión se transmite de vuelta al microcontrolador a través de la línea MISO (Master In Slave Out). El bit más significativo (MSB) se envía primero, seguido de los bits restantes. El microcontrolador lee el resultado a través del bus SPI durante este tiempo.

Tras enviar el valor digital completo de 10 bits, el MCP3008 completa el ciclo y espera el siguiente comando.

../_images/MCP3008detail.png

Potenciómetro

El potenciómetro también es un componente resistivo con 3 terminales, y su valor de resistencia puede ajustarse según una variación regular. Normalmente consiste en una resistencia y un contacto móvil. Cuando el contacto se desplaza a lo largo de la resistencia, se produce una determinada resistencia o voltaje de salida dependiendo del desplazamiento.

../_images/image310.png

Las funciones del potenciómetro en el circuito son las siguientes:

  1. Servir como divisor de voltaje

El potenciómetro es una resistencia ajustable de forma continua. Cuando ajustas el eje o el deslizador del potenciómetro, el contacto móvil se desliza sobre la resistencia. En ese punto, puede obtenerse un voltaje de salida dependiendo del voltaje aplicado al potenciómetro y del ángulo o distancia que recorra el brazo móvil.

Diagrama esquemático

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

../_images/schematic_2.1.7_potentiometer_mcp3008.png

Procedimiento experimental

Paso 1: Montar el circuito.

../_images/july24_2.1.7_potentiometer_mcp3008.png

Nota

Coloca el chip siguiendo la posición mostrada en la imagen correspondiente. Observa que la ranura del chip debe quedar a la izquierda al colocarlo.

Paso 2: Abrir el archivo de código.

cd ~/davinci-kit-for-raspberry-pi/c/2.1.4-2/

Paso 3: Compilar el código.

gcc 2.1.4_Potentiometer.c -lwiringPi

Paso 4: Ejecutar.

sudo ./a.out

Después de ejecutar el código, al girar la perilla del potenciómetro, la intensidad del LED cambiará en consecuencia.

Nota

Si no funciona después de ejecutarlo, o aparece el error: «wiringPi.h: No such file or directory», consulta ¿El código en C no funciona?.

Código

#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <softPwm.h>

#define SPI_CHANNEL 0  // CE0
#define SPI_SPEED   1000000  // 1MHz
#define LedPin      3

int readADC(int channel) {
    if (channel < 0 || channel > 7) return -1;

    unsigned char buffer[3];
    buffer[0] = 1;                             // Bit de inicio
    buffer[1] = (8 + channel) << 4;            // Modo de entrada simple, canal
    buffer[2] = 0;

    wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);

    int value = ((buffer[1] & 3) << 8) | buffer[2];
    return value;
}

int main(void) {
    if (wiringPiSetup() == -1) {
        printf("¡Fallo en la inicialización de WiringPi!\n");
        return 1;
    }

    if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
        printf("¡Fallo en la configuración SPI!\n");
        return 1;
    }

    softPwmCreate(LedPin, 0, 100);

    while (1) {
        int analogVal = readADC(0);  // CH0
        printf("Valor ADC: %d\n", analogVal);

        int pwmVal = analogVal * 100 / 1023;  // Normalizar a 0–100
        softPwmWrite(LedPin, pwmVal);

        delay(100);
    }

    return 0;
}

Explicación del código

#define SPI_CHANNEL 0  // CE0
#define SPI_SPEED   1000000  // 1MHz
#define LedPin      3

Define el canal SPI como CE0 (chip enable 0), establece la velocidad SPI en 1 MHz y asigna GPIO3 al pin del LED.

int readADC(int channel) {
    if (channel < 0 || channel > 7) return -1;

    unsigned char buffer[3];
    buffer[0] = 1;                             // Bit de inicio
    buffer[1] = (8 + channel) << 4;            // Modo simple, canal
    buffer[2] = 0;

    wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);

    int value = ((buffer[1] & 3) << 8) | buffer[2];
    return value;
}

Esta función se utiliza para leer datos analógicos desde el MCP3008.

  • Primero, verifica que el número de canal esté en el rango válido (0 a 7).

  • Inicializa un arreglo de 3 bytes, donde: * buffer[0] = 1: Bit de inicio para la comunicación con MCP3008. * buffer[1] = (8 + channel) << 4: Construye el byte de configuración para modo simple y selecciona el canal. * buffer[2] = 0: Byte de relleno para recibir el resultado.

  • wiringPiSPIDataRW envía y recibe datos a través del canal SPI.

  • El valor devuelto se extrae de los últimos dos bytes usando operaciones bit a bit para obtener el resultado ADC de 10 bits.

int main(void) {
    if (wiringPiSetup() == -1) {
        printf("¡Fallo en la inicialización de WiringPi!\n");
        return 1;
    }

    if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
        printf("¡Fallo en la configuración SPI!\n");
        return 1;
    }

    softPwmCreate(LedPin, 0, 100);

    while (1) {
        int analogVal = readADC(0);  // CH0
        printf("Valor ADC: %d\n", analogVal);

        int pwmVal = analogVal * 100 / 1023;  // Normalizar a 0–100
        softPwmWrite(LedPin, pwmVal);

        delay(100);
    }

    return 0;
}

En la función principal:

  • wiringPiSetup() inicializa la librería WiringPi.

  • wiringPiSPISetup() inicializa la comunicación SPI en el canal 0 a 1 MHz.

  • softPwmCreate() configura el PWM por software en GPIO3 con ciclo de trabajo inicial 0 y rango 0–100.

El programa entra en un bucle infinito donde:

  • Lee el valor ADC del canal 0 (conectado al potenciómetro).

  • Muestra el valor ADC en la terminal.

  • Convierte el valor ADC de 10 bits a un ciclo de trabajo PWM entre 0 y 100.

  • Escribe el valor PWM al LED, de forma que el brillo refleje la posición del potenciómetro.

delay(100) pausa 100 milisegundos antes del siguiente ciclo de lectura/escritura.