Note

Bonjour, bienvenue dans la communauté SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts sur Facebook ! Approfondissez vos connaissances sur Raspberry Pi, Arduino et ESP32 avec d’autres passionnés.

Pourquoi rejoindre ?

  • Support d’experts : Résolvez les problèmes après‑vente et les défis techniques avec l’aide de notre communauté et de notre équipe.

  • Apprendre et partager : Échangez des astuces et des tutoriels pour améliorer vos compétences.

  • Aperçus exclusifs : Accédez en avant‑première aux annonces de nouveaux produits et aux aperçus.

  • Réductions spéciales : Profitez de réductions exclusives sur nos tout derniers produits.

  • Promotions et cadeaux festifs : Participez à des concours et promotions spéciales pendant les fêtes.

👉 Prêt à explorer et à créer avec nous ? Cliquez sur [Ici] et rejoignez‑nous dès aujourd’hui !

3.1.4 Ventilateur intelligent (MCP3008)

Note

../_images/mcp3008_and_adc0834.jpg

Selon la version de votre kit, identifiez si vous disposez d’un ADC0834 ou d’un MCP3008 et suivez la section correspondante.

Introduction

Dans ce projet, nous utiliserons des moteurs, des boutons et des thermistances pour fabriquer un ventilateur intelligent manuel + automatique dont la vitesse de rotation est réglable.

Composants requis

Dans ce projet, nous avons besoin des composants suivants :

../_images/list2_Smart_Fan.png

Il est bien sûr pratique d’acheter un kit complet, voici le lien :

Nom

ÉLÉMENTS DANS CE KIT

LIEN

Kit Raphael

337

Raphael Kit

Vous pouvez également les acheter séparément via les liens ci‑dessous.

INTRODUCTION DU COMPOSANT

LIEN D’ACHAT

Carte d’extension GPIO

ACHETER

Plaque d’expérimentation (Breadboard)

ACHETER

Fils de Liaison

ACHETER

Résistance

ACHETER

Module d’Alimentation

-

Thermistance

ACHETER

L293D

-

MCP3008

-

Bouton

ACHETER

Moteur à courant continu

ACHETER

Schéma de câblage

T-Board Name

physique

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

../_images/schematic_3.1.4_smart_fan_mcp3008.png

Procédures expérimentales

Étape 1 : Construisez le circuit.

../_images/july24_3.1.4_smart_fan_mcp3008.png

Note

Le module d’alimentation peut utiliser une pile 9 V avec l’attache 9 V fournie dans le kit. Insérez le cavalier du module d’alimentation sur la barre 5 V de la plaque d’essai.

../_images/image118.jpeg

Étape 2 : Accédez au dossier du code.

cd ~/raphael-kit/c/3.1.4-2/

Étape 3 : Compilez le code.

gcc 3.1.4_SmartFan.c -o SmartFan -lwiringPi -lm

Étape 4 : Exécutez le fichier exécutable.

./SmartFan

Lorsque le programme s’exécute, démarrez le ventilateur en appuyant sur le bouton. Chaque pression ajuste la vitesse d’un cran vers le haut ou vers le bas. Il y a 5 niveaux de vitesse : 0 ~ 4. Lorsque la vitesse atteint le 4ème niveau et que vous appuyez à nouveau sur le bouton, le ventilateur s’arrête (0).

Dès que la température augmente ou diminue de plus de 2 °C, la vitesse augmente ou diminue automatiquement d’un cran.

Note

Si cela ne fonctionne pas après l’exécution ou si un message d’erreur apparaît : « wiringPi.h: No such file or directory », veuillez vous référer à Installer et vérifier WiringPi.

Code

#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 démarrage
    buffer[1] = (8 + channel) << 4;     // Mode entrée unique et 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;  // Référence de 3,3 V
    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("Échec de l’initialisation de wiringPi !\n");
        return;
    }

    if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
        printf("Échec de l’initialisation 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;
}

Explication du code

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

    unsigned char buffer[3];
    buffer[0] = 1;                      // Bit de démarrage
    buffer[1] = (8 + channel) << 4;     // Mode entrée unique et canal
    buffer[2] = 0;

    wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);

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

Cette fonction lit l’entrée analogique du MCP3008 sur le canal spécifié. Elle envoie une commande SPI de 3 octets et renvoie une valeur numérique sur 10 bits comprise entre 0 et 1023.

int temperture()
{
    int analogVal = read_ADC(0);
    double Vr = 3.3 * analogVal / 1023.0;  // Référence de 3,3 V
    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 fonction temperture() lit le signal analogique du thermistor via le MCP3008, calcule la tension, la résistance, puis convertit la valeur en degrés Celsius et Fahrenheit grâce à la formule du thermistor (approximation de 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 fonction motor() contrôle la vitesse du ventilateur via le PWM. Le niveau varie de 0 à 4, où 0 éteint le ventilateur et chaque niveau augmente le cycle de service de 25 %.

void setup()
{
    if (wiringPiSetup() == -1) {
        printf("Échec de l’initialisation de wiringPi !\n");
        return;
    }

    if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
        printf("Échec de l’initialisation SPI !\n");
        return;
    }

    softPwmCreate(MotorPin1, 0, 100);
    softPwmCreate(MotorPin2, 0, 100);
    pinMode(MotorEnable, OUTPUT);
    pinMode(BtnPin, INPUT);
}

La fonction setup() initialise WiringPi, configure le SPI, configure le PWM et les broches GPIO nécessaires au contrôle du moteur et du bouton.

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 fonction main() contient la boucle principale du programme :

  1. Vérifie constamment l’état du bouton et lit la température actuelle.

  2. À chaque appui, le niveau de vitesse augmente (cycle 0–4) et la température de référence est enregistrée.

  3. Si la température change de ±2 °C, la vitesse s’ajuste automatiquement d’un cran.

  4. Appelle motor(level) pour mettre à jour la sortie PWM en fonction du niveau actuel.