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
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.
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.
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.
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.
Las funciones del potenciómetro en el circuito son las siguientes:
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 |
Procedimiento experimental
Paso 1: Montar el circuito.
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.wiringPiSPIDataRWenví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.