.. note::
Bonjour et bienvenue dans la communauté Facebook des passionnés de SunFounder Raspberry Pi & Arduino & ESP32 ! Plongez plus profondément dans l’univers du Raspberry Pi, Arduino et ESP32 avec d’autres passionnés.
**Pourquoi nous rejoindre ?**
- **Support expert** : Résolvez vos problèmes après-vente et vos défis techniques avec l’aide de notre communauté et de notre équipe.
- **Apprendre & partager** : Échangez des conseils 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 remises exclusives sur nos derniers produits.
- **Promotions festives et cadeaux** : Participez à des concours et à des promotions spéciales.
👉 Prêt à explorer et créer avec nous ? Cliquez sur [|link_sf_facebook|] et rejoignez-nous dès aujourd’hui !
.. _3.1.4_c_pi5_mcp3008:
3.1.4 Ventilateur intelligent (MCP3008)
=======================================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Selon la version de votre kit, veuillez identifier si vous disposez du **ADC0834** ou du **MCP3008** et suivre la section correspondante.
Introduction
------------
Dans ce projet, nous allons utiliser des moteurs, des boutons et des thermistances pour créer un ventilateur intelligent manuel + automatique dont la vitesse du vent est réglable.
Composants nécessaires
----------------------
Pour ce projet, nous avons besoin des composants suivants.
.. image:: ../img/list2_Smart_Fan.png
:align: center
Schéma de câblage
-----------------
============ ======== ======== ===
Nom T-Board 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
============ ======== ======== ===
.. image:: ../img/schematic_3.1.4_smart_fan_mcp3008.png
:align: center
Procédure expérimentale
-----------------------
**Étape 1 :** Construire le circuit.
.. image:: ../img/july24_3.1.4_smart_fan_mcp3008.png
:align: center
.. note::
Le module d’alimentation peut utiliser une pile de 9 V avec le clip pour pile 9 V inclus dans le kit. Insérez le cavalier du module d’alimentation dans les rails 5 V de la plaque d’essai.
.. image:: ../img/image118.jpeg
:align: center
**Étape 2** : Accéder au dossier du code.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/c/3.1.4-2/
**Étape 3** : Compiler.
.. raw:: html
.. code-block::
gcc 3.1.4_SmartFan.c -o SmartFan -lwiringPi -lm
**Étape 4** : Exécuter le fichier exécutable ci-dessus.
.. raw:: html
.. code-block::
./SmartFan
Lorsque le code s’exécute, démarrez le ventilateur en appuyant sur le bouton. Chaque pression augmente ou diminue la vitesse d’un niveau. Il existe **5** niveaux : **0~4**. Lorsque vous êtes au 4\ :sup:`ème` niveau et que vous appuyez sur le bouton, le ventilateur s’arrête (vitesse **0**).
Dès que la température augmente ou diminue de plus de 2 ℃, la vitesse augmente ou diminue automatiquement d’un niveau.
.. note::
Si le programme ne fonctionne pas après l’exécution ou si un message d’erreur apparaît : « wiringPi.h: No such file or directory », veuillez consulter :ref:`install_wiringpi`.
Code
----
.. code-block:: c
#include
#include
#include
#include
#include
#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; // Utiliser 3.3 V comme Vref pour MCP3008
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
-------------------
.. code-block:: c
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 permet de lire l’entrée analogique sur le canal spécifié du MCP3008.
Elle envoie une commande SPI de 3 octets et renvoie une valeur numérique 10 bits comprise entre 0 et 1023.
.. code-block:: c
int temperture()
{
int analogVal = read_ADC(0);
double Vr = 3.3 * analogVal / 1023.0; // Utiliser 3.3 V comme Vref pour MCP3008
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 de la thermistance via le MCP3008,
calcule la tension, la résistance, puis convertit en Celsius et Fahrenheit en utilisant
la formule de la thermistance (approximation de Steinhart–Hart).
.. code-block:: c
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 PWM.
Le niveau va de 0 à 4 : 0 éteint le ventilateur et chaque niveau augmente le cycle de service de 25 %.
.. code-block:: c
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,
paramètre le PWM et les broches GPIO nécessaires pour le contrôle du moteur et l’entrée du bouton.
.. code-block:: c
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. Lors d’un appui sur le bouton, le niveau du ventilateur augmente (cycle 0–4) et la température est enregistrée.
3. Si la température varie de ±2 °C, la vitesse du ventilateur s’ajuste automatiquement.
4. Appelle ``motor(level)`` pour mettre à jour la sortie PWM selon le niveau actuel.