// Variation de la vitesse des ventilateurs de l'alimentation // 30A en fonction de la température du dissipateur à l'arrière. // LM35DT (TO220) pour la mesure de la température. // ACS712-30 pour la mesure du courant. // Ventilateurs commandés par sortie PWM intégrée et amplifiée. // Alarme température élevée. // Mesure tension, courant et puissance de sortie. // Affichage sur LCD-I2C de 2 lignes de 24 caractères. // Compilation avec IDE Arduino 1.8.10 // www.rotilom.com/F6IDT/alim30a.htm // Version V.04 (août 2021) #include #include ///// ENTREES ///// #define TEMP_ADC A0 // Mesure température avec un LM 35DT #define INTENS_ADC A2 // Mesure intensité avec un ACS712-30 #define TENSION_ADC A3 // Mesure tension de sortie ///// SORTIES ///// #define PWM_PIN 3 // Contrôle du ventilateur par PWM_PIN #define ALARME 13 // Alarme temérature élevée //// PARAMETRES //// #define MOY_NUM 20 // Nombre de mesures à moyenner //------------------------------------------------------------------ ////////////// DECLARATION DES VARIABLES GLOBALES ////////////////// //------------------------------------------------------------------ int temperature = 0; int PWM = 0; int vit = 0; float tension = 0; float intensite = 0; float msec = 0; float last_msec = 0; float elasped_msec = 0; float elasped_time = 0; float puissance = 0; // Adresse du LCD de 2 lignes de 24 caractères // en général, c'est une de ces deux adresses selon le contrôleur LiquidCrystal_I2C lcd(0x3F, 24, 2); //LiquidCrystal_I2C lcd(0x27, 24, 2); //****************** DEBUT PROGRAMME ************************* void setup() { Serial.begin(9600); // vitesse moniteur série // Fréquence PWM_PIN = 31,4 kHz TCCR2B = TCCR2B & B1111000 | B00000001; pinMode(PWM_PIN,OUTPUT); digitalWrite(PWM_PIN,LOW); pinMode(ALARME,OUTPUT); digitalWrite(ALARME,LOW); lcd.begin(); // initialisation du LCD I2C lcd.backlight(); lcd.setCursor(0, 0); lcd.print(" ALIMENTATION 13.8V 30A "); lcd.setCursor(0,1); lcd.print(" F6IDT V.04 (08-2021) "); delay(2500); lcd.clear(); lcd.setCursor(0, 0); } void loop() { read_data(); // lecture des entrées analogiques ventilo_PWM(); // PWM sur ventilateur power(); // calcul de la puissance print_data(); // affichage dans le serial monitor lcd_display(); // affichage sur LCD delay(500); // 5 mesures par seconde } //********************* FIN PROGRAMME ***************************** //----------------------------------------------------------------- /////////// LECTURE ET MOYENNAGE DES ENTREES ANALOGIQUES ////////// //----------------------------------------------------------------- int read_adc(int adc_parameter) { int sum = 0; int sample ; for (int i = 0; i < MOY_NUM; i++) { // Boucle MOY_NUM de fois sample = analogRead(adc_parameter); // Lecture de la valeur sum += sample; // Somme des mesures avant moyenne delayMicroseconds(50); // Pause de 50 microsecondes } return(sum / MOY_NUM); // Calcul de la mesure moyenne } //--------------------------------------------------- ////////// LECTURE DE LA TEMPERATURE //////////////// //--------------------------------------------------- void read_data() { // Pour 5V on a ADC = 1024 d'ou 1 ADC = (5/1024)Volt = 0.00488 Volt // La valeur de 0,00488 est théorique, dépend de la valeur exacte du 5 volts // et devra éventuellement être ajustée. // Vout = Vin*R2/(R1+R2) => Vin = Vout*(R1+R2)/R2 R1 = 133k and R2 = 33k // Sortie ampli ACS712-30 (66 mV/A théorique): 0A --> 2,5V et 30A--> 2,5 - 1,98 = 0,52V // Les mesures ont donné 70 mV/A soit 0,00482 * 14,3 = 0,0689 // Calcul du facteur 0,0689: // 30 * 0,070 = 2,1 et 2,5 - 2,1 = 0,4 // Pour O,4V on a adc = 512 * 0,4 / 2,5 = 82 // 30 / (512 - 82) * 0,00482 = 14,3 // 14,3 * 0,00482 = 0,0689 temperature = read_adc(TEMP_ADC)*0.00482*100; tension = read_adc(TENSION_ADC)*0.00482*(133/33); intensite = (512 - (read_adc(INTENS_ADC))) * 0.0689; { if (intensite < 0) { intensite = 0; } } } //------------------------------------------------------------- //////////////// CALCUL DE LA PUISSANCE /////////////////////// //------------------------------------------------------------- void power() { msec = millis(); elasped_msec = msec - last_msec; // Temps passé depuis le dernier appel de la fonction elasped_time = elasped_msec / 1000.0; // 1sec = 1000 msec puissance = tension * intensite; // Calcul de la puissance (W=U*I) last_msec = msec; // Entregistrement de la valeur pour la prochaine fois if (puissance < 0) // Pour éviter d'éventuelles valeurs négatives { puissance = 0; } } //-------------------------------------------------- //////////////// PWM_PIN VENTILATEUR ////////////////// //-------------------------------------------------- void ventilo_PWM() { if (temperature <= 25) { PWM = 0; digitalWrite(ALARME,LOW); vit = 0; } else if ((temperature > 25) && (temperature <= 35)) { PWM = 90; digitalWrite(ALARME,LOW); vit = 35; } else if ((temperature > 35) && (temperature <= 40)) { PWM = 130; digitalWrite(ALARME,LOW); vit = 50; } else if ((temperature > 40) && (temperature <= 45)) { PWM = 170; digitalWrite(ALARME,LOW); vit = 65; } else if ((temperature > 45) && (temperature <= 50)) { PWM = 200; digitalWrite(ALARME,LOW); vit = 80; } else if ((temperature > 50) && (temperature <= 60)) { PWM = 255; digitalWrite(ALARME,LOW); vit = 100; } else if (temperature > 60) { PWM = 255; digitalWrite(ALARME,HIGH); vit = 100; } analogWrite(PWM_PIN,PWM); } //-------------------------------------------------- ///////// AFFICHAGE DANS SERIAL MONITOR //////////// //-------------------------------------------------- void print_data() { Serial.print("Température: "); Serial.print(temperature); Serial.println(" degrés Celsius"); Serial.print("PWM: "); Serial.println(PWM); Serial.print("Tension de sortie: "); Serial.print(tension); Serial.println(" V"); Serial.print("Courant: "); Serial.print(intensite); Serial.println(" A"); Serial.print("Puissance: "); Serial.print(puissance); Serial.println(" W"); Serial.println("******************************"); } //------------------------------------------------------ ///////////////// AFFICHAGE SUR LCD //////////////////// //------------------------------------------------------ void lcd_display() { // affichage de la température lcd.setCursor(0, 0); lcd.print("Temperature:"); lcd.print(temperature); lcd.write(0b11011111); // symbole degré lcd.print("C "); // affichage de la vitesse en % lcd.setCursor(17,0); lcd.print("VT="); lcd.print(vit); lcd.print("% "); // affichage de la tension lcd.setCursor(0,1); lcd.print("U:"); lcd.print(tension, 1); lcd.print("V "); // affichage de l'intensité de sortie lcd.setCursor(8,1); lcd.print("I:"); lcd.print(intensite, 1); lcd.print("A "); // affichage de la puissance lcd.setCursor(17,1); lcd.print("P:"); lcd.print(puissance, 0); lcd.print("W "); }