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
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