Forum Électro-Bidouilleur

Merci de vous connecter ou de vous inscrire.

Connexion avec identifiant, mot de passe et durée de la session
Recherche avancée  

Nouvelles:

Le Forum est maintenant chiffré (préambule https). Bien sûr, des liens externes insérés dans les sujets vont demeurer inchangés. Mais la composition des pages du Forum est désormais sécurisée. Si des problèmes d'affichage surviennent, veillez à vider votre cache pour ce site.

Auteur Sujet: Énergie Solaire chez soi ( Centre de contrôl V1nano & V2esp32 )  (Lu 2180 fois)

Manu

  • Newbie
  • *
  • Messages: 36
    • Voir le profil

Bonjour à  tous !
Je voudrais partager avec vous ce "Centre de contrôle des panneaux solaires" fait avec un arduino et recyclage d'un vieil ampli RF de CB.

Solar Control Center v1.0 (Arduino NANO)


Sur la photo:
-2 VUmètre, l'un indiquait les watts d'entrée et l'autre la sortie (non ajusté à  l'échelle, de 0 à  400w linéaires tous les deux).
-2 leds rouges qui indiquent si un fusible a sauté ou si la batterie est débranchée.
-Un écran oled qui indique le pourcentage approximatif de la batterie (basé sur Vmin et Vmax), les volts du premier panneau solaire, les volts du deuxième panneau solaire (celui-ci a son propre câble pour ne pas être affecté par la chute de tension générale de la ligne), Watts de charge et watts de sortie. Un message apparaîtra également si un fusible tombe en panne ou si la batterie a une tension en dehors des plages normales.
-Trois interrupteurs Un qui éteint tout le système arduino, un pour éteindre le VUmètre et un autre pour éteindre l'écran oled (pour réactiver l'écran oled après avoir coupé sa tension, il faut éteindre et rallumer l'arduino).


Deux petits régulateurs BEC stepDown, un premier pour passer de 30v à  7 et l'autre pour ajuster le 5v final.


J'ai dû ajouter une résistance parallèle de 220k pour que le VU soit au maximum correctement.

---et 3kg d'étain plus tard...


Vue d'en-haut. On peut voir deux grandes plaques de cuivre une pour le négatif à  gauche et une pour le positif à  droite. Le fusible noir 40A avec les pattes dorées. Le 20A Disj pour alimenter les lumières de la maison (le système Dali basé sur du 24v , onduleur 230va n'est pas nécessaire). Les deux capteurs de courant en bleu, un pour l'entrée et un pour la sortie. Les deux régulateurs de tension bleu et vert. L'arduino avec ses résistances qui font office de pont diviseur de tension.



Le code:
Après des test en situation réelle, il faut prendre en compte que le pourcentage de batterie affiché sauter par étapes de 66, 77 et 88%.... et je n'ai pas encore pu corriger cela.Peut-être à  cause de l'adc basse résolution, du diviseur de tension mal choisi, ou le code.
J'essaierai de mettre à  jour tout ça plus tard.

/*
 * Solar Central Control V1.0
 * by Manu
 *
 * OLED 128x64 pin 5V GND  SCK A5 & SDA A4
 * CURRENT SENSOR HCS LSP 25A & 50A Pin 4V GND A0 & A1 ( supply voltage affects the analog output value, must be stable )
 * Voltage Meter Analog Read A2, A3, A7, A6
 * LED fuse failure D3 & D5
 * VU meter Watt D6 & D9
*/


//OLED-----------------------------------
#include <U8g2lib.h>                     // Pin I2C A4 A5
#define OledContrast 160                 // Contraste display
#define Font1 u8g2_font_haxrcorp4089_tr  // text size small
#define Font2 u8g2_font_logisoso16_tf    //           19x23
#define Font3 u8g2_font_logisoso42_tf    //           50x62
#define Font4 u8g2_font_logisoso30_tf    //           36x45
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//PIN------------------------------------
#define PinCS1 A0                        // Current Sensor Analog input A0 Output 25A
#define PinCS2 A1                        // Current Sensor Analog input A1 InPut 50A
#define PinV40A A2                       // Volt Sensor Analog A2 40Amp Fuse
#define PinV20A A3                       // Volt Sensor Analog A3 20Amp Fuse
#define PinVpvA A7                       // Volt Sensor Analog A7 PVa ( Photovoltaic Panel )
#define PinVpvB A6                       // Volt Sensor Analog A6 PVb ( Photovoltaic Panel )
//LED------------------------------------
#define PinLED1 3                        // led indicating a fuse failure output 20Amp D3
#define PinLED2 5                        // led indicating a fuse failure input 40Amp o failure input D5
#define LEDBrgs 1                        // led brightness
//VU meter ( Watt )----------------------
#define PinWout 6                        // Watt meter VU output D6
#define PinWin 9                         // Watt meter VU input D9
//Delay----------------------------------
#define msLoop 1000                      // Loop Delay ms
#define msLowBat 1000                    // Flashing speed of the led that indicates the alarm
#define msHighBat 500                    // Flashing speed of the led that indicates the alarm
//Current--------------------------------
#define CS1Zero 514                      // Current Sensor value for 0Amp
#define CS1PerUnit 17.49                 // Current Sensor value step 1Amp 50A sensor
#define CS2Zero 511                      // Current Sensor value for 0Amp
#define CS2PerUnit 8.74                  // Current Sensor value step 1Amp 25A sensor
//Voltage--------------------------------
#define V40ACst 33.6                     // Input voltage From 40A Fuse  220k + 10k  & 47k-GND  30vmax to 5vmax      & is the checkpoint that goes to the analog input pin   
#define V20ACst 33.4                     // Input voltage From 20A Fuse  220k + 10k  & 47k-GND
#define VpvACst 19.7                     // Input voltage From PVa       100k + 100k & 22k-GND  50vmax to 5vmax
#define VpvBCst 20.1                     // Input voltage From PVb       100k + 100k & 22k-GND
#define VbatMax 29.2                     // Voltage battery maximum 29.2v
#define VbatMaxAlert 29.5                // Alarm voltage battery is high  trigger the alarm above    = 29.2vmax + 0.3v margin of error of the analog input
#define VbatMin 20                       // Alarm voltage battery is low   trigger the alarm below
#define Vfuse   7                        // Alarm voltage fuse fail                trigger the alarm below
#define WminMeter 0                      // Watts value measured to display the Minimum on the meter 0W
#define WmaxMeter 400                    // Watts value measured to display the Maximum on the meter 400W
#define WVUMin 0                         // Analog value of the output to mark the Minimum watts on the meter pwm0 = aproxi 0v
#define WVUMax 255                       // Analog value of the output to mark the Maximum watts on the meter pwm255 = aproxi 5v o 3.3v
#define BatPrMin 0                       // Maximum value of % of the battery showing on the oled display
#define BatPrMax 100                     // Minimum value of % of the battery showing on the oled display
#define ZeroDflt 0.01                    // Saved value for reading values of 0 or less, avoid negative values or error multicast by 0
#define Diod40A 0.504                    // Voltage drop of the diode in the voltage divider bridge of the analog inputs.
#define Diod20A 0.488                   
#define DiodpvA 0.505                   
#define DiodpvB 0.509
//Test----------------------------------
#define StepTst 7                        // Steps to get count to 255 and back to 0   255/7 = 36 steps
#define StepLed 5                        // Steps to get led light value max and min  Led Max Value= StepLed*StepTst
#define SetOled 2.55                     // Sets the maximum number that the screen will show and will roll back to 0   255max value / 2.55 = 100   Display show 0->100 100->0


float CS1Raw=0;                          // Analog Value Current Sensor 25A
float CS2Raw=0;                          // "            Current Sensor 50A
float V40ARaw=0;                         // "            Resistive voltage divider 
float V20ARaw=0;                         // "            Resistive voltage divider 
float VpvARaw=0;                         // "            Resistive voltage divider 
float VpvBRaw=0;                         // "            Resistive voltage divider 
float CS1=0;                             // Save value conversion to current output
float CS2=0;                             // Save value conversion to current input
float V40A=0;                            // Save value conversion to voltage 40A Fuse input charge battery
float V20A=0;                            // Save value conversion to voltage 20A Fuse output discharge battery
float VpvA=0;                            // Save value Voltage probe from the A twin photovoltaic panels
float VpvB=0;                            // Save value Voltage probe from the B twin photovoltaic panels
float WattOut=0;                         // Save the output watt calculation
float WattIn=0;                          // Save the input watt calculation
float WattVUout=0;                       // Save input value to move the wattmeter needle
float WattVUin=0;                        // Save output value to move the wattmeter needle
float BatPor=0;                          // Save % battery

//Test
short i=0;                               // inicial value for i testmode inicial

void InitSetup(){
  u8g2.begin();                          // Start oled
  u8g2.setContrast(OledContrast);
  pinMode(PinWin, OUTPUT);
  pinMode(PinWout, OUTPUT);
  pinMode(PinLED1, OUTPUT);
  pinMode(PinLED2, OUTPUT);
  pinMode(PinV40A,INPUT);
  pinMode(PinV20A,INPUT);
  pinMode(PinVpvA,INPUT);
  pinMode(PinVpvB,INPUT);
  pinMode(PinCS1,INPUT);
  pinMode(PinCS2,INPUT);
}

void InitTest(){
    analogWrite(PinWout, i);
    analogWrite(PinWin, i);
    analogWrite(PinLED1, (i/StepLed));
    analogWrite(PinLED2, (i/StepLed));       
    u8g2.clearBuffer();
    u8g2.setFont(Font3);
    u8g2.setCursor(40,62);             
    u8g2.print((i/SetOled),0);              // divid 2.55   0->255 to 0->100
    u8g2.sendBuffer();   
}

void setup() {
  InitSetup();
  for(i=0;i<WVUMax;i=(i+StepTst)){
    InitTest();
  }
  for(i=WVUMax;i>0;i=(i-StepTst)){
    InitTest();
  }
  analogWrite(PinWout, 0);
  analogWrite(PinWin, 0);
  analogWrite(PinLED1, 0);
  analogWrite(PinLED2, 0); 
}

void loop() {
//RAW Value---------------------------------------
CS1Raw=(analogRead(PinCS1)-CS1Zero);     // Current Sensor Analog input A0 Output 25A
CS2Raw=(analogRead(PinCS2)-CS2Zero);     // Current Sensor Analog input A1 InPut 50A
V40ARaw=analogRead(PinV40A);             // Volt Sensor Analog A2 40Amp Fuse
V20ARaw=analogRead(PinV20A);             // Volt Sensor Analog A3 20Amp Fuse
VpvARaw=analogRead(PinVpvA);             // Volt Sensor Analog A7 PVa ( Photovoltaic Panel )
VpvBRaw=analogRead(PinVpvB);             // Volt Sensor Analog A6 PVb ( Photovoltaic Panel )
//RAW to CONVERSION-------------------------------
CS1=CS1Raw/CS1PerUnit;
if(CS1<0){                               // for negative value save 0
  CS1=ZeroDflt;
}             
CS2=CS2Raw/CS2PerUnit;
if(CS2<0){                                       
  CS2=ZeroDflt;

V40A=(V40ARaw/V40ACst)-Diod40A;            // -0.504v diod voltage drop
if(V40A<0){
  V40A=ZeroDflt;
}
V20A=(V20ARaw/V20ACst)-Diod20A;                     
if(V20A<0){
  V20A=ZeroDflt;
}
VpvA=(VpvARaw/VpvACst)-DiodpvA;
if(VpvA<0){
  VpvA=ZeroDflt;
}
VpvB=(VpvBRaw/VpvBCst)-DiodpvB;
if(VpvB<0){
  VpvB=ZeroDflt;
}
WattOut=V20A*CS1;
if(WattOut<10){
  WattOut=ZeroDflt;
}
WattIn=V40A*CS2;
if(WattIn<10){
  WattIn=ZeroDflt;
}
BatPor = map(V40A,VbatMin,VbatMax,BatPrMin,BatPrMax);  // erreur possible, en attente de vérification !
if(BatPor<0){
  BatPor=ZeroDflt;
}
//CHECK VOLTAGE AND FUSES------------------------
  if(V40A < Vfuse){                          // fuse 40A input alarm     
    analogWrite(PinLED2,LEDBrgs); 
    u8g2.clearBuffer();
      u8g2.setFont(Font2);
      u8g2.setCursor(0,23);
      u8g2.print("   BATERIA");
      u8g2.setCursor(0,43);
      u8g2.print("DESCONECTADA");
      u8g2.setCursor(0,64);
      u8g2.print("  O FUSIBLE");
    u8g2.sendBuffer();
    goto NEXT;
  }
  else if(V40A < VbatMin){                    // low battery alarm   20V minimum
    analogWrite(PinLED1,LEDBrgs);   
    delay(msLowBat);
    analogWrite(PinLED1, 0);
    analogWrite(PinLED2, 0);
    delay(msLowBat);
    u8g2.clearBuffer();
      u8g2.setFont(Font2);
      u8g2.setCursor(0,45);
      u8g2.print("BATERIA BAJA");
    u8g2.sendBuffer();   
    goto NEXT;
  }
  else if(V40A > VbatMaxAlert){                  // high over battery alarm 
    analogWrite(PinLED1,LEDBrgs);   
    delay(msHighBat);
    analogWrite(PinLED1, LEDBrgs);
    analogWrite(PinLED2, LEDBrgs);
    delay(msHighBat);
    u8g2.clearBuffer();
      u8g2.setFont(Font2);
      u8g2.setCursor(0,45);
      u8g2.print("VOLTAGE ALTO");
    u8g2.sendBuffer();   
    goto NEXT;
  }
  else if(V20A < Vfuse){                     // fuse 20A output alarm   
    analogWrite(PinLED1,LEDBrgs);
    u8g2.clearBuffer();
      u8g2.setFont(Font2);
      u8g2.setCursor(0,23);
      u8g2.print("  SALTO LA");
      u8g2.setCursor(4,43);
      u8g2.print(" PROTECCION");
      u8g2.setCursor(0,64);
      u8g2.print("   REARMAR");
    u8g2.sendBuffer();   
    goto NEXT;
  }

  else{
    analogWrite(PinLED1, 0);
    analogWrite(PinLED2, 0);
  }
//SHOW DATA---------------------------------------
u8g2.clearBuffer();
  u8g2.setFont(Font2);
  u8g2.setCursor(19,21);
  u8g2.print(VpvA,0);
  u8g2.print("v   ");
  u8g2.print(VpvB,0);
  u8g2.print("v ");
  u8g2.setCursor(69,43);
  u8g2.print("<"); 
  if(WattIn<100){
    u8g2.print(" ");
  }
  if(WattIn<10){
    u8g2.print("  ");
  }
  u8g2.print(WattIn,0);
  u8g2.print("W");
  u8g2.setCursor(69,64);
  u8g2.print(">");
  if(WattOut<100){
    u8g2.print(" ");
   }
  if(WattOut<10){
     u8g2.print("  ");
  }
  u8g2.print(WattOut,0);
  u8g2.print("W");
  u8g2.setCursor(0,64);
  if(BatPor<100){
     u8g2.setFont(Font2);
     u8g2.print(" ");
  }
  if(BatPor<10){
     u8g2.setFont(Font2);
     u8g2.print("  ");
  }
  u8g2.setFont(Font4);
  u8g2.print(BatPor,0);
  u8g2.print("%");
 u8g2.sendBuffer();
 
NEXT:

//VU METER----------------------------------------
WattVUout=map(WattOut,WminMeter,WmaxMeter,WVUMin,WVUMax);      //from 0 to 400 watts the needle moves from 0 to maximum
WattVUin=map(WattIn,WminMeter,WmaxMeter,WVUMin,WVUMax);
analogWrite(PinWout, WattVUout);
analogWrite(PinWin, WattVUin);

delay(msLoop);
}
Le code est très mal optimisé certes, mais fonctionnel. Toute bonne idée pour minimiser la consommation de ressources de l'arduino est la bienvenue.
J´ai Essayé de changer le "float" en "int" "uint16" et autres. Mais je n'ai pas pu obtenir les décimales nécessaires pour avoir un calcul exact des watts entre autres
N'oubliez pas de configurer le message d'alerte à  votre convenance, car ils sont en espagnol  :o



Dans l'ordre sur les photos:
-En haut le détecteur d'incendie blanc
-2 gros fils noirs du "Solaire Control center" pour alimenter l'éclairage domestique.
-Juste en dessous venant du contrôleur mppt entre et qui charge la batterie.
-Connecteur 7 broches provenant de l'extérieur pour mesurer la tension des panneaux.
-Câble rouge & noir positif de la batterie le même pour charger que pour décharger
-En vert connecté au châssis du boitier, la batterie et mppt tous au même point de masse. (pas le negatif de la batterie)
-Le mppt blue. Celui-ci présente deux entrées + - des panneaux solaires et sorties + - pour charger la batterie.
(Dans le manuel, il est clairement indiqué qu'il est obligatoire de connecter d'abord la batterie et ensuite seulement les panneaux)


Comme je l'ai déjà  dit, les aiguilles ne sont qu'indicatives et ne sont pas sur l'échelle marquée du VU. Réglez à  environ 400 W pour les valeur maxi.

Enfin, je tiens à  dire qu'il y a trop d'énergie pour alimenter uniquement les lumières de la maison et je vais ajouter bientôt des bricolles pour en profiter.
A plus  ;D
« Modifié: octobre 05, 2022, 07:42:47 am par Manu »
IP archivée

francoisp31

  • Jr. Member
  • **
  • Messages: 90
    • Voir le profil
Re : Solaire Control Center
« Réponse #1 le: mai 22, 2022, 01:14:43 pm »

pas mal du tout ce projet :)
IP archivée

Manu

  • Newbie
  • *
  • Messages: 36
    • Voir le profil
Re : Re : Solaire Control Center
« Réponse #2 le: mai 22, 2022, 01:51:48 pm »

IP archivée

Manu

  • Newbie
  • *
  • Messages: 36
    • Voir le profil
Énergie Solaire chez soi ( Centre de contrôl v2.0 )
« Réponse #3 le: octobre 05, 2022, 07:17:33 am »

Bonjour,
Récemment, j'ai ajouté un onduleur 24v 3000 Victron Energy à  l'installation, profitant de cette amélioration, J'ai mis à  jour le "contrôle solaire" avec maintenant un ESP32. Avec des alarmes en cas de fusible défectueux, basse tension, ampérage trop élevé,... entre autres.

Solar Control Center v2.0 (ESP32)






Version 3420x2600
https://i.ibb.co/1TCQyB0/IMG-20220916-165822-01-01.jpg

Board:

Attention à  ne pas trop étamer les pistes et à  les chauffer, la pcb pourrait se plier avec la chaleur.

alimentation externe au cas où: (régler même tension que le BEC de la board):


vue de face tout assemblé:


Gardez à  l'esprit que les ADC ne doivent pas avoir de tension présente lors de la mise sous tension de l'ESP32. Allumez d'abord l'ESP32, puis appliquez une tension aux entrées ADC. Pour faciliter cela, j'ai dû ajouter des connecteurs.
En théorie, ajouter une diode 1N5711 entre l'entrée de chaque ADC et GND pourrait résoudre le problème, mais je ne l'ai pas essayé.

Le code:

/*
 * Solar Control Center v2.0 (ESP32) by Manu 2022-09-23 16:31
 *
 * ESP32 Devkit V1 WROOM32 30PINS   Pins Reference https://lastminuteengineers.com/esp32-pinout-reference/
 *
 * Oled 128x64 pin 5V GND      21, 22                       SDA, SCL
 * Current Sensor Analog Read  34, 35, 32                   HCS LSP 50A, 25A, 20A
 * Voltage Meter  Analog Read  27, 14, 12, 33, 25, 26       Check Fuse, PV, Bat  (amélioration a faire a+ 1N5711)
 * Voltage Ref ADC             13, 15                       GND, 3.3v on board (not use)
 * LED Alarm                   2, 4, 5
 * VU meter Watt               23, 19
 * Battery LiFePO4  PylonTech UP2500 Nominal 25.6v / 2840Wh nominal / 2550Wh usable / 23v discharge / charge 28.8 / 56A contin. / 100A peak 15sec /
 *
 * This helps to ADC Read  Inspired by https://www.youtube.com/Électro-Bidouilleur -> EB_#501 https://www.youtube.com/watch?v=5SlQFSFdu68
 * This helps to structure Inspires by https://www.youtube.com/c/PhilippeDemerliac_Cyrob
*/

//OLED-----------------------------------
#include <SPI.h>
#include <U8g2lib.h>                      // Display Libr.
#define DspLight 200                      // Display Contrast 0min - 255max
#define DspFont2 u8g2_font_logisoso16_tf  // Fonts size 19x23  list:https://github.com/olikraus/u8g2/wiki/fntgrplogisoso
#define DspLine1 23                       // Cursor position first line                   & Fuse Msg Alarm
#define DspLine2 43                       //                 second line Charge   ">>>>>" & Volt Msg Alarm
#define DspLine3 64                       //                 third line  BatLevel ".   ." & Amp  Msg Alarm
//Serial---------------------------------
#define SerialSet 9600                    // Serial baude           
//Led------------------------------------
#define LedON 50                          // Led brightness
//Delay----------------------------------
#define msLoop 500                        // Delay ms Loop
#define msLedAlarm1 650                   //          Led blink
#define msLedAlarm2 300                   //          Led blink
#define msADC 50                          //          between each reading of the adc
//PIN------------------------------------
  //input
#define PinC1 32                          // Current Sensor 20A INP    MPPT -> BAT
#define PinC2 35                          //                25A OUT            BAT  -> LIGHTING HOME
#define PinC3 34                          //                50A OUT            BAT  -> INVERTER
#define PinF1 14                          // Volt Sensor    60A Fuse   GENERAL         BAT -> 60AFuse
#define PinF2 27                          //                50A Fuse   INVRT                  60AFuse -> 50AFuse Inverter
#define PinF3 26                          //                20A Fuse   LIGHTING HOME                  -> 20AFuse Lighting Home
#define PinPVa 25                         //                PVa (Photovoltaic Panel A)
#define PinPVb 33                         //                PVb (Photovoltaic Panel B)
#define PinBat 12                         // Volt Battery
#define PinAdc0 13                        //                GND  input     "to calibrate ADC not used in this version" 
#define PinAdc4095 15                     //                3.3V input     "to calibrate ADC not used in this version" 
#define InputNbr 11                       // Number of input pins
  //output
#define PinLed1 2                         // led indicating ALARM Fuse MPPT   
#define PinLed2 4                         //                           Inverter
#define PinLed3 5                         //                           Battery
#define PinVUout 19                       // Vu battery output meter amp
#define PinVUinp 23                       //                   meter voltage
#define OutputNbr 5                       // Number of output pins
//Battery--------------------------------
#define BatVMax 29.2                      // Voltage Max limit possible damage
#define BatVFull 28.8                     //         Full
  //#define BatvNominal 25.6              //         Nominal (not use)
#define BatVEmpty 23                      //         Empty
#define BatVMin 21                        //         Min limit possible damage
#define BatAMaxOut 40                     // Current Max Continuous output From BAT to INVRT LIGHT ... UP2500 pylontech 56A
  //#define BatAMaxIn 10                  //         Max            input  From MPPT to BAT charge (not use)
//VUMeter--------------------------------
#define VUMin 0                           // PWM value Watts min VU  PWM 0   = aproxi 0v
#define VUMax 255                         //                 max         255          5v o 3.3v
//Range Drop Voltage Fuse----------------
#define F1VDrop 2                         // Limit of voltage drop in the fuse to activate the alarm Battery
#define F2VDrop 2                         //                                                         Inverter
#define F3VDrop 2                         //                                                         Lighting Home
//ADC------------------------------------
  //10Kohm - 1Kohm 35v max 
#define C1Zero 2867                       // RAW value when 0A pass through the              20ASensor MPPT
#define C2Zero 2901                       // 0A Dali Lighting Home                           25ASensor Lighting Home
#define C3Zero 2872                       // 0VA Inverter VIctron Energy Phoenix 24v 3000 &  50ASensor Inverter
#define C1R  176                          // RAW value when 1A pass through the 20ASensor
#define C2R  132                          //                                    25ASensor
#define C3R  90                           // 3.54 = 1VA aproxi                  50ASensor
#define F1FromMin 2664                    // RAW value of the adc with the min ToMin voltage of interest
#define F1FromMax 2993                    //                               max ToMax
#define F2FromMin 2662                    // RAW value of the adc with the min ToMin voltage of interest
#define F2FromMax 2993                    //                               max ToMax
#define F3FromMin 2682                    // RAW value of the adc with the min ToMin voltage of interest
#define F3FromMax 3021                    //                               max ToMax
#define BatFromMin 2660                   // RAW value of the adc with the min ToMin voltage of interest               
#define BatFromMax 2994                   //                               max ToMax
#define ToMin 2560                        // mV =25.60v Nominal voltage    reference of the min interest value   
#define ToMax 2848                        // mV =28.48V Floatation voltage                  max
  //22kohm - 1.5kohm 50v max               
#define PVaFromMin 337                    // RAW value of the adc with the min PVToMin voltage of interest
#define PVaFromMax 3256                   //                               max PVToMax
#define PVbFromMin 273                    //                               min
#define PVbFromMax 3220                   //                               min
#define PVToMin 600                       // 6v  reference of the min interest value
#define PVToMax 4500                      // 45v                  max 
  //Others
#define ADCResol 12                       // ADC Resolution 12 bits
#define Decimal 100                       // map() cannot handle decimal, from mV to V
#define ADCsampl 256                      // Number of samples to be accumulated to more accurately measure the mean value
#define Zero 0                            // Zero
//Display--------------------------------
  //Msg
#define MsgStart "SOLAR CENTER"
#define MsgF1Fault "FUSIB BATTERY"
#define MsgF2Fault "FUSI INVERTER"
#define MsgF3Fault "FUSI LiGHTING"
#define MsgVBatHIGH " V ALTA!"
#define MsgVBatLOW " V  BAJA!"
#define MsgVBatlow " V   baja"
#define MsgVBathigh " V  alta"
#define MsgABatHIGH "A ALTO !"
  //Decimal Show Display
#define DecimalAbat 0                     // Amp  0 = from 10.23A to 10A
#define DecimalVbat 1                     // Volt 1        25.61v    25.6v

//INPUT----------
float C1=0;
float C2=0;
float C3=0;
float F1=0;
float F2=0;
float F3=0;
float VpvA=0;
float VpvB=0;
float Vbat=0;
float Ain=0;
float AOut=0;
byte PinInput[InputNbr]={PinC1, PinC2, PinC3, PinF1, PinF2, PinF3, PinPVa, PinPVb, PinBat, PinAdc0, PinAdc4095};
//OUTPUT---------
uint8_t VUout=0;
uint8_t VUinp=0;
uint8_t Led1=0;
uint8_t Led2=0;
uint8_t Led3=0;
byte PinOutput[OutputNbr]={PinLed1, PinLed2, PinLed3, PinVUout, PinVUinp};
uint8_t x=0;
float Value=0;

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

void SerialBaude(){
  Serial.begin(SerialSet);
  Serial.print("Serial Baude: ");
  Serial.println(SerialSet);
}

void u8g2Init(){
  u8g2.begin();                       
  u8g2.setContrast(DspLight);
  DisplayStart();
  DisplayLine2();
  u8g2.print(MsgStart);
  DisplayEnd();
  Serial.println("Display Begin: U8g2 Oled");
  delay(1000);
}

void ConfigPins(){
  for(x=Zero;x<InputNbr;x++){       // input
    pinMode(PinInput[x], INPUT);
    Serial.print(PinInput[x]);
    Serial.println(" INPUT MODE");                                                               
  }
 x=Zero;
  for(x=Zero;x<OutputNbr;x++){       // output
    pinMode(PinOutput[x], OUTPUT);
    analogWrite(PinOutput[x], Zero);
    Serial.print(PinOutput[x]);
    Serial.println(" OUTPUT MODE");     
  }
 x=Zero;
}

void ADCCalibration(){
  analogReadResolution(ADCResol);                                 // Fixer la résolution ADC à  12 bits
}

float readADC(unsigned char inputPin){
  float adcVal = Zero;
  for (unsigned int i = Zero; i < ADCsampl; i++){  // Pour augmenter la résolution de n bits, 4n fois le nombre d'échantillons doivent être accumulés.
    adcVal += analogRead(inputPin);                // Additon des valeurs lues pour compiler la moyenne
  }
  return adcVal / ADCsampl;                        // Renvoi de la division finale par le nombre d'échantillons, produisant la lecture moyenne.
}

void ReadValue(){
//Current Sensor
  Value = (readADC(PinC1) - C1Zero) / C1R;
  C1 =Value;
  Serial.print("AmpMPPT:");  // 20A
  Serial.print(C1,1);
  Serial.print("A ");
  delay(msADC);
  Value = (readADC(PinC2) - C2Zero) / C2R;
  C2 =Value;
  Serial.print("  AmpLIGHT:"); // 25A
  Serial.print(C2,1);
  Serial.print("A ");
  delay(msADC);
  Value = (readADC(PinC3) - C3Zero) / C3R;
  C3 =Value;
  Serial.print("  AmpINVRT:");  // 50A
  Serial.print(C3,1);
  Serial.print("A ");
  delay(msADC);
  Ain=C1;                          // Amp input   MPPT --> BAT
  AOut=(C2+C3);                    // Amp output           BAT --> LIGHT + INVRT

//FUSE
  Value = map(readADC(PinF1), F1FromMin, F1FromMax, ToMin, ToMax);
  F1 = Value/Decimal;
  Serial.print("  F1:");
  Serial.print(F1,2);
  Serial.print("V  ");
  delay(msADC);
  Value = map(readADC(PinF2), F2FromMin, F2FromMax, ToMin, ToMax);
  F2 = Value/Decimal;
  Serial.print("  F2:");
  Serial.print(F2,2);
  Serial.print("V  ");
  delay(msADC);
  Value = map(readADC(PinF3), F3FromMin, F3FromMax, ToMin, ToMax);
  F3 = Value/Decimal;
  Serial.print("  F3:");
  Serial.print(F3,2);
  Serial.print("V  ");
  delay(msADC);

//Photovolt A & B
  Value = map(readADC(PinPVa), PVaFromMin, PVaFromMax, PVToMin, PVToMax);
  VpvA = Value/Decimal;
  Serial.print("  PVa:");
  Serial.print(VpvA,2);
  Serial.print("V");
  delay(msADC);
  Value = map(readADC(PinPVb), PVbFromMin, PVbFromMax, PVToMin, PVToMax);
  VpvB = Value/Decimal;
  Serial.print("  PVb:");
  Serial.print(VpvB,2);
  Serial.print("V");
  delay(msADC);
 
//VBAT
  Value = map(readADC(PinBat), BatFromMin, BatFromMax, ToMin, ToMax);
  Vbat = Value/Decimal;
  Serial.print("  Vbat:");
  Serial.print(Vbat,2);
  Serial.println("V");
}

void CheckFuse(){
DisplayLine1();
  if(F1<Vbat-F1VDrop){
    Serial.println("FuseBat     FAULT");
    u8g2.print(MsgF1Fault);
    Led1on();
    Led2off();
    Led3off();
    delay(msLedAlarm1);
  }else if(F2<Vbat-F2VDrop){
    Serial.println("FuseInvrt   FAULT");
    u8g2.print(MsgF2Fault);
    Led1off();
    Led2on();
    Led3off();
    delay(msLedAlarm1);
  }else if(F3<Vbat-F3VDrop){
    Serial.println("FuseLight   FAULT");
    u8g2.print(MsgF3Fault);
    Led1off();
    Led2off();
    Led3on();
    delay(msLedAlarm1);
  }else{
    Serial.println("FUSE OK");
  }
Led1off();
Led2off();
Led3off();
}

void CheckVBat(){
DisplayLine2();
Serial.print("BATTERY:   ");
Serial.print(Vbat,1);
Serial.print("V  ");
Serial.print(AOut,0);
Serial.print("Aoutput ");
Serial.print(Ain,0);
Serial.println("Ainput ");
  if((Vbat<BatVFull) && (Vbat>BatVEmpty)){
    Led1off();
    Led2off();
    Led3off();
    delay(msLedAlarm2);
    if(Ain>Zero){                           // Amp discharge Level from ">    "
      if(Ain<0.5){                          //                          ">>   "
        u8g2.print(">");                    //                          ">>>  "
      }else if(Ain<1){                       
        u8g2.print(">>");
      }else if(Ain<2){
        u8g2.print(">>>");
      }else if(Ain<3){
        u8g2.print(">>>>");
      }else if(Ain<4){
        u8g2.print(">>>>>");
      }else if(Ain<5){
        u8g2.print(">>>>>>");
      }else if(Ain<6){
        u8g2.print(">>>>>>>");
      }else if(Ain<7){
        u8g2.print(">>>>>>>>");
      }else if(Ain<8){
        u8g2.print(">>>>>>>>>");
      }else{
        u8g2.print(">>>>>>>>>>>");
      }
    }
  }else if(Vbat>=BatVMax){
   Serial.println("HIGH");
   u8g2.print(Vbat,DecimalVbat);
   u8g2.print(MsgVBatHIGH);
    Led1on();
    Led2on();
    Led3on();
    delay(msLedAlarm2);
  }
  else if (Vbat<=BatVMin){
    Serial.println("LOW");
    if(Vbat<10){
      u8g2.print(" ");
    }
    u8g2.print(Vbat,DecimalVbat);
    u8g2.print(MsgVBatLOW);
    Led1on();
    Led2on();
    Led3on();
    delay(msLedAlarm2);
  }
  else if(Vbat<BatVEmpty){
   Serial.println("low");
    if(Vbat<10){
      u8g2.print(" ");
    }
    u8g2.print(Vbat,DecimalVbat);
    u8g2.print(MsgVBatlow);
    Led1on();
    Led2on();
    Led3off();
    delay(msLedAlarm2);
  }
  else{  // Vbat>Full
    Serial.println("high");
    u8g2.print(Vbat,DecimalVbat);
    u8g2.print(MsgVBathigh);
    Led1on();
    Led2on();
    Led3off();
    delay(msLedAlarm2);
  }
}

void CheckABat(){
DisplayLine3();
  if(AOut>BatAMaxOut){
    Serial.print("Ouput HIGH: ");
    Serial.print(AOut,DecimalAbat);
    Serial.println("A");
    u8g2.print("  ");
    u8g2.print(AOut,DecimalAbat);
    u8g2.print(MsgABatHIGH);
    Led1on();
    Led2on();
    Led3on();
    delay(msLedAlarm2);
  }else{
    Led1off();
    Led2off();
    Led3off();
    if(x>Zero){
      u8g2.print(".");                          // Battey Level blink from ".     "  to  "        ."
      x=Zero;                                   //                                   to  "      .  "
    }                                           //                                   to  "    .    "
    else{
      if(Vbat>27.76){
        u8g2.print("            .");           
        x=1;
      }else if(Vbat>27.04){
        u8g2.print("         .");
        x=1;
      }else if(Vbat>26.32){
        u8g2.print("      .");
        x=1;
      }else if(Vbat>25.60){
        u8g2.print("    .");
        x=1;
      }else{
        u8g2.print("  .");
        x=1;
      }
    }
  }
}

void DisplayStart(){
  u8g2.clearBuffer();
  u8g2.setFont(DspFont2);
}

void DisplayLine1(){
  u8g2.setCursor(Zero,DspLine1);
}

void DisplayLine2(){
  u8g2.setCursor(Zero,DspLine2);
}

void DisplayLine3(){
  u8g2.setCursor(Zero,DspLine3);
}

void DisplayEnd(){
  u8g2.sendBuffer();
}

void Led1on(){
  analogWrite(PinLed1,LedON);
  Serial.println("Led1: ON ");
}

void Led2on(){
  analogWrite(PinLed2,LedON);
   Serial.println("Led2: ON ");
}

void Led3on(){
  analogWrite(PinLed3,LedON);
  Serial.println("Led3: ON ");
}

void Led1off(){
  analogWrite(PinLed1, Zero);
}

void Led2off(){
  analogWrite(PinLed2, Zero);
}

void Led3off(){
  analogWrite(PinLed3, Zero);
}

void VUshow(){
  VUout=map(AOut,Zero,BatAMaxOut,VUMin,VUMax);      // VUout = Amp  BAT output --> Lighting & Inverter ( not mppt charge input consider )
  VUinp=map(Vbat,BatVEmpty,BatVFull,VUMin,VUMax);      // VUinp = Volt BAT
  analogWrite(PinVUout, VUout);
  analogWrite(PinVUinp, VUinp);
  Serial.print("PWM   [Amp:");
  Serial.print(VUout); 
  Serial.print("]    [Volt:");
  Serial.print(VUinp);
  Serial.println("]");
}

void setup(){
  SerialBaude();
  u8g2Init();
  ConfigPins();
  ADCCalibration();
}

void loop(){
  ReadValue();    // Sensor Value
  DisplayStart();
   CheckVBat();   // Volt
   CheckABat();   // Amp
   CheckFuse();   // Fuse
  DisplayEnd();
  VUshow();
delay(msLoop);
}
« Modifié: octobre 05, 2022, 07:43:40 am par Manu »
IP archivée

papyblue

  • Administrator
  • Hero Member
  • *****
  • Messages: 747
    • Voir le profil
Re : Énergie Solaire chez soi ( Centre de contrôl V1nano & V2esp32 )
« Réponse #4 le: octobre 05, 2022, 11:03:14 am »

Bonjour,
Un beau projet bien documenté qui peut donner des idées...
On voit la difficulté pour intégrer dans un boitier les petits écrans chinois Oled et autres LCD. Il sont très pratiques pour de l'expérimentation sur table  mais dès qu'on veut les mettre sur une face avant ce n'est pas simple.

Merci pour ce partage.

PB
IP archivée

Manu

  • Newbie
  • *
  • Messages: 36
    • Voir le profil
Re : Énergie Solaire chez soi ( Centre de contrôl V1nano & V2esp32 )
« Réponse #5 le: octobre 06, 2022, 03:52:57 pm »


Les commentaires sont toujours bien appréciés, Merci papyblue.

écrans chinois Oled:
D'autant plus que j'ai dû cacher l'énorme bouton d'origine de l'ampli.


( image made in http://arifidenza.it/Forum/topic.asp?ARCHIVE=true&TOPIC_ID=312055  )
IP archivée