Derniers sujets
routeur triphasé pour autoconsommation
4 participants
Page 1 sur 1
routeur triphasé pour autoconsommation
Je vais décrire ici ma gestion du surplus photovoltaïque (avec un appareil appelé communément routeur du mot anglais 'router') en vue de ne pas injecter gratuitement le surplus d'injection dans le réseau EDF
Il existe des routeurs DIY mais ces systèmes sont prévus pour le monophasé hors je suis en triphasé et là, c'est plus compliqué, le comptage de l'énergie se faisant avec la somme des consommations / injection sur les 3 phases liées.
C'est très bien ainsi car ce qui est injecté sur une phase peut être consommé sur les autres
Ce tableau résume la situation:
Il existe un routeur triphasé sur un site anglais, mais il faut pas mal de matériel...De plus ça risque fort de ne pas fonctionner avec notre linky qui impose de faire du découpage de phase. Edit.: Il fonctionne finalement correctement avec linky !
Je vais essayer de faire un routeur à partir d'un compteur triphasé mécanique (à disque) qui présente l'intérêt de mesurer la résultante de la consommation moins l'injection de façon correcte sur les 3 phases:
Si on consomme, le disque tourne dans un sens
Si on injecte, le disque tourne dans l'autre sens
L'idéal étant que le disque ne tourne pas (consommation = production) :sun:
La force développé par le disque en rotation est très faible et n'est pas utilisable pour actionner des contacts (j'ai essayé...). Une détection optique est donc nécessaire.
Il existe des routeurs DIY mais ces systèmes sont prévus pour le monophasé hors je suis en triphasé et là, c'est plus compliqué, le comptage de l'énergie se faisant avec la somme des consommations / injection sur les 3 phases liées.
C'est très bien ainsi car ce qui est injecté sur une phase peut être consommé sur les autres
Ce tableau résume la situation:
Il existe un routeur triphasé sur un site anglais, mais il faut pas mal de matériel...
Je vais essayer de faire un routeur à partir d'un compteur triphasé mécanique (à disque) qui présente l'intérêt de mesurer la résultante de la consommation moins l'injection de façon correcte sur les 3 phases:
Si on consomme, le disque tourne dans un sens
Si on injecte, le disque tourne dans l'autre sens
L'idéal étant que le disque ne tourne pas (consommation = production) :sun:
La force développé par le disque en rotation est très faible et n'est pas utilisable pour actionner des contacts (j'ai essayé...). Une détection optique est donc nécessaire.
Dernière édition par Silicium81 le Ven 6 Mai 2022 - 14:38, édité 6 fois
Re: routeur triphasé pour autoconsommation
La modification du compteur a disque triphasé consiste à l'équiper d'un codeur incrémental sur l'axe. Le disque que j'ai utilisé a 1008 encoches par tour soit une résolution minimale de 7,5 Wh/1008. (On peut avoir du x4 en comptant tous les fronts des signaux, je suis en X2)
Le premier test consiste à afficher une puissance instantanée positive ou négative en fonction du sens de rotation et d'ajouter un contrôle de phase pour empêcher l'injection (le disque ne devant pas tourner à l'envers...
Le contrôle de phase va alimenter un chauffe eau électrique qui absorbera exactement le surplus électrique.
Voici une petite vidéo des premiers essais où j'ai une production d'une soixantaine de Watts, je module la consommation d'une lampe manuellement et il n'y a pas encore de gestion du routage mais juste l'affichage de la puissance qui est négative quand la production dépasse la consommation.
Le timer 2 est utilisé pour le contrôle de phase (le 1 est utilisé pour la mesure de la puissance via la fréquence des impulsions).
La deuxième entrée matérielle d'it sert à détecter la rotation du disque en déclenchant une it à chaque changement de niveau logique, la première détecte les passages à 0 du secteur (pour la phase qui routera).
La boucle de régulation fonctionne
Quand le disque commence à tourner à l'envers, la puissance gérée par le triac augmente, la correction monte à 20 et met le disque à l'arrêt
J'ai directement mis une régulation du type PID et à ma grande surprise, ça à fonctionner quasiment du premier coup, il reste à affiner le bornage des valeurs et les coefficient Kp, Kp et Ki mais ça régule sans oscillation.
Le premier test consiste à afficher une puissance instantanée positive ou négative en fonction du sens de rotation et d'ajouter un contrôle de phase pour empêcher l'injection (le disque ne devant pas tourner à l'envers...
Le contrôle de phase va alimenter un chauffe eau électrique qui absorbera exactement le surplus électrique.
Voici une petite vidéo des premiers essais où j'ai une production d'une soixantaine de Watts, je module la consommation d'une lampe manuellement et il n'y a pas encore de gestion du routage mais juste l'affichage de la puissance qui est négative quand la production dépasse la consommation.
Le timer 2 est utilisé pour le contrôle de phase (le 1 est utilisé pour la mesure de la puissance via la fréquence des impulsions).
La deuxième entrée matérielle d'it sert à détecter la rotation du disque en déclenchant une it à chaque changement de niveau logique, la première détecte les passages à 0 du secteur (pour la phase qui routera).
La boucle de régulation fonctionne
Quand le disque commence à tourner à l'envers, la puissance gérée par le triac augmente, la correction monte à 20 et met le disque à l'arrêt
J'ai directement mis une régulation du type PID et à ma grande surprise, ça à fonctionner quasiment du premier coup, il reste à affiner le bornage des valeurs et les coefficient Kp, Kp et Ki mais ça régule sans oscillation.
Dernière édition par Silicium81 le Sam 12 Déc 2020 - 14:41, édité 1 fois
Re: routeur triphasé pour autoconsommation
Un ballon d'eau chaude sanitaire de 150L électrique a été installé en amont du chauffe eau gaz pour absorber le surplus et j'aurai à terme entre 3,5 kWc et 5 kWc de panneaux affectés à l'autoconsommation. Le gain en électricité et en gaz doit permettre un retour sur investissement de 5..6 ans.
Le e-compteur triphasé à disque est aussi en place en amont du tableau électrique.
La carte arduino est en place pour router vers le ballon si le disque veut tourner a l'envers.
ça route correctement, dès que le disque recule, la puissance de routage augmente rapidement pour stabiliser le disque a l'arrêt, le linky indique alors parfois une injection que je n'ai pas quantifié. En fonction de celle ci, je décalerai peut être le point d'équilibre pour ne pas arrêter le disque... je ferai un bilan ce soir.
En tout cas, je trouve très amusant d’empêcher mon linky d'incrémenter son index d'injection en utilisant un compteur mécanique (devenu un e-compteur) de 70 ans d'age
Le e-compteur triphasé à disque est aussi en place en amont du tableau électrique.
La carte arduino est en place pour router vers le ballon si le disque veut tourner a l'envers.
ça route correctement, dès que le disque recule, la puissance de routage augmente rapidement pour stabiliser le disque a l'arrêt, le linky indique alors parfois une injection que je n'ai pas quantifié. En fonction de celle ci, je décalerai peut être le point d'équilibre pour ne pas arrêter le disque... je ferai un bilan ce soir.
En tout cas, je trouve très amusant d’empêcher mon linky d'incrémenter son index d'injection en utilisant un compteur mécanique (devenu un e-compteur) de 70 ans d'age
Re: routeur triphasé pour autoconsommation
Le code arduino actuel
- Code:
// codeur avec 1008 impultions par tour
// V0b
// affichage impultions, Wh , Watts
// prise en compte de tous les fronts de A et B (2016 impulsions par tour (7,5Wh)
// La mesure dure 1s ce qui donne une résolution de 13W
// V0d
// Une seule entréz d'interruption utilisée
// résolution de 26W
// V1a codeur sur 4(int) et 3(int) pour la détection du zéro secteur.
// v1b contrôle de phase sur la sortie 5
// Avec variation de la phase de 0 à 100% pour test
// V2 Version de test pour la commande de la phase pour annuler la rotation du disque à l'envers
// La V2 fonctionne
// V2a L'asservissement est en cours d'optimisation
// include the library code:
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <TimerOne.h> // Pour le timer 1
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
#define ON 0x1
#define OFF 0x0
#define ENCODEURA 3
#define ENCODEURB 4
#define DETECT 2
#define Triac 5
#define minPhase 114
#define maxPhase 255
#define dureeImpGachette 200
//PID constants
double kp = 2000; //2000
double ki = 10; //5
double kd = 10;
volatile int lastcount =0; // comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption matériel 0 qui se fait sur le pin 2
volatile int count =0;
volatile int compte =0; // comptage précédent
volatile byte laststate =0; // etat précédent de l'encodeur
volatile byte phase=254; //pas de retard de phase à l'initialisation
long wh;
long puissanceWatt;
long consignePuissance=0;
long out;
byte puissanceTriac=0;
boolean drapPid;
unsigned long currentTime, previousTime;
long elapsedTime;
long error;
long lastError;
long input, output;
long setPoint=0;
long cumError, rateError;
int puissancePid;
void setup()
{
Serial.begin(9600);
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
lcd.setBacklight(ON);
pinMode(ENCODEURA, INPUT_PULLUP);
pinMode(ENCODEURB, INPUT_PULLUP);
pinMode(DETECT, INPUT_PULLUP); //zero cross detect
pinMode(Triac, OUTPUT);
attachInterrupt(1,counter, CHANGE); // on crée l'interruption sur changement sur la pin 3 => interruption 1, la routine counter va se faire toute seule sans l'appeler à chaque changement d'état sur le pin 2
attachInterrupt(0,zeroSec, RISING); //on crée l'interruption sur front montant sur la pin 2
Timer1.initialize(1000000); // On défini le timeur : 1000000 microseconds ( 1 sec - or 1Hz )
Timer1.attachInterrupt(timerIsr); // attach the service routine here la fonction timerIsr est une routine qui va se faire automatiquement 1* par secondes sans l'appeler
cli(); // Désactive l'interruption globale
bitClear (TCCR2A, WGM20); // WGM20 = 0
bitClear (TCCR2A, WGM21); // WGM21 = 0
TCCR2B = 0b00000111; // Clock / 1024 soit 64 us et WGM22 = 0
TIMSK2 |= (1<<0); // Interruption locale autorisée par TOIE2
sei(); // Active l'interruption globale
}
void loop()
{
puissanceWatt=compte*26;
lcd.setCursor(0, 0);
lcd.print(count); lcd.print("p"); lcd.print(" "); lcd.print((count*7.5)/1008); lcd.print(" Wh ");
lcd.setCursor(0,1);
lcd.print(puissanceWatt); lcd.print(" W ");lcd.print(puissanceTriac);lcd.print(" ");
Serial.print("error ");
Serial.print(error);
Serial.print(" ");
Serial.print("lastError ");
Serial.print(lastError);
Serial.print(" ");
Serial.print("cumError ");
Serial.print(cumError);
Serial.print(" ");
Serial.print("out ");
Serial.print(out);
Serial.print(" ");
Serial.print("elapsedTime ");
Serial.print(elapsedTime);
Serial.println(" ");
//*******PID début
input = puissanceWatt; //consigne de puissance
output = computePID(input);
delay(100);
puissanceTriac=output;
phase=(((maxPhase-minPhase)*puissanceTriac)/255)+minPhase; // 0<puissanceTriac<255 -> 114<phase<254
//*******PID fin
/*
uint8_t buttons = lcd.readButtons();
if (buttons)
{
if (buttons & BUTTON_UP) {
puissance++;
}
if (buttons & BUTTON_DOWN) {
puissance--;
}
if (buttons & BUTTON_LEFT) {
lcd.print("LEFT ");
}
if (buttons & BUTTON_RIGHT) {
lcd.print("RIGHT ");
}
if (buttons & BUTTON_SELECT)
{
count=0;
}
}
*/
}
long computePID(long inp){
currentTime = millis(); //get current time
elapsedTime = (long)(currentTime - previousTime); //compute time elapsed from previous computation
error = setPoint - inp; // determine error
cumError += error * elapsedTime; // compute integral
if (cumError>2600000) //2500000
{
cumError=2600000;
}
if (cumError<0)
{
cumError=0;
}
rateError = (error - lastError)/elapsedTime; // compute derivative
out = (kp*error) + (ki*cumError) + (kd*rateError); //PID output
lastError = error; //remember current error
previousTime = currentTime; //remember current time
puissancePid=out/100000;
if (puissancePid<0)
{
puissancePid=0;
}
if (puissancePid>255)
{
puissancePid=255;
}
return puissancePid; //have function return the PID output
}
ISR(TIMER2_OVF_vect) // dépassement du timer 2, il faut générer la commande de la gachette du triac
{
TIMSK2 = TIMSK2&0b11111110; // pas d'autre interruption (on bloque l'it de dépassement)
if (phase!=minPhase) digitalWrite(Triac, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac, 0); //si phase au max pas d'impulsions à 0
}
// Comptage des pulses du codeur
void counter() // On entre ici s'il y a une interuption sur la broche 3 (sur changement d'état logique)
{
byte state=PIND; // state = port D (PIND est le registre de lecture du port D)
state|=B11100111; // masque OU pour ne regarder que les changements sur 3 et 4
if( state!=laststate)
{
(((state&8)>>3)^((state&16)>>4))?count++:count--;
laststate=state;
}
}
void zeroSec() // passage à zéro du secteur (toute les 10ms)
{
TIMSK2 = TIMSK2|0b00000001; //autoriser l'interruption d'overflow du timer 2
TCNT2 = phase; //valeur de départ du comptage
}
// Une seconde c'est écoulée
void timerIsr()
{
compte=count-lastcount; // nombre de tick en 1s dans compte
lastcount=count; // comptage précédent
}
Re: routeur triphasé pour autoconsommation
Silicium81 a écrit:
En tout cas, je trouve très amusant d’empêcher mon linky d'incrémenter son index d'injection en utilisant un compteur mécanique (devenu un e-compteur) de 70 ans d'age
Excellent. le compteur electromécanique est plus précis que le Linky.
Snickers- Messages : 499
Date d'inscription : 25/04/2014
Localisation : Hanovre (Allemagne)
Re: routeur triphasé pour autoconsommation
Quelques courbes relevés hier et aujourd'hui en modifiant la consigne de routage (0W hier et 26W aujourd'hui) pour voir si cela améliore l'injection résiduelle.
Courbes du 23/09:
Journée complète. un peu plus de 100Wh injectés en fin de journée (mais il y a eu une dizaine de Wh du à une saturation du routage...)
Mais le principal, c'est bien l'annulation de la consommation quasiment toute la journée Il n'y a que quand on consomme plus que la production que le linky incrémente les kWh consommés. Cela se voit à la courbe marron qui est a 0, en l’absence de production solaire elle aurait oscillé autour des 500 Wh toute la journée (avec des pics pour les gros consommateurs). En bonus, les kWh produits en trop (courbe verte) servent à chauffer l'eau domestique (de l'eau chaude gratuite )
zoom1
zoom2
zoom3 détail sur la saturation du routage (la puissance produite par les PV dépasse la puissance consommée + le routage) qui provoque un peu d'injection
Courbes du 24-09:
Journée complète. 25Wh injectés. La consigne à 26W diminue bien l'injection résiduelle 8-)
zoom1
zoom2
zoom3
Pas mal pour un compteur a disque arduinisé
Le pas de mesure de la puissance est de 26W (limite due au principe de la mesure avec un disque tournant !)
Courbes du 23/09:
Journée complète. un peu plus de 100Wh injectés en fin de journée (mais il y a eu une dizaine de Wh du à une saturation du routage...)
Mais le principal, c'est bien l'annulation de la consommation quasiment toute la journée Il n'y a que quand on consomme plus que la production que le linky incrémente les kWh consommés. Cela se voit à la courbe marron qui est a 0, en l’absence de production solaire elle aurait oscillé autour des 500 Wh toute la journée (avec des pics pour les gros consommateurs). En bonus, les kWh produits en trop (courbe verte) servent à chauffer l'eau domestique (de l'eau chaude gratuite )
zoom1
zoom2
zoom3 détail sur la saturation du routage (la puissance produite par les PV dépasse la puissance consommée + le routage) qui provoque un peu d'injection
Courbes du 24-09:
Journée complète. 25Wh injectés. La consigne à 26W diminue bien l'injection résiduelle 8-)
zoom1
zoom2
zoom3
Pas mal pour un compteur a disque arduinisé
Le pas de mesure de la puissance est de 26W (limite due au principe de la mesure avec un disque tournant !)
Re: routeur triphasé pour autoconsommation
Je viens de faire évoluer le soft de l'arduino pour gérer 2 charges de délestage. En effet, la puissance du chauffe eau est un peu juste et comme je vais ajouter 1kWc... j'aurai alors de l'injection en milieu de journée.
Pour ne pas avoir à gérer 2 sorties à découpage de phase, j'ai fait la chose suivante:
Initialement la consigne variait entre 0 (pas d'injection) et 255 (injection max), j'ai étendu la consigne de 0 à 511. Entre 0 et 255, je sors les pulses vers le SSR1 puis entre 256 et 511 j'envoie les pulses vers le SSR2 (en maintenant actif le SSR1). Je route donc maintenant vers 2 consommateurs avec priorité a celui raccordé au SSR1.
Le code actuel:
Pour info, le code se simule parfaitement dans Proteus (isis) pour ceux qui connaissent
Pour ne pas avoir à gérer 2 sorties à découpage de phase, j'ai fait la chose suivante:
Initialement la consigne variait entre 0 (pas d'injection) et 255 (injection max), j'ai étendu la consigne de 0 à 511. Entre 0 et 255, je sors les pulses vers le SSR1 puis entre 256 et 511 j'envoie les pulses vers le SSR2 (en maintenant actif le SSR1). Je route donc maintenant vers 2 consommateurs avec priorité a celui raccordé au SSR1.
Le code actuel:
- Code:
// codeur avec 1008 impultions par tour
// compteur triphasé 7,5 Wh/tour
// V0b
// affichage impulsions, Wh , Watts
// prise en compte de tous les fronts de A et B (2016 impulsions par tour (7,5Wh)
// La mesure dure 1s ce qui donne une résolution de 13W
// V0d
// Une seule entrée d'interruption utilisée
// résolution de 26W (7,5/1008*3600)
// V1a codeur sur 4(int) et 3(int) pour la détection du zéro secteur.
// v1b contrôle de phase sur la sortie 5
// Avec variation de la phase de 0 à 100% pour test
// V2 Version de test pour la commande de la phase pour annuler la rotation du disque à l'envers
// La V2 fonctionne
// V2a L'asservissement est en cours d'optimisation
// V3 ajout de la sortie série pour openlog (affichage en puissanceWatt puissanceTriac temps en ms
// V3.1 afichage temps en HH:MM:SS jours
// V3.2 avec ds3231
// V3.21 ajout de CountEnergieTotale
// V3.22 ajout Wh consommés et injectés
// V3.4 deux sorties triacs. Quand la première est a saturation, on module une deuxième sortie.
// include the library code:
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <TimerOne.h> // Pour le timer 1
#include <ds3231.h> //************************************************************************************ds3231
#include <Wire.h> //************************************************************************************ds3231
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); // gestion d'un module afficheur I2C (avec boutons)
#define ON 0x1
#define OFF 0x0
#define ENCODEURA 3
#define ENCODEURB 4
#define DETECT 2
#define Triac 5
#define Triac2 6 // deuxième sortie
#define minPhase 114 //valeur minimum du timer pour un retard de phase de 0° (Pmax)
#define maxPhase 255 //valeur maximale du timer pour retard de phase de 180° (Pmin)
#define dureeImpGachette 200 // La gachette du triac est à 1 pendant 200 µs
#define maxPID 511 //255 avant modif
//PID constants
double kp = 2000; //2000
double ki = 10; //5
double kd = 10;
double time;
volatile int lastcount =0; // comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption matériel 0 qui se fait sur le pin 2
volatile int count =0;
volatile int compte =0; // comptage précédent
volatile byte laststate =0; // etat précédent de l'encodeur
volatile byte phase = 254; //pas de retard de phase à l'initialisation
long wh;
long puissanceWatt;
long MoyennePuissanceWatt;
long MoyennePuissanceWattLcd;
long consignePuissance=0;
long out;
byte puissanceTriac=0;
long MoyennePuissanceTriac;
long MoyennePuissanceTriacLcd;
long CountEnergieTotaleCons;
long CountEnergieTotaleInj;
long MilliWattHeure;
boolean drapPid;
boolean drapTrame;
volatile boolean drapTriac2;
unsigned long currentTime, previousTime;
long elapsedTime;
long error;
long lastError;
long input, output;
long setPoint=26; //*********************************<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< (0)
long cumError, rateError;
int puissancePid;
int compteSecondes=0;
struct ts t; //pour l'horloge ds3231
void setup()
{
Serial.begin(9600);
Serial.print("puissanceWatt");
Serial.print(" ");
Serial.print("consigneTriac");
Serial.print(" ");
Serial.print("EnergieConsWh");
Serial.print(" ");
Serial.print("EnergieInjWh");
Serial.print(" ");
Serial.println("MM/JJ/AAA HH:MM:SS");
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
lcd.setBacklight(ON);
Wire.begin(); //ds3231
DS3231_init(DS3231_INTCN); //ds3231
pinMode(ENCODEURA, INPUT_PULLUP);
pinMode(ENCODEURB, INPUT_PULLUP);
pinMode(DETECT, INPUT_PULLUP); //zero cross detect
pinMode(Triac, OUTPUT);
pinMode(Triac2, OUTPUT);
attachInterrupt(1,counter, CHANGE); // on crée l'interruption sur changement sur la pin 3 => interruption 1, la routine counter va se faire toute seule sans l'appeler à chaque changement d'état sur le pin 2
attachInterrupt(0,zeroSec, RISING); //on crée l'interruption sur front montant sur la pin 2
Timer1.initialize(1000000); // On défini le timeur : 1000000 microseconds ( 1 sec - or 1Hz )
Timer1.attachInterrupt(timerIsr); // attach the service routine here la fonction timerIsr est une routine qui va se faire automatiquement 1* par secondes sans l'appeler
cli(); // Désactive l'interruption globale
bitClear (TCCR2A, WGM20); // WGM20 = 0
bitClear (TCCR2A, WGM21); // WGM21 = 0
TCCR2B = 0b00000111; // Clock / 1024 soit 64 us et WGM22 = 0 Le timer 2 génère le retard de phase avec une résolution de 64µs
TIMSK2 |= (1<<0); // Interruption locale autorisée par TOIE2
sei(); // Active l'interruption globale
}
void loop()
{
puissanceWatt=compte*26;
lcd.setCursor(0, 0);
// lcd.print("out ");lcd.print(output);lcd.print(" dT2 ");lcd.print(drapTriac2);lcd.print(" ");
lcd.print("C");lcd.print(CountEnergieTotaleCons/1000);lcd.print("Wh ");lcd.print("I");lcd.print(CountEnergieTotaleInj/1000);lcd.print("Wh ");
lcd.setCursor(0,1);
lcd.print(puissanceWatt); lcd.print("W ");lcd.print("T:");lcd.print(puissanceTriac);lcd.print(" T:");lcd.print(drapTriac2+1);lcd.print(" ");
if (drapTrame) // l'intervalle c'est écoulé -> emission d'une trame série
{
drapTrame=0;
Serial.print(MoyennePuissanceWattLcd);
Serial.print(" ");
Serial.print(MoyennePuissanceTriacLcd);
Serial.print(" ");
Serial.print(CountEnergieTotaleCons/1000);
Serial.print(" ");
Serial.print(CountEnergieTotaleInj/1000);
Serial.print(" ");
DS3231_get(&t);
Serial.print(t.mday);
Serial.print("/");
Serial.print(t.mon);
Serial.print("/");
Serial.print(t.year+100);
Serial.print(" ");
Serial.print(t.hour);
Serial.print(":");
Serial.print(t.min);
Serial.print(":");
Serial.println(t.sec);
MoyennePuissanceWatt=0;
MoyennePuissanceTriac=0;
}
//*******PID début
input = puissanceWatt; //consigne de puissance
output = computePID(input);
delay(100);
if (output>256)
{
puissanceTriac=output-256;
drapTriac2=1; // On sort sur triac2
}
else
{
puissanceTriac=output;
drapTriac2=0; //on sort sur triac1
}
phase=(((maxPhase-minPhase)*puissanceTriac)/255)+minPhase; // 0<puissanceTriac<255 -> 114<phase<254
//*******PID fin
}
long computePID(long inp){
currentTime = millis(); //get current time
elapsedTime = (long)(currentTime - previousTime); //compute time elapsed from previous computation
error = setPoint - inp; // determine error
cumError += error * elapsedTime; // compute integral
if (cumError>5200000) //22600000
{
cumError=5200000;
}
if (cumError<0)
{
cumError=0;
}
rateError = (error - lastError)/elapsedTime; // compute derivative
out = (kp*error) + (ki*cumError) + (kd*rateError); //PID output
lastError = error; //remember current error
previousTime = currentTime; //remember current time
puissancePid=out/100000;
if (puissancePid<0)
{
puissancePid=0;
}
if (puissancePid>maxPID)// plafonnement valeur max PID (255->511)
{
puissancePid=maxPID; //*********************************************************************
}
return puissancePid; //have function return the PID output
}
ISR(TIMER2_OVF_vect) // dépassement du timer 2, il faut générer la commande de la gachette du triac
{
TIMSK2 = TIMSK2&0b11111110; // pas d'autre interruption (on bloque l'it de dépassement)
if (drapTriac2)
{
digitalWrite(Triac, 1);
if (phase!=minPhase) digitalWrite(Triac2, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac2, 0); //si phase au max pas d'impulsions à 0
}
else
{
digitalWrite(Triac2, 0);
if (phase!=minPhase) digitalWrite(Triac, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac, 0); //si phase au max pas d'impulsions à 0
}
}
// Comptage des pulses du codeur
void counter() // On entre ici s'il y a une interuption sur la broche 3 (sur changement d'état logique)
{
byte state=PIND; // state = port D (PIND est le registre de lecture du port D)
state|=B11100111; // masque OU pour ne regarder que les changements sur 3 et 4
if( state!=laststate)
{
(((state&8)>>3)^((state&16)>>4))?count++:count--;
laststate=state;
}
}
void zeroSec() // passage à zéro du secteur (toute les 10ms)
{
TIMSK2 = TIMSK2|0b00000001; //autoriser l'interruption d'overflow du timer 2
TCNT2 = phase; //valeur de départ du comptage
}
// Une seconde c'est écoulée
void timerIsr()
{
compte=count-lastcount; // nombre de tick en 1s dans compte
MilliWattHeure=compte*7.4; //(compte*7500)/1008;
if (compte>0)
{
CountEnergieTotaleCons+=MilliWattHeure;
}
else
{
CountEnergieTotaleInj+=MilliWattHeure;
}
lastcount=count; // comptage précédent
compteSecondes++;
MoyennePuissanceWatt+=puissanceWatt;
MoyennePuissanceTriac+=puissanceTriac;
if (compteSecondes==10)
{
MoyennePuissanceWattLcd=MoyennePuissanceWatt/10;
MoyennePuissanceTriacLcd=MoyennePuissanceTriac/10;
drapTrame=1; //drapeau trame a 1 pour indiquer qu'il faut emettre une trame série
compteSecondes=0;
}
}
Pour info, le code se simule parfaitement dans Proteus (isis) pour ceux qui connaissent
Re: routeur triphasé pour autoconsommation
Tout mes panneaux pour l'autoconso sont en place avec 13 micros onduleurs M250 associés chacun avec 350Wc de panneaux. Les MO arrivent facilement à saturation et j'ai donc souvent 13x255W=3,3 kW à consommer
Le prix de revient total (structures alu complète, panneaux, micros onduleurs, surveillance, routage avec achat d'un chauffe eau électrique 150L et un réchauffeur de boucle) est de 2970€ pour 4500 Wc. Le retour sur investissement sera de l'ordre de 6..7 ans (électricité et gaz économisés)
La stratégie de routage 'saison froide' est maintenant câblée, j'ai:
-Un chauffe eau électrique (1800W) en amont du chauffe eau instantanée gaz. Le chauffe eau gaz est neutralisé si l'eau dans le cumulus est à plus de 40 °C.
-Un réchauffeur de boucle électrique placée dans le circuit eau chaude du chauffage gaz (3x1700W)
Avec le SSR 1: Résistance du chauffe eau (1800W), si la température max est atteinte (60°C), la résistance est remplacée par une du réchauffeur de boucle (1700W).
Si SSR1 est a 100%, sortie vers SSR2 qui chauffe la deuxième résistance du réchauffeur de boucle (+1700W)
Cela permet de router au minimum 3400W et donc d'absorber la totalité de la production si besoin.
Le prix de revient total (structures alu complète, panneaux, micros onduleurs, surveillance, routage avec achat d'un chauffe eau électrique 150L et un réchauffeur de boucle) est de 2970€ pour 4500 Wc. Le retour sur investissement sera de l'ordre de 6..7 ans (électricité et gaz économisés)
La stratégie de routage 'saison froide' est maintenant câblée, j'ai:
-Un chauffe eau électrique (1800W) en amont du chauffe eau instantanée gaz. Le chauffe eau gaz est neutralisé si l'eau dans le cumulus est à plus de 40 °C.
-Un réchauffeur de boucle électrique placée dans le circuit eau chaude du chauffage gaz (3x1700W)
Avec le SSR 1: Résistance du chauffe eau (1800W), si la température max est atteinte (60°C), la résistance est remplacée par une du réchauffeur de boucle (1700W).
Si SSR1 est a 100%, sortie vers SSR2 qui chauffe la deuxième résistance du réchauffeur de boucle (+1700W)
Cela permet de router au minimum 3400W et donc d'absorber la totalité de la production si besoin.
Re: routeur triphasé pour autoconsommation
Mise en place du mode 'été'
Pour l'été, le réchauffeur de boucle n'est plus guère utilisable (sauf pour le sèche serviette de la salle de bain), je vais pouvoir chauffer la piscine avec un chauffage électrique du type zodiac trouvé sur lbc à 50€
Stratégie d'été:
Le programme a été modifié:
Il y a maintenant 4 sorties pour 4 SSR:
SSR1: chauffe eau / R1 réchauffeur de boucle
SSR2: R2 réchauffeur de boucle
SSR3: R1 chauffage piscine
SSR4: R2 chauffage piscine
En hiver, c'est comme avant
En été:
SSR1: chauffe eau
SSR2: nc
SSR3: R1 chauffage piscine
SSR4: R2 chauffage piscine
Priorité à SSR1 + SSR4
Si SSR4 sature c'est que le chauffe eau est plein (la résistance est déconnecté), on bascule sur SSR3 pendant 1 heure, le retour a SSR1 est ainsi automatique.
Dernière version:
Pour l'été, le réchauffeur de boucle n'est plus guère utilisable (sauf pour le sèche serviette de la salle de bain), je vais pouvoir chauffer la piscine avec un chauffage électrique du type zodiac trouvé sur lbc à 50€
Stratégie d'été:
Le programme a été modifié:
Il y a maintenant 4 sorties pour 4 SSR:
SSR1: chauffe eau / R1 réchauffeur de boucle
SSR2: R2 réchauffeur de boucle
SSR3: R1 chauffage piscine
SSR4: R2 chauffage piscine
En hiver, c'est comme avant
En été:
SSR1: chauffe eau
SSR2: nc
SSR3: R1 chauffage piscine
SSR4: R2 chauffage piscine
Priorité à SSR1 + SSR4
Si SSR4 sature c'est que le chauffe eau est plein (la résistance est déconnecté), on bascule sur SSR3 pendant 1 heure, le retour a SSR1 est ainsi automatique.
Dernière version:
- Code:
// codeur avec 1008 impultions par tour
// compteur triphasé 7,5 Wh/tour
// V0b
// affichage impulsions, Wh , Watts
// prise en compte de tous les fronts de A et B (2016 impulsions par tour (7,5Wh)
// La mesure dure 1s ce qui donne une résolution de 13W
// V0d
// Une seule entrée d'interruption utilisée
// résolution de 26W (7,5/1008*3600)
// V1a codeur sur 4(int) et 3(int) pour la détection du zéro secteur.
// v1b contrôle de phase sur la sortie 5
// Avec variation de la phase de 0 à 100% pour test
// V2 Version de test pour la commande de la phase pour annuler la rotation du disque à l'envers
// La V2 fonctionne
// V2a L'asservissement est en cours d'optimisation
// V3 ajout de la sortie série pour openlog (affichage en puissanceWatt puissanceTriac temps en ms
// V3.1 afichage temps en HH:MM:SS jours
// V3.2 avec ds3231
// V3.21 ajout de CountEnergieTotale
// V3.22 ajout Wh consommés et injectés
// V3.4 deux sorties triacs. Quand la première est a saturation, on module une deuxième sortie.
// V3.41 correction format sortie datalogger (pour SSR1 et SSR2)+ correction année (la correction de 100 ans n'est plus utile à partir du 3/3/2020 !)
// V3.5 ajout du mode été avec voie 1 soit vers SSR1 soit vers SSR3 et voie 2 vers SSR4
// la voie 1 est normalement vers SSR1, si la consigne globale sature (=511) c'est que le CES est plein,
// on bascule alors la voie 1 vers SSR3 pendant 1h (pour repasser automatiquement vers SSR1)
// include the library code:
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <TimerOne.h> // Pour le timer 1
#include <ds3231.h> //************************************************************************************ds3231
#include <Wire.h> //************************************************************************************ds3231
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); // gestion d'un module afficheur I2C (avec boutons)
#define ON 0x1
#define OFF 0x0
#define ENCODEURA 3
#define ENCODEURB 4
#define DETECT 2
#define Ete 9 // 0=été 1=hiver
#define Triac 5
#define Triac2 6 // deuxième sortie
#define Triac3 7 // troisième sortie (SSR3 été)
#define Triac4 8 // quatrieme sortie (SSR4 été)
#define minPhase 114 //valeur minimum du timer pour un retard de phase de 0° (Pmax)
#define maxPhase 255 //valeur maximale du timer pour retard de phase de 180° (Pmin)
#define dureeImpGachette 200 // La gachette du triac est à 1 pendant 200 µs
#define maxPID 511 //255 avant modif
//PID constants
double kp = 2000; //2000
double ki = 10; //5
double kd = 10;
double time;
volatile int lastcount =0; // comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption matériel 0 qui se fait sur le pin 2
volatile int count =0;
volatile int compte =0; // comptage précédent
volatile byte laststate =0; // etat précédent de l'encodeur
volatile byte phase = 254; //pas de retard de phase à l'initialisation
long wh;
long puissanceWatt;
long MoyennePuissanceWatt;
long MoyennePuissanceWattLcd;
long consignePuissance=0;
long out;
byte puissanceTriac=0;
//long MoyennePuissanceTriac;
//long MoyennePuissanceTriacLcd;
long CountEnergieTotaleCons;
long CountEnergieTotaleInj;
long MilliWattHeure;
boolean drapPid;
boolean drapTrame;
boolean drapCES;
boolean mode; // valeur de l'inter été / hiver (mode=0 pour l'été et mode=1 pour l'hiver)
volatile boolean drapTriac2;
unsigned long currentTime, previousTime;
long elapsedTime;
long error;
long lastError;
long input, output;
long setPoint=26; //*********************************<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< (0)
long cumError, rateError;
int puissancePid;
int compteSecondes=0;
int timerTriac3; // comptage de 60' pour délestage CES vers Triac3 l'été
int S1;
int S2;
int consigne1;
int consigne2;
long moyenneConsigne1;
long moyenneConsigne2;
struct ts t; //pour l'horloge ds3231
void setup()
{
Serial.begin(9600);
Serial.print("puissanceWatt");
Serial.print(" ");
Serial.print("sortie 1 utilisée");
Serial.print(" ");
Serial.print("consigne 1");
Serial.print(" ");
Serial.print("sortie 2 utilisée");
Serial.print(" ");
Serial.print("consigne 2");
Serial.print(" ");
Serial.print("EnergieConsWh");
Serial.print(" ");
Serial.print("EnergieInjWh");
Serial.print(" ");
Serial.println("MM/JJ/AAA HH:MM:SS");
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
lcd.setBacklight(ON);
lcd.setCursor(0, 0);
lcd.print("Version: 3.5");
delay(200);
Wire.begin(); //ds3231
DS3231_init(DS3231_INTCN); //ds3231
pinMode(ENCODEURA, INPUT_PULLUP);
pinMode(ENCODEURB, INPUT_PULLUP);
pinMode(DETECT, INPUT_PULLUP); //zero cross detect
pinMode(Triac, OUTPUT);
pinMode(Triac2, OUTPUT);
pinMode(Triac3, OUTPUT);
pinMode(Triac4, OUTPUT);
pinMode(Ete, INPUT_PULLUP);
attachInterrupt(1,counter, CHANGE); // on crée l'interruption sur changement sur la pin 3 => interruption 1, la routine counter va se faire toute seule sans l'appeler à chaque changement d'état sur le pin 2
attachInterrupt(0,zeroSec, RISING); //on crée l'interruption sur front montant sur la pin 2
Timer1.initialize(1000000); // On défini le timeur : 1000000 microseconds ( 1 sec - or 1Hz )
Timer1.attachInterrupt(timerIsr); // attach the service routine here la fonction timerIsr est une routine qui va se faire automatiquement 1* par secondes sans l'appeler
cli(); // Désactive l'interruption globale
bitClear (TCCR2A, WGM20); // WGM20 = 0
bitClear (TCCR2A, WGM21); // WGM21 = 0
TCCR2B = 0b00000111; // Clock / 1024 soit 64 us et WGM22 = 0 Le timer 2 génère le retard de phase avec une résolution de 64µs
TIMSK2 |= (1<<0); // Interruption locale autorisée par TOIE2
sei(); // Active l'interruption globale
}
void loop()
{
puissanceWatt=compte*26;
lcd.setCursor(0, 0);
lcd.print("C");lcd.print(CountEnergieTotaleCons/1000);lcd.print("Wh ");lcd.print("I");lcd.print(CountEnergieTotaleInj/1000);lcd.print("Wh ");
lcd.setCursor(0,1);
lcd.print(puissanceWatt); lcd.print("W ");lcd.print(S1);lcd.print(":");lcd.print(consigne1);lcd.print(" ");lcd.print(S2);lcd.print(":");lcd.print(consigne2);lcd.print(" ");
mode=digitalRead(Ete);
if (drapTrame) // l'intervalle c'est écoulé -> emission d'une trame série
{
drapTrame=0;
MoyennePuissanceWattLcd=MoyennePuissanceWatt/10;
moyenneConsigne1=moyenneConsigne1/10;
moyenneConsigne2=moyenneConsigne2/10;
timerTriac3--;
if (timerTriac3==0) // test si une heure écoulée
{
drapCES=0; // oui, on repasse la voie 1 vers Triac1
}
Serial.print(MoyennePuissanceWattLcd);
Serial.print(" ");
Serial.print(S1);
Serial.print(" ");
Serial.print(moyenneConsigne1);
Serial.print(" ");
Serial.print(S2);
Serial.print(" ");
Serial.print(moyenneConsigne2);
Serial.print(" ");
Serial.print(CountEnergieTotaleCons/1000);
Serial.print(" ");
Serial.print(CountEnergieTotaleInj/1000);
Serial.print(" ");
DS3231_get(&t);
Serial.print(t.mday);
Serial.print("/");
Serial.print(t.mon);
Serial.print("/");
Serial.print(t.year);
Serial.print(" ");
Serial.print(t.hour);
Serial.print(":");
Serial.print(t.min);
Serial.print(":");
Serial.println(t.sec);
MoyennePuissanceWatt=0;
moyenneConsigne1=0;
moyenneConsigne2=0;
}
// lcd.print(puissanceWatt); lcd.print("W ");lcd.print(S1);lcd.print(":");lcd.print(consigne1);lcd.print(" ");lcd.print(S2);lcd.print(":");lcd.print(consigne2);lcd.print(" ");
//*******PID début
input = puissanceWatt; //consigne de puissance
output = computePID(input);
delay(100);
if (output>256)
{
puissanceTriac=output-256;
drapTriac2=1; // On sort sur triac2
consigne1=255;
consigne2=puissanceTriac;
}
else
{
puissanceTriac=output;
drapTriac2=0; //on sort sur triac1
consigne1=puissanceTriac;
consigne2=0;
}
phase=(((maxPhase-minPhase)*puissanceTriac)/255)+minPhase; // 0<puissanceTriac<255 -> 114<phase<254
//*******PID fin
}
long computePID(long inp){
currentTime = millis(); //get current time
elapsedTime = (long)(currentTime - previousTime); //compute time elapsed from previous computation
error = setPoint - inp; // determine error
cumError += error * elapsedTime; // compute integral
if (cumError>5200000) //22600000
{
cumError=5200000;
}
if (cumError<0)
{
cumError=0;
}
rateError = (error - lastError)/elapsedTime; // compute derivative
out = (kp*error) + (ki*cumError) + (kd*rateError); //PID output
lastError = error; //remember current error
previousTime = currentTime; //remember current time
puissancePid=out/100000;
if (puissancePid<0)
{
puissancePid=0;
}
if (puissancePid>maxPID)// plafonnement valeur max PID (255->511)
{
consigne1=255;
puissancePid=maxPID; //*********************************************************************
drapCES=1; // saturation de l'erreur, le CES est plein, on va sortir sur Triac3 pendant une heure (en été)
timerTriac3=360; // départ comptage 360 x 10s = 1h (on va utiliser la tempo de 10s du datalogger pour décrémenter timerTriac3
}
return puissancePid; //have function return the PID output
}
ISR(TIMER2_OVF_vect) // dépassement du timer 2, il faut générer la commande de la gachette du triac
{
TIMSK2 = TIMSK2&0b11111110; // pas d'autre interruption (on bloque l'it de dépassement)
if (mode) // test si on est configuré en été (0) ou en hiver (1)
{ // hiver
if (drapTriac2) // test si on doit utiliser la voie 2 ?
{ // oui
digitalWrite(Triac, 1); // la voie 1 à 100%
S1=1;
S2=2;
if (phase!=minPhase) digitalWrite(Triac2, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac2, 0); //si phase au max pas d'impulsions à 0
}
else
{ //non
digitalWrite(Triac2, 0); // la voie 2 à 0%
if (phase!=minPhase) digitalWrite(Triac, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac, 0); //si phase au max pas d'impulsions à 0
}
}
else
{ // été
if (drapTriac2) // test si on doit utiliser la voie 4 ?
{ // oui
if (drapCES) // le CES est plein ?
{ // oui, on sort vers triac3
digitalWrite(Triac3, 1); // la voie 3 à 100%
S1=3;
}
else
{ // non, on sort vers triac1
digitalWrite(Triac, 1); // la voie 1 à 100%
S1=1;
}
S2=4;
if (phase!=minPhase) digitalWrite(Triac4, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac4, 0); //si phase au max pas d'impulsions à 0
}
else
{ //non, pas de dépassement, seulement la voie 1
digitalWrite(Triac3, 0); // la voie 4 à 0%
digitalWrite(Triac, 0); // la voie 1 à 0%
if (drapCES) // le CES est plein ?
{ // oui, on utilise triac3
S1=3;
if (phase!=minPhase) digitalWrite(Triac3, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac3, 0); //si phase au max pas d'impulsions à 0
}
else
{ // non, on utilise triac1
S1=1;
if (phase!=minPhase) digitalWrite(Triac, 1); //si phase au min pas d'impultions à 1
delayMicroseconds(dureeImpGachette); // largeur de l'impultion de commande de 200 us
if (phase!=maxPhase-1) digitalWrite(Triac, 0); //si phase au max pas d'impulsions à 0
}
}
}
}
// Comptage des pulses du codeur
void counter() // On entre ici s'il y a une interuption sur la broche 3 (sur changement d'état logique)
{
byte state=PIND; // state = port D (PIND est le registre de lecture du port D)
state|=B11100111; // masque OU pour ne regarder que les changements sur 3 et 4
if( state!=laststate)
{
(((state&8)>>3)^((state&16)>>4))?count++:count--;
laststate=state;
}
}
void zeroSec() // passage à zéro du secteur (toute les 10ms)
{
TIMSK2 = TIMSK2|0b00000001; //autoriser l'interruption d'overflow du timer 2
TCNT2 = phase; //valeur de départ du comptage
}
// Une seconde c'est écoulée
void timerIsr()
{
compte=count-lastcount; // nombre de tick en 1s dans compte
MilliWattHeure=compte*7.4; //(compte*7500)/1008;
if (compte>0)
{
CountEnergieTotaleCons+=MilliWattHeure;
}
else
{
CountEnergieTotaleInj+=MilliWattHeure;
}
lastcount=count; // comptage précédent
compteSecondes++;
MoyennePuissanceWatt+=puissanceWatt;
moyenneConsigne1+=consigne1;
moyenneConsigne2+=consigne2;
if (compteSecondes==10)
{
drapTrame=1; //drapeau trame a 1 pour indiquer qu'il faut emettre une trame série
compteSecondes=0;
}
}
Dernière édition par Silicium81 le Sam 12 Déc 2020 - 14:47, édité 2 fois
Re: routeur triphasé pour autoconsommation
Schéma simplifié de la partie commande des SSR distants de 10m pour SSR1 et 2 et plus de 80m pour SSR3 et 4:
Re: routeur triphasé pour autoconsommation
Silicium81 a écrit:
Il existe un routeur triphasé sur un site anglais, mais il faut pas mal de matériel... De plus ça risque fort de ne pas fonctionner avec notre linky qui impose de faire du découpage de phase.
Bonjour,
Je me permets de corriger ce point. Le routeur triphasé de Robin Emley, pour ne pas le nommer, fonctionne parfaitement avec tous les compteurs triphasés francais, que cela soit les blancs électroniques (par exemple Landy&Gear) ou que cela soit les Linky triphasés.
Perso, j'ai un Linky tri, et j'ai construit des routeurs tri pour d'autres utilisateurs équipés de Linky tri... tout baigne !!
Voilà le résultat:
Fred
FredM67- Messages : 2
Date d'inscription : 06/05/2022
Re: routeur triphasé pour autoconsommation
Oui, cela à été confirmé depuis que j'ai fait mon routeur. C'est une bonne solution pour ceux qui sont en triphasé. Je vais éditer mon texte. Ce n'était pas évident car ce routeur fonctionnant par train d'ondes avec pour conséquence que sur une période secteur, le routage n'est pas correct et le linky était réputé faire ses mesures sur une seule période.
Comme cela fonctionne finalement, cela signifie que linky mesure l'énergie consommée sur plusieurs périodes.
Comme cela fonctionne finalement, cela signifie que linky mesure l'énergie consommée sur plusieurs périodes.
Re: routeur triphasé pour autoconsommation
Il apparaît surtout que le Linky tri est moins chiant que le mono.
Moyennant une légère modif dans le prog que Robin a fait il y a quelques mois, son routeur mono fonctionne aussi parfaitement avec le Linky mono.
Moyennant une légère modif dans le prog que Robin a fait il y a quelques mois, son routeur mono fonctionne aussi parfaitement avec le Linky mono.
FredM67- Messages : 2
Date d'inscription : 06/05/2022
Re: routeur triphasé pour autoconsommation
Bonjour à vous tous, je ne sais où mettre mon message.
Je vais mettre en place d'ici peu une installation PV de 3Kwc en TRI et en autoconsommation. je suis donc à la recherche d'un routeur tri (Arduino), la construction ne doit pas me poser de problème à condition d'avoir les schémas d'implantations des composants, la liste des composants et le programme pour le fonctionnement du routeur. Merci de réorienter ce message.
Je vais mettre en place d'ici peu une installation PV de 3Kwc en TRI et en autoconsommation. je suis donc à la recherche d'un routeur tri (Arduino), la construction ne doit pas me poser de problème à condition d'avoir les schémas d'implantations des composants, la liste des composants et le programme pour le fonctionnement du routeur. Merci de réorienter ce message.
jose82- Messages : 1
Date d'inscription : 12/09/2022
Re: routeur triphasé pour autoconsommation
Le routeur de Robin Emley en version triphasé devrait faire ton bonheur:
https://mk2pvrouter.co.uk/
FredM67 a modifié (amélioré) le code et partage cela sur sur Github:
https://github.com/FredM67/PVRouter-3-phase
https://mk2pvrouter.co.uk/
FredM67 a modifié (amélioré) le code et partage cela sur sur Github:
https://github.com/FredM67/PVRouter-3-phase
Sujets similaires
» Stratégie de production PV triphasé
» Raccord installation PV sur compteur triphasé
» Balise de signalement électronique DIY
» Du 5V pour votre VAE
» Interrupteur pour cnc
» Raccord installation PV sur compteur triphasé
» Balise de signalement électronique DIY
» Du 5V pour votre VAE
» Interrupteur pour cnc
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
Lun 18 Nov 2024 - 13:34 par Silicium81
» conversion greencitybike monte-carlo 24V lipo ---> 36V lipo
Sam 9 Nov 2024 - 18:55 par soltes
» Remise en état d'un analyseur de spectre R3361A Advantest
Mar 29 Oct 2024 - 13:58 par Silicium81
» LCD couleur 6.5" sur R3361A
Mar 22 Oct 2024 - 18:43 par Silicium81
» Un BMS Home made
Lun 14 Oct 2024 - 16:31 par Silicium81
» Dell G3 3779 qui ne démarre plus [résolu]
Dim 29 Sep 2024 - 14:37 par Snickers
» Chargeur batterie universel DC/DC 150W
Mar 24 Sep 2024 - 18:20 par Silicium81
» Protection BMS contre les surtensions sur circuit de charge.
Ven 16 Aoû 2024 - 14:35 par legraybat
» HP Probook 470 G1 qui ne démarre plus - écran noir - bios corrompu [résolu]
Mar 13 Aoû 2024 - 16:20 par Silicium81