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.
3.1.4 Ventilador Inteligente (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
En este proyecto usaremos motores, botones y termistores para crear un ventilador inteligente manual + automático cuya velocidad de viento se puede ajustar.
Componentes necesarios
En este proyecto, necesitamos los siguientes componentes.
Diagrama esquemático
T-Board Name |
physical |
wiringPi |
BCM |
SPICE0 |
Pin 24 |
10 |
8 |
SPIMOSI |
Pin 19 |
12 |
10 |
SPIMISO |
Pin 21 |
13 |
9 |
SPISCLK |
Pin 23 |
14 |
11 |
GPIO22 |
Pin 15 |
3 |
22 |
GPIO5 |
Pin 29 |
21 |
5 |
GPIO6 |
Pin 31 |
22 |
6 |
GPIO13 |
Pin 33 |
23 |
13 |
Procedimiento experimental
Paso 1: Montar el circuito.
Nota
El módulo de alimentación puede usar una batería de 9V con el clip para batería incluido en el kit. Inserta el puente del módulo de alimentación en las líneas de 5V de la protoboard.
Paso 2: Entrar en la carpeta del código.
cd ~/davinci-kit-for-raspberry-pi/c/3.1.4-2/
Paso 3: Compilar.
gcc 3.1.4_SmartFan.c -o SmartFan -lwiringPi -lm
Paso 4: Ejecutar el archivo compilado.
./SmartFan
Al ejecutar el código, inicia el ventilador presionando el botón. Cada vez que lo presiones, la velocidad aumenta o disminuye en 1 nivel. Hay 5 niveles de velocidad: 0~4. Cuando esté en el nivel 4 y presiones el botón, el ventilador se detendrá con velocidad 0.
Si la temperatura sube o baja más de 2℃, la velocidad aumenta o disminuye automáticamente en 1 nivel.
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>
#include <math.h>
#define SPI_CHANNEL 0
#define SPI_SPEED 1000000
#define MotorPin1 21
#define MotorPin2 22
#define MotorEnable 23
#define BtnPin 3
int read_ADC(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 entrada única + canal
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int result = ((buffer[1] & 3) << 8) | buffer[2];
return result;
}
int temperture()
{
int analogVal = read_ADC(0);
double Vr = 3.3 * analogVal / 1023.0; // Vref = 3.3V
double Rt = 10000.0 * Vr / (3.3 - Vr);
double temp = 1 / (((log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)));
double cel = temp - 273.15;
double Fah = cel * 1.8 + 32;
printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah);
return (int)cel;
}
int motor(int level)
{
if (level == 0) {
digitalWrite(MotorEnable, LOW);
return 0;
}
if (level >= 4) {
level = 4;
}
digitalWrite(MotorEnable, HIGH);
softPwmWrite(MotorPin1, level * 25);
return level;
}
void setup()
{
if (wiringPiSetup() == -1) {
printf("¡Fallo en configuración wiringPi!\n");
return;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("¡Fallo en configuración SPI!\n");
return;
}
softPwmCreate(MotorPin1, 0, 100);
softPwmCreate(MotorPin2, 0, 100);
pinMode(MotorEnable, OUTPUT);
pinMode(BtnPin, INPUT);
}
int main(void)
{
setup();
int currentState, lastState = 0;
int level = 0;
int currentTemp, markTemp = 0;
while (1) {
currentState = digitalRead(BtnPin);
currentTemp = temperture();
if (currentTemp <= 0) continue;
if (currentState == 1 && lastState == 0) {
level = (level + 1) % 5;
markTemp = currentTemp;
delay(500);
}
lastState = currentState;
if (level != 0) {
if (currentTemp - markTemp <= -2) {
level = level - 1;
markTemp = currentTemp;
}
if (currentTemp - markTemp >= 2) {
level = level + 1;
markTemp = currentTemp;
}
}
level = motor(level);
}
return 0;
}
Explicación del código
int read_ADC(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 entrada única + canal
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int result = ((buffer[1] & 3) << 8) | buffer[2];
return result;
}
Esta función lee la entrada analógica del MCP3008 en el canal indicado. Envía un comando SPI de 3 bytes y devuelve un valor digital de 10 bits (0–1023).
int temperture()
{
int analogVal = read_ADC(0);
double Vr = 3.3 * analogVal / 1023.0; // Vref = 3.3V
double Rt = 10000.0 * Vr / (3.3 - Vr);
double temp = 1 / (((log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)));
double cel = temp - 273.15;
double Fah = cel * 1.8 + 32;
printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah);
return (int)cel;
}
La función temperture() lee la señal analógica del termistor a través del MCP3008,
calcula el voltaje, luego la resistencia, y la convierte a °C y °F usando la fórmula del termistor (aproximación Steinhart–Hart).
int motor(int level)
{
if (level == 0) {
digitalWrite(MotorEnable, LOW);
return 0;
}
if (level >= 4) {
level = 4;
}
digitalWrite(MotorEnable, HIGH);
softPwmWrite(MotorPin1, level * 25);
return level;
}
La función motor() controla la velocidad del ventilador mediante PWM.
El nivel va de 0 a 4, donde 0 apaga el ventilador y cada nivel incrementa el ciclo de trabajo un 25%.
void setup()
{
if (wiringPiSetup() == -1) {
printf("¡Fallo en configuración wiringPi!\n");
return;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("¡Fallo en configuración SPI!\n");
return;
}
softPwmCreate(MotorPin1, 0, 100);
softPwmCreate(MotorPin2, 0, 100);
pinMode(MotorEnable, OUTPUT);
pinMode(BtnPin, INPUT);
}
La función setup() inicializa WiringPi, configura SPI, y prepara PWM y GPIO para el control del motor y la lectura del botón.
int main(void)
{
setup();
int currentState, lastState = 0;
int level = 0;
int currentTemp, markTemp = 0;
while (1) {
currentState = digitalRead(BtnPin);
currentTemp = temperture();
if (currentTemp <= 0) continue;
if (currentState == 1 && lastState == 0) {
level = (level + 1) % 5;
markTemp = currentTemp;
delay(500);
}
lastState = currentState;
if (level != 0) {
if (currentTemp - markTemp <= -2) {
level = level - 1;
markTemp = currentTemp;
}
if (currentTemp - markTemp >= 2) {
level = level + 1;
markTemp = currentTemp;
}
}
level = motor(level);
}
return 0;
}
La función main() contiene el bucle principal:
Lee el estado del botón y la temperatura actual.
Al presionar el botón, aumenta el nivel del ventilador (ciclando 0–4) y guarda la temperatura de referencia.
Si la temperatura cambia ±2°C, ajusta la velocidad del ventilador automáticamente.
Llama a
motor(level)para actualizar el PWM según el nivel actual.