Nota

¡Hola! Bienvenido a la comunidad de entusiastas de SunFounder Raspberry Pi, Arduino y ESP32 en Facebook. Profundiza en el mundo de Raspberry Pi, Arduino y ESP32 con otros entusiastas.

¿Por qué unirse?

  • Soporte experto: Resuelve problemas post-venta y desafíos técnicos con la ayuda de nuestra comunidad y equipo.

  • Aprender y compartir: Intercambia consejos y tutoriales para mejorar tus habilidades.

  • Avances 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 festivas y sorteos: Participa en sorteos y promociones festivas.

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

3.1.4 Ventilador Inteligente

Nota

../_images/mcp3008_and_adc0834.jpg

Dependiendo de la versión de su kit, identifique si tiene ADC0834 o MCP3008 y continúe con la sección correspondiente.

Introducción

En este proyecto, utilizaremos motores, botones y termistores para crear un ventilador inteligente manual y automático, cuya velocidad del viento es ajustable.

Componentes Requeridos

En este proyecto, necesitamos los siguientes componentes.

../_images/list_Smart_Fan.png

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

Nombre

ELEMENTOS EN ESTE KIT

ENLACE

Raphael Kit

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

Módulo de Fuente de Alimentación

-

Termistor

COMPRAR

L293D

-

ADC0834

-

Botón

COMPRAR

Motor de corriente continua (DC)

COMPRAR

Diagrama Esquemático

Nombre T-Board

Pin físico

wiringPi

BCM

GPIO17

Pin 11

0

17

GPIO18

Pin 12

1

18

GPIO27

Pin 13

2

27

GPIO22

Pin 15

3

22

GPIO5

Pin 29

21

5

GPIO6

Pin 31

22

6

GPIO13

Pin 33

23

13

../_images/Schematic_three_one4.png

Procedimientos Experimentales

Paso 1: Construir el circuito.

../_images/image245.png

Nota

El módulo de alimentación puede usar una batería de 9V con el conector de batería de 9V incluido en el kit. Inserta el capuchón del módulo de alimentación en las tiras de bus de 5V de la placa de pruebas.

../_images/image118.jpeg

Paso 2: Accede a la carpeta del código.

cd ~/raphael-kit/c/3.1.4/

Paso 3: Compilar.

gcc 3.1.4_SmartFan.c -lwiringPi -lm

Paso 4: Ejecutar el archivo ejecutable anterior.

sudo ./a.out

Al ejecutar el código, enciende el ventilador presionando el botón. Cada vez que presiones, se ajusta un nivel de velocidad hacia arriba o hacia abajo. Hay 5 tipos de niveles de velocidad: 0~4. Cuando se configura en el 4:sup: nivel de velocidad y presionas el botón, el ventilador deja de funcionar con una velocidad de viento de 0.

Una vez que la temperatura sube o baja más de 2℃, la velocidad automáticamente aumenta o disminuye en 1 nivel.

Nota

Si no funciona después de ejecutarlo, o aparece un mensaje de error: "wiringPi.h: No such file or directory", consulta Instalar y verificar WiringPi.

Código

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

typedef unsigned char uchar;
typedef unsigned int uint;

#define ADC_CS      0
#define ADC_CLK     1
#define ADC_DIO     2
#define MotorPin1   21
#define MotorPin2   22
#define MotorEnable 23
#define BtnPin      3

uchar get_ADC_Result(uint channel)
{
    uchar i;
    uchar dat1=0, dat2=0;
    int sel = channel > 1 & 1;
    int odd = channel & 1;

    digitalWrite(ADC_CLK, 1);
    delayMicroseconds(2);
    digitalWrite(ADC_CLK, 0);
    delayMicroseconds(2);

    pinMode(ADC_DIO, OUTPUT);
    digitalWrite(ADC_CS, 0);
    // Start bit
    digitalWrite(ADC_CLK,0);
    digitalWrite(ADC_DIO,1);    delayMicroseconds(2);
    digitalWrite(ADC_CLK,1);    delayMicroseconds(2);
    //Single End mode
    digitalWrite(ADC_CLK,0);
    digitalWrite(ADC_DIO,1);    delayMicroseconds(2);
    digitalWrite(ADC_CLK,1);    delayMicroseconds(2);
    // ODD
    digitalWrite(ADC_CLK,0);
    digitalWrite(ADC_DIO,odd);  delayMicroseconds(2);
    digitalWrite(ADC_CLK,1);    delayMicroseconds(2);
    //Select
    digitalWrite(ADC_CLK,0);
    digitalWrite(ADC_DIO,sel);    delayMicroseconds(2);
    digitalWrite(ADC_CLK,1);

    digitalWrite(ADC_DIO,1);    delayMicroseconds(2);
    digitalWrite(ADC_CLK,0);
    digitalWrite(ADC_DIO,1);    delayMicroseconds(2);

    for(i=0;i<8;i++)
    {
        digitalWrite(ADC_CLK,1);    delayMicroseconds(2);
        digitalWrite(ADC_CLK,0);    delayMicroseconds(2);

        pinMode(ADC_DIO, INPUT);
        dat1=dat1<<1 | digitalRead(ADC_DIO);
    }

    for(i=0;i<8;i++)
    {
        dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))<<i);
        digitalWrite(ADC_CLK,1);    delayMicroseconds(2);
        digitalWrite(ADC_CLK,0);    delayMicroseconds(2);
    }

    digitalWrite(ADC_CS,1);
    pinMode(ADC_DIO, OUTPUT);
    return(dat1==dat2) ? dat1 : 0;
}

int temperture(){
    unsigned char analogVal;
    double Vr, Rt, temp, cel, Fah;
    analogVal = get_ADC_Result(0);
    Vr = 5 * (double)(analogVal) / 255;
    Rt = 10000 * (double)(Vr) / (5 - (double)(Vr));
    temp = 1 / (((log(Rt/10000)) / 3950)+(1 / (273.15 + 25)));
    cel = temp - 273.15;
    Fah = cel * 1.8 +32;
    int t=cel;
    return t;
}

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){ //when initialize wiring failed,print messageto screen
        printf("setup wiringPi failed !");
        return;
    }
    softPwmCreate(MotorPin1,  0, 100);
    softPwmCreate(MotorPin2,  0, 100);
    pinMode(MotorEnable,OUTPUT);
    pinMode(BtnPin,INPUT);
    pinMode(ADC_CS,  OUTPUT);
    pinMode(ADC_CLK, OUTPUT);
}

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 temperture(){
    unsigned char analogVal;
    double Vr, Rt, temp, cel, Fah;
    analogVal = get_ADC_Result(0);
    Vr = 5 * (double)(analogVal) / 255;
    Rt = 10000 * (double)(Vr) / (5 - (double)(Vr));
    temp = 1 / (((log(Rt/10000)) / 3950)+(1 / (273.15 + 25)));
    cel = temp - 273.15;
    Fah = cel * 1.8 +32;
    int t=cel;
    return t;
}

Temperture() convierte los valores del termistor leídos por ADC0834 en valores de temperatura. Consulte 2.2.2 Termistor para más detalles.

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;
}

Esta función controla la velocidad de rotación del motor. El rango del nivel: 0-4 (el nivel 0 detiene el motor). Un ajuste de nivel representa un cambio del 25% en la velocidad del viento.

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 proceso completo del programa como se muestra:

  1. Leer constantemente el estado del botón y la temperatura actual.

  2. Cada pulsación hace que el nivel +1 y al mismo tiempo, se actualice la temperatura. El nivel varía entre 1~4.

  3. Mientras el ventilador está funcionando (el nivel no es 0), la temperatura se encuentra bajo detección. Un cambio de +2℃ causa el aumento o disminución del nivel.

  4. El motor cambia la velocidad de rotación con el nivel.