Nota
¡Hola! Bienvenido a la Comunidad de Entusiastas de SunFounder Raspberry Pi & Arduino & ESP32 en Facebook. Profundiza en Raspberry Pi, Arduino y ESP32 junto 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 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 de temporada.
👉 ¿Listo para explorar y crear con nosotros? Haz clic en [Aquí] y únete hoy mismo.
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, usamos el chip ADC MCP3008 para realizar esta conversión. Un potenciómetro se utiliza 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 necesarios
En este proyecto, necesitamos los siguientes componentes.
Principio
MCP3008
MCP3008 es un convertidor analógico-digital (ADC) de aproximaciones sucesivas de 10 bits con 8 canales de entrada y un protocolo de comunicación SPI (Serial Peripheral Interface). Puede comunicarse con un microcontrolador para convertir señales analógicas en datos digitales para su posterior procesamiento.
Secuencia de funcionamiento
Una conversión en el MCP3008 comienza poniendo el pin CS (chip select) en bajo, lo que activa la comunicación con el dispositivo. El microcontrolador envía entonces un flujo de control de 3 bytes a través de la interfaz SPI para especificar la configuración y seleccionar el canal de entrada.
El primer byte enviado 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) se va a leer. Los datos se introducen en el dispositivo en cada flanco ascendente del reloj SPI (SCLK) y el resultado de la conversión se devuelve simultáneamente.
Se incluye un breve retardo interno para que el canal de entrada seleccionado se estabilice antes de que comience la conversión. Luego, el MCP3008 realiza una conversión ADC de 10 bits utilizando un circuito de muestreo y retención y un comparador SAR.
El resultado de la conversión se transmite de nuevo al microcontrolador a través de la línea MISO (Master In Slave Out). El bit más significativo (MSB) del resultado de 10 bits se envía primero, seguido por los bits restantes. El microcontrolador lee el resultado por el bus SPI durante este tiempo.
Después de que se desplaza el valor digital completo de 10 bits, el MCP3008 completa el ciclo y espera el siguiente comando.
Potenciómetro
El potenciómetro es también un componente resistivo con 3 terminales y su valor de resistencia puede ajustarse según una variación regulada. Generalmente consiste en una resistencia y un cursor móvil. Cuando el cursor se desplaza a lo largo de la resistencia, se obtiene una cierta resistencia o voltaje de salida dependiendo del desplazamiento.
Las funciones del potenciómetro en el circuito son las siguientes:
Servir como divisor de voltaje
Un potenciómetro es una resistencia ajustable de forma continua. Cuando ajustas el eje o el deslizador, el contacto móvil se desplazará sobre la resistencia. En ese momento, se puede obtener un voltaje de salida que depende del voltaje aplicado al potenciómetro y del ángulo o distancia recorrida por 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 |
Procedimientos experimentales
Paso 1: Construye el circuito.
Nota
Coloca el chip según la posición mostrada en la imagen. Ten en cuenta que las muescas del chip deben quedar a la izquierda al colocarlo.
Para usuarios de lenguaje C
Paso 2: Abre el archivo de código.
cd ~/davinci-kit-for-raspberry-pi/c/2.1.4-2/
Paso 3: Compila el código.
gcc 2.1.4_Potentiometer.c -lwiringPi
Paso 4: Ejecuta.
sudo ./a.out
Cuando el código se ejecute, al girar la perilla del potenciómetro, la intensidad del LED cambiará en consecuencia.
Nota
Si no funciona después de ejecutar o aparece el error «wiringPi.h: No such file or directory», consulta Instalar y Comprobar WiringPi.
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 un solo extremo, 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
Se definen las constantes para el canal SPI (CE0), la velocidad (1 MHz) y el pin del LED (GPIO3).
#define SPI_CHANNEL 0 // CE0
#define SPI_SPEED 1000000 // 1MHz
#define LedPin 3
La función
readADClee datos analógicos del MCP3008. Comprueba que el canal esté entre 0 y 7, configura los bytes de control, realiza la transferencia SPI y extrae el valor ADC de 10 bits.
int readADC(int channel) {
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // Start bit
buffer[1] = (8 + channel) << 4; // Single-ended mode, channel
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int value = ((buffer[1] & 3) << 8) | buffer[2];
return value;
}
En la función
main:wiringPiSetup()inicializa la biblioteca WiringPi.wiringPiSPISetup()configura la comunicación SPI en el canal 0 a 1 MHz.softPwmCreate()configura el PWM por software en GPIO3.
Luego entra en un bucle infinito que: * Lee el valor del canal 0. * Lo imprime. * Lo convierte a un ciclo de trabajo PWM entre 0 y 100. * Ajusta el brillo del LED según la posición del potenciómetro.
int main(void) {
if (wiringPiSetup() == -1) {
printf("WiringPi init failed!\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("SPI setup failed!\n");
return 1;
}
softPwmCreate(LedPin, 0, 100);
while (1) {
int analogVal = readADC(0); // CH0
printf("ADC Value: %d\n", analogVal);
int pwmVal = analogVal * 100 / 1023; // Normalize to 0–100
softPwmWrite(LedPin, pwmVal);
delay(100);
}
return 0;
}
Para usuarios de Python
Paso 2: Configura la interfaz SPI e instala la librería spidev (consulta Configuración de SPI para instrucciones detalladas). Si ya lo hiciste, puedes omitir este paso.
Paso 3: Abre el archivo de código.
cd ~/davinci-kit-for-raspberry-pi/python
Paso 4: Ejecuta.
sudo python3 2.1.4-2_Potentiometer.py
Al ejecutar el código, al girar la perilla del potenciómetro, la intensidad del LED cambiará en consecuencia.
Advertencia
Si aparece el error RuntimeError: Cannot determine SOC peripheral base address, consulta Si gpiozero no funciona..
Código
#!/usr/bin/env python3
import spidev
import time
import RPi.GPIO as GPIO
PWM_PIN = 22
GPIO.setmode(GPIO.BCM)
GPIO.setup(PWM_PIN, GPIO.OUT)
pwm = GPIO.PWM(PWM_PIN, 1000)
pwm.start(0)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
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
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
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()
Explicación del código
RPi.GPIOse utiliza para generar señales PWM que controlan un LED.spidevmaneja la comunicación SPI con el MCP3008.timese usa para las pausas.#!/usr/bin/env python3 import spidev import time import RPi.GPIO as GPIO
Se configura el pin GPIO22 para salida PWM. Se establece la comunicación SPI en el bus 0, CE0, a 1 MHz.
PWM_PIN = 22 GPIO.setmode(GPIO.BCM) GPIO.setup(PWM_PIN, GPIO.OUT) pwm = GPIO.PWM(PWM_PIN, 1000) # 1kHz frequency pwm.start(0) # Start with 0% duty cycle spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000
read_adclee datos analógicos del MCP3008 (canales 0–7) y devuelve un valor entero de 0 a 1023.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
MAPconvierte un valor de un rango numérico a otro, usado aquí para escalar el valor ADC al ciclo de trabajo PWM (0–100).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:
Lee el canal 0.
Imprime el valor.
Lo mapea a un porcentaje PWM.
Ajusta el brillo del LED.
El bucle se repite cada 0,2 segundos. Con Ctrl+C se detiene y limpia la configuración.
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()