Commande pwm ventilateur pc

Bonjour à tous,

J'aimerais, dans mon meuble Hi-Fi, ventiler les appareils qui s'y trouvent. J'ai déjà les ventilateurs 12V (de PC), l'alimentation 12V, un arduino nano, une sonde de température DHT22 et une bande de LED 12V.

Selon la température dans le meuble, j'aimerais faire tourner plus ou moins fort le(s) ventilo(s). J'y arrive très bien en 5V avec les sorties PWM de l'arduino mais je me demande comment faire pour le faire en 12V?

Je ne suis pas un pro de l'électronique alors je ne sais pas quel composant prendre.

J'ai trouvé sur un site, un montage pour faire varier les couleurs d'un ruban à LED RVB. Je suppose que ce composant conviendrait: ULN 2803 - Octuple driver d'amplification de puissance on/off

Merci à vous

bonjour, tu peux partir sur un MOFSET pour le pwm

Bonjour,

Merci infobarquee pour ta réponse. J’ai fait quelques recherches et je suis arrivé à la conclusion qu’il me fallait un MOSFET IRF540N (assez commun d’après ce que j’ai compris).

RDV dans mon magasin d’électronique pour en acheter un pour 3€. J’ai fais tous mes branchements (Sonde DHT22, Ventilo et écran LCD). J’ai bien mis une résistance sur la sonde DHT22 et sur le MOFSET (10K ohms).

Du coup, je me suis fait quelques règles pour que le ventilo tourne plus ou moins vite selon la température.

#include "DHT.h"
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


#define DHTPIN A0 
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27,16,2);  // défini LCD adresse à 0x27 pour un 16 caractères et deux lignes

const int VENTILO=3; //declaration du ventilo sur la broche 3
int TEMP = 0; //on déclare l'entrée sur la broche 0


void setup() {
  // put your setup code here, to run once:
analogWrite(VENTILO,0); //Met le ventilo a l'arret au demarrage
pinMode(VENTILO, OUTPUT); //met la broche en sortie
pinMode(TEMP, INPUT); //met la broche en entree
Serial.begin(9600); //initialise le port serie
lcd.init();  // initialise le lcd
lcd.backlight(); //allume le rétroeclairage
}

void loop() {
  // put your main code here, to run repeatedly:
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    if (isnan(t) || isnan(h))
                  {
                    Serial.println("Capteur de temperature HS");
                  }
             else {
                    Serial.print("Humidity: "); 
                    Serial.print(h);
                    Serial.print(" %\t");
                    Serial.print("Temperature: "); 
                    Serial.print(t);
                    //Serial.println("");
                   }
                   
if(analogRead(t) >= 1 && analogRead(t) < 600)
{ analogWrite(VENTILO,50);Serial.println("     Vitesse: 50");lcd.print(t);lcd.print(" - 50");}

if(analogRead(t) >= 600 && analogRead(t) < 700)
{ analogWrite(VENTILO,100);Serial.println("     Vitesse: 100");lcd.print(t);lcd.print(" - 100");} 

if(analogRead(t) >= 700 && analogRead(t) < 800)
{ analogWrite(VENTILO,150);Serial.println("     Vitesse: 150");lcd.print(t);lcd.print(" - 150");}

if(analogRead(t) >= 800 && analogRead(t) < 900)
{ analogWrite(VENTILO,200);Serial.println("     Vitesse: 200");lcd.print(t);lcd.print(" - 200");}

if(analogRead(t) >= 900 && analogRead(t) < 60000)
{ analogWrite(VENTILO,255);Serial.println("     Vitesse: 255");lcd.print(t);lcd.print(" - 255");}

Serial.print("Humidite: ");
Serial.print(analogRead(t));
Serial.print("     -     ");
Serial.print("Temperature: ");
Serial.println(analogRead(t));
delay(1000);
lcd.clear();

}

Mon ventilateur passe de la vitesse “50” à la vitesse “255” sans grande variation de vitesse…

Voici les log serie:

Humidity: 69.60 %	Temperature: 25.40     Vitesse: 50
Humidite: 149     -     Temperature: 150
Humidity: 74.20 %	Temperature: 25.70     Vitesse: 50
Humidite: 151     -     Temperature: 151
Humidity: 74.20 %	Temperature: 25.70     Vitesse: 50
Humidite: 150     -     Temperature: 150
Humidity: 74.90 %	Temperature: 26.00     Vitesse: 255
Humidite: 1016     -     Temperature: 1016
Humidity: 74.90 %	Temperature: 26.00     Vitesse: 255
Humidite: 1017     -     Temperature: 1017
Humidity: 73.70 %	Temperature: 26.50     Vitesse: 255
Humidity: 49.70 %	Temperature: 26.00     Vitesse: 255
Humidite: 1016     -     Temperature: 1016
Humidity: 49.70 %	Temperature: 26.00     Vitesse: 255
Humidite: 1017     -     Temperature: 1016
Humidity: 49.30 %	Temperature: 25.90     Vitesse: 150
Humidite: 561     -     Temperature: 560
Humidity: 49.30 %	Temperature: 25.90     Vitesse: 50
Humidite: 385     -     Temperature: 385
Humidity: 49.40 %	Temperature: 25.90     Vitesse: 50
Humidite: 241     -     Temperature: 241

On remarque qu’au passage des 26° la lecture de la broche analogique change du tout au tout…
Je ne sais pas pourquoi? Des idées?
Aussi, sur cette broche analogique on peut lire de 0 à 1023 c’est bien ça?
Est-ce qu’on peut calculer la valeur de la broche à X°? Histoire de dire qu’a 20° le ventilo tourne a 50 etc etc?

Merci

Salut
je pense que tu fait une erreure dans ton programe , la librairie du DTH te renvoi directement une temperature convertie
que tu stok dans un float:

 float t = dht.readTemperature();

ça ok c’est bon , mais pourquoi essaye tu de lire la valeur sur une broche definie par t

if(analogRead(t) >= 1 && analogRead(t) < 600)
{ analogWrite(VENTILO,50);Serial.println("     Vitesse: 50");lcd.print(t);lcd.print(" - 50");}

analog read va aller lire la tension sur la broche definie par t or t est ici une temperature!

je pense que c’est ça que tu cherchai a faire :

if(t>30.0 && t<=35.0)
{ analogWrite(VENTILO,50);Serial.println("     Vitesse: 50");lcd.print(t);lcd.print(" - 50");}

je crois pas que les valeurs soient proportionnelles. mieux vaut passer par la temp en C et humidité en %

avec certains mofset, la différence pwm n'est pas flagrante, on passe de 50 à 100% comme ca.

je ferai un truc du style que le pwm corresponde à la temp, plus la temp monte, plus le pwm monte.

float t = dht.readTemperature();
int temp = t;
analogWrite(VENTILO, temp);

Re,

Ahhhhhhhhhhhhhhhh ben voilà! Merci Heloderma-kris! C'est bien ça que je cherchais! Je crois que je me suis pris la tête pour rien lol... En tous cas, ca fonctionne nickel pour les paliers de températures définis!

J'avance... J'avance...

je te proposerai bien une amelioration :
partant du principe que la temperature de déclanchement et de 20°C et que tu veux une plage de progrésion linéaire avec la temperature jusqu’a un max de 40°C pour fonctionement total
tu peut faire

alors :

int vitesse=0// vittesse a transmetre en valeur de 0 à 255
int offset=20;// mimnima de declanchement
int largeur_plage=20;//40°C-20°c
vitesse=(t - offset) * (256 / largeur_plage);// on calcul la vitesse
if(vitesse<0){vitesse=0};on verifie les bornes
if(vitesse>255){vitesse=255};
analogWrite(VENTILO, vitesse);// on injecte un signal PWM proportionel a la vitesse calculer
Serial.print("Vitesse: ");Serial.println(((t - 20) / 20) * 100));
lcd.print(((t - 20) / 20) * 100));
lcd.print("%");

tu devrai avoir une augmentation de la vitesse linaire ( si je me suis pas planter dans le calcule)

Oui, c'est sûrement mieux comme tu viens de me dire.

Le problème pour le moment, c'est que je ne connais pas vraiment la température moyenne dans le meuble.

Je suppose être dans les 40° en temps normal. Tout dépend aussi de où sera placé la sonde.

Je peux tester le code (ce que je vais faire d'ailleurs) en chauffant la sonde dans ma main et te dire le résultat.

Par contre, c'est assez difficile comme code :o . Je ne sais pas, si je regarde le code dans deux mois, je comprennes encore! :confused:

Je teste

le code n'est pas des plus compliqué a la limite ce qui t'effrais un peut c'est les calcule et dans le cas présent c'est du produit en croix

le PWM géré par analogWrite ce pilote de 0 a 255 soit sur 256 valeur, ce qui corespond a 0 à 100%

ensuite on transforme la valeur de temperature moins sont minima en valeur de 0 a 256

t-offset: exemple t=30°C offset 20°C on a donc un delta de 10°C

10*256/largeur_plage: on transforme en valeur de 0 a 256 la notre plage fai 40°C-20°C c'est entre ces 2 borne que lon va faire varier la vitesse soit sur 20°C ce qui nous donne 10*256/20=128

on injecte ça dans analogWrite(ventilo,128); tu auras donc normalement a 30°C un signal PWM dont le rappord cyclique est 128 ou bien encore 50% donc ton ventilo tournera a 50% de ça vitesse max.

Donc, là dans ton exemple, à 40° le ventilo tournera à fond?

Si oui, il faut que je modifie la plage entre 30° et 50°.. Il me suffit de mettre l'offset à 30, exact? Si oui toujours, avec l'offset à 30, je suis a 36% de ventilation (avec une température a 27°) et le ventilo reste à l'arrêt.

Voici quelques relevés:

Humidity: 45.00 %   Temperature: 26.70     Vitesse: 33.50

Humidity: 40.00 %   Temperature: 28.70     Vitesse: 43.50

Humidity: 77.60 %   Temperature: 30.10     Vitesse: 50.50

Humidity: 56.30 %   Temperature: 34.40     Vitesse: 72.00

Humidity: 83.10 %   Temperature: 34.80     Vitesse: 74.00

Humidity: 89.00 %   Temperature: 35.40     Vitesse: 77.00

iNouNours:
Donc, là dans ton exemple, à 40° le ventilo tournera à fond?

Si oui, il faut que je modifie la plage entre 30° et 50°… Il me suffit de mettre l’offset à 30, exact?
.

oui dans le cas présent c’est ça :slight_smile:

Si oui toujours, avec l’offset à 30, je suis a 36% de ventilation (avec une température a 27°) et le ventilo reste à l’arrêt.

avec un offset a 30 le calcul donerait -15% or les boucles de controle limite entre 0 et 100 donc le ventilo sera arrété car :

if(vitesse<0)// si vitesse est négative 
{vitesse=0;}//alors vitesse =0

Je ne comprend pas le calcul...

L'idéal serait qu'a 40° le PWM soit a 128.

Si on se réfère à ça:

( t      offset )   (   256        largeur_plage   )

( 50° -   30    ) * (   256   /       20           ) = 256 à 50°
( 40° -   30    ) * (   256   /       20           ) = 128 à 40°

Les calculs sont justes non?

oui c'est ça ! qu'est ce que tu ne comprend pas ?

Salut,

Dans le post d'avant tu me dis que si je met le "offset" à 30, après calcul ça donne -15%.

Et du coup, d'après mes calculs c'est juste.. C'est déconcertant.

En dessous de 30% (je crois) le ventilateur ne tourne pas et émet un petit sifflement..

Et donc, avec l'offset à 30 j'ai l'impression que le calcul du % sur le lcd et le port serie est faux.

Ok on c est pas compris il faut modifier aussi dans la partie retour serie par :

((t-offset)/largeur_plage)*100) ou on vire l’ofset source du probléme de compréhension

donc au final tu as :

int vitesse=0// vittesse a transmetre en valeur de 0 à 255
float t =0;// temperature mesuré
float tempMin=30.0;// temperature de declanchement ventilo a 0%
float tempMax=50.0;// temperature max ventilo a100%
int largeur_plage= tempMax - tempMin;//50°C-30°c

vitesse=(t - tempMin) * (256 / largeur_plage);// on calcul la vitesse

if(vitesse<0){vitesse=0};//on verifie les bornnes
if(vitesse>255){vitesse=255};

analogWrite(VENTILO, vitesse);// on injecte un signal PWM proportionel a la vitesse calculer

Serial.print("Vitesse: ");Serial.println(((t - tempMin) / largeur_plage) * 100));
lcd.print(((t - tempMin) / largeur_plage) * 100));
lcd.print("%");

apres il est posible qu’en dessous d’un certain seuil le ventilo ne tourne pas , la en téhorie c’est a 0% mais a cause de la limite de puissance fournie a basse vitesse il n’arrive peutetre pas a s’enclanché dans ce cas change dans les valeurs des boucle de limite ,ex:

if(vitesse<64){vitesse=64};//on verifie les bornnes
if(vitesse>255){vitesse=255};

ici en desous de 25% de la vitésse max le ventilo sera forcé a 25%, donc il ne desendra jamais en desous de 25%.

Voilà! Ca me parait bien plus simple comme ça. Et plus facile à gérer aussi.
J’ai modifié à ma sauce.

Merci Heloderma-kris :kissing:

Voici mon code:

#include "DHT.h"
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


#define DHTPIN A0 
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27,16,2);  // défini LCD adresse à 0x27 pour un 16 caractères et deux lignes

const int VENTILO=3; //declaration du ventilo sur la broche 3
int TEMP = 0; //on déclare l'entrée sur la broche 0
int vitesse=0;// vittesse a transmetre en valeur de 0 à 255
float t =0;// temperature mesuré
float tempMin=30.0;// temperature de declanchement ventilo a 0%
float tempMax=50.0;// temperature max ventilo a100%
int largeur_plage= tempMax - tempMin;//50°C-30°c


void setup() {
                analogWrite(VENTILO,0); //Met le ventilo a l'arret au demarrage
                pinMode(VENTILO, OUTPUT); //met la broche en sortie
                pinMode(TEMP, INPUT); //met la broche en entree
                Serial.begin(9600); //initialise le port serie
                lcd.init();  // initialise le lcd
                lcd.backlight(); //allume le rétroeclairage
              }

void loop() {

    float h = dht.readHumidity();
    float t = dht.readTemperature();
    if (isnan(t) || isnan(h))
                  {
                    Serial.println("Capteur de temperature HS");
                    error();
                    return;
                  }

Serial.print("Humidite: "); 
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: "); 
Serial.print(t);
                    


vitesse=(t - tempMin) * (256 / largeur_plage);// on calcul la vitesse
if(vitesse<=50){vitesse=50;} // on verifie les bornes
if(vitesse>=255){vitesse=255;} // a fond!

analogWrite(VENTILO, vitesse); // on injecte un signal PWM proportionel a la vitesse calculer
Serial.print("     Vitesse:");
Serial.print(((t - tempMin) / largeur_plage) * 100);lcd.print("%         ");;
Serial.println(" %\t");
lcd.setCursor(0,0);
lcd.print("V: ");

if (vitesse<=50)
          {lcd.print("Vitesse mini");}
else if (vitesse>=255)
          {lcd.print("Vitesse maxi");}
else
          {lcd.print(((t - tempMin) / largeur_plage) * 100);lcd.print("%         ");}
lcd.setCursor(0,1);
lcd.print("T: ");
lcd.print(t);
lcd.print((char)223);
lcd.print("C      ");
delay(1000);
}

void error(){
                lcd.setCursor(0,0);
                lcd.print("V: Vitesse maxi "); //Affichage écran
                lcd.setCursor(0,1);
                lcd.print("T: Capteur HS   "); //Affichage écran
                analogWrite(VENTILO, 255);     //Dans le doute, ventilo à fond
                tone(6, 440, 500);delay(5000); //Buzzer sur le pin D6
            }

C’est surement encore perfectible…
Il me reste à rajouter le code pour gérer des relais pour allumer mes lampes via le web avec l’interface Ethernet et je crois que ce sera fini :stuck_out_tongue: :wink:

Me revoilà pour vous donner des nouvelles.
J’ai intégré du code pour avoir une gestion de 4 relais via le Web avec une URL pour activer et une URL pour désactiver le relais.

Pour le moment je suis obligé d’héberger la page d’appel sur mon PC, ce qui n’est pas le top.
J’appel mon URL ex: http://IP_ARDUINO/$x et mon arduino génère une page html qui me fait un retour arrière et donc je revient sur la page de mon PC.

J’aimerais taper l’adresse de mon arduino et tomber sur un bouton “allumer” et un bouton “eteindre” et que ça fonctionne mais je ne trouve pas…
Quand j’y arrive, les infos de température ne se mettent plus à jour sur le LCD.

Quelqu’un a une idée?

PS: J’ai posté mon code en fichier car il est trop gros pour être écrit dans le post.

Projet_meuble_fini.ino (10.3 KB)

J'ai l'impression que tu as mis le sketch qui marche (PC + Arduino) et pas celui qui ne marche pas (arduino seul).

Salut, oui, ce sketch fonctionne. Comme celui avec l’arduino seul ne fonctionnait pas… :astonished:
Mais je vais le refaire

Sinon en gros, le seul moment où j’ai réussi à afficher quelque chose en mettant l’adresse ip de l’arduino c’est en modifiant la fin du sketch

else if (c != '\r') { currentLineIsBlank = false; }

Par

else if (c != '\r') { currentLineIsBlank = false; 
                       client.println("<html>");
                       client.println("<head>");
                       client.println("<title>Arduino</title>");
                       client.println("</head>");
                       client.println("<body>");
                       client.println("<a href=\"./$b\">Allumer la lampe relais 2</a>");
                       client.println("
");
                       client.println("<a href=\"./$a\">Eteindre la lampe relais 2</a>");
                       client.println("</body>");
                       client.println("</html>");
                       client.stop();
                     }

Là, la température marche correctement mais ca n’allume pas mes relais…
Je ne sais pas vraiment où placer mes commandes, peut être avec du javascript mais je ne sais pas faire :frowning: