Le compteur Linky n’affiche pas la puissance active, ni la puissance réinjectée tant que la demande spécifique n’est pas faite à ENEDIS.
Le compteur Linky affiche donc la puissance apparente positive qui est saturé à 0.
Le compteur Linky n’a pas de wi fi donc non communicant pour gérer de l’autoconsommation avec du photovoltaïque, ni la recharge d’une batterie domestique, ni la recharge d’un véhicule.
Par conséquent, le compteur linky ne permet pas de communiquer pour faire un délestage. Les applications cloud des energy meter vendu dans le commerce n’ont pas de période d’échantillonnage correcte pour faire varier le chargement d’un véhicule via l’autoconsommation photovoltaïque lors de couverture nuageuse variable, ni de faire la commande de délestage.
Donc, on propose de faire EMS (Energy Management System) pour mesurer la puissance monophasée de 8KVA (30A, 230V) avec un wifi d’où l’utilisation d’un ESP32 avec monitoring.
Il y a déjà pleins de choses sur internet avec des méthodes de programmations et des capteurs différents mais sans donner la précision des mesures. Certains utilisent des Library de capteur qui doivent être calibré, d’autres des circuits spécialisés tel que ATM90E26, PZEM-004T,….)
Notre choix a été d’utiliser des capteurs basiques pour tester plusieurs méthodes tout en isolant la tension secteur du micro tel que zmpt101b sensor voltage (0.5V d’amplitude de sortie) pour 311V et le sensor current SCT-013-050 qui passe de 50A d’amplitude à 1V. les 2 permettent d’être lu directement par l’ESP32.
Mais pour que le micro puisse mesurer le facteur de puissance positif et négatif, il faut une période d’échantillonnage convenable et avoir l’ondulation globale donc avec une tension d’offset de 1.65V
Le rapport de transformation zmpt101b 2mA de la tension secondaire dépend du rapport des résistances d’entrée et de sortie
Avec le schéma électrique suivant la tension théorique sur la résistance R1 sera égale à la tension suivante avec une tension secteur de 240V
U2=240V*100/820k=0.029V
Puis, il y a 2 filtres inverseurs avec LM358 en cascades avec un gain de 10 chacun en théorie.
Mais, pour une amplitude secteur 340V (240V RMS), l’amplitude est de 0.55V avec un offset de 2.25V étant alimenté en 4.85V donc avec l’ESP 32 la précision de la mesure sera de 2V.
Pour une alimentation en 3.3V, l’amplitude de sortie est de 0.25V avec 1.65V d’offset.
Une fréquence d’échantillonnage de 0.2ms va être utilisé pour avoir 100 échantillons de la période secteur 20ms ce qui permettra d’avoir une mesure de précision du déphasage de 3.6° entre la tension et le courant. Mais, la méthode de la mesure du facteur de puissance par la puissance moyenne divisé par la puissance apparente mais il faudra calibrer le déphasage du capteur
Mais dans un premier temps, le sensor voltage va être testé sans routine d’interruption sur 1000 échantillon donc 10 périodes
Les méthodes de mesures sont bien expliquées sur ce lien
Voici le programme pour lire la tension secteur
// ZMPT101B sensor voltage
// Mesure de tension AC RMS
const int pinZMPT = 12; //240V 50Hz
const int nombreEchantillons = 1000; //10 periodes
float facteurCalibration = 1.00;
float somme = 0;
float sommeCarres = 0;
int valeurADC;
float tensionADC;
float offset=3103;
float signal1;
float rmsADC;
float tensionRMS;
float valeurMax; //
float valeurMin;
float amplitude;
void setup() {
Serial.begin(115200);
analogReadResolution(12); // ADC 12 bits : 0 à 4095
analogSetAttenuation(ADC_11db); // Plage ADC environ 0 à 3,3 V
}
void loop() {
valeurMax = 0;
valeurMin = 4095;
sommeCarres = 0;
// calcul des sommes verif offset 2.5V=>3103
for (int i = 0; i < nombreEchantillons; i++) {
valeurADC = analogRead(pinZMPT);
somme += valeurADC; //
if (valeurADC > valeurMax) valeurMax = valeurADC;
// if (valeurADC < valeurMin) valeurMin = valeurADC;
signal1 = valeurADC - offset; // Suppression de l'offset pour RMS
sommeCarres += signal1 * signal1; // Carré du signal
delayMicroseconds(200); //pour 20ms secteur mesure sur 100echantillon par periode
}
// calcul de l'offset
offset = somme / nombreEchantillons;
somme=0;
// determination amplitude
amplitude=((valeurMax-offset)*3.3*facteurCalibration)/4095;
// Calcul RMS du signal alternatif
rmsADC = sqrt(sommeCarres / nombreEchantillons);
tensionADC = (rmsADC / 4095.0) * 3.3;
tensionRMS = tensionADC * facteurCalibration;
// Affichage monitor serie
Serial.print("Offset=");
Serial.print(offset, 1);
Serial.print(" | RMS=");
Serial.print(tensionRMS, 3);
Serial.print(" | ampl="); //peu precis
Serial.println(amplitude, 3);
}
Dans la copie d’écran, le facteur de calibration est de 1 donc il faudra le passer à 582 en réel.
On remarquera que la mesure de l’amplitude n’est pas précise. De plus, le capteur déforme un peu le signal sinusoïdal, donc le rapport de racine de 2 entre l’amplitude de la valeur efficace ne fonctionne pas.
La suite des explications pour le teste du capteur de courant avec son offset avec la méthode de mesure de puissance et facteur de puissance ce sera pour bientôt.
Si l’on désire vérifier le déphasage entre la tension et le courant secteur avec une période d’échantillonnage rapide, le serial plotter ne peut pas être utilisé car l’envoie d’un float met 200us avec 115200 bauds.
De plus, le serial.print bloque la routine d’interruption.
Evidemment, un oscilloscope peut faire le job, mais utiliser le micro permet de vérifier l’acquisition.
Donc la solution est d’enregistrer les données dans une table tous les 4 secondes ici et envoie les données en bloquant les acquisitions.
Le programme utilise une routine d’interruption pour acquérir les 50 échantillons de la tension secteur avec si la période d’échantillonnage est de 400us, une période est visualisable.
Si l’on choisit une routine d’interruption de 800us alors 2 périodes seront visualisables
Voici le programme
//TTGO dispaly ZMPT101B sensor voltage
// Mesure de tension et intensity AC RMS
#include <TFT_eSPI.h>
#include <SPI.h>
hw_timer_t * timer = NULL;
TFT_eSPI tft = TFT_eSPI(); //library 1,4" color 135, 240
const int nbrEchantillons = 2500; // periodes
const float facteurCalibrationV = 582.00;
const float facteurCalibrationI = 1.00;
int sampler=0;
bool flag;
bool flagenvoie;
float sommeV = 0;
float sommeI=0;
float sommeCarres = 0;
float sommeCarresI = 0;
int valeurADC; // tension,
int valeurI; //current
const int nbrsampler=50;
int16_t tableV[nbrsampler];
int16_t tableI[nbrsampler];
byte indexTable=0;
int offsetV=3103;
int offsetI=2048;
int signalV;
int signalI;
float rmsV;
float tensionRMS;
float rmsI;
float currentRMS;
float MaxV; //
float minV;
float amplitudeV;
float MaxI; //
float amplitudeI;
void IRAM_ATTR timer_isr() { //routine interruption 1 seconde
if (flagenvoie==1) {flag=0;} else {flag=1;} //bloque l'acquisition lors d'envoie des data
sampler++; //10 periode de 20ms
}//fin isr
void setup() {
Serial.begin(115200);
pinMode(22, OUTPUT);
tft.init(); //135 × 240.
tft.setRotation(0); //0 format portrait a l'endroit 2 180°
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0, 2); //// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK); //(couleur police, background police)
tft.println("IUT GEII SOISSONS");
analogReadResolution(12); // ADC 12 bits : 0 à 4095
analogSetAttenuation(ADC_11db); // Plage ADC environ 0 à 3,3 V
uint8_t timer_id = 1;
uint16_t prescaler = 80; // Between 0 and 65 535
int threshold = 800; // 800us
timer = timerBegin(timer_id, prescaler, true);
timerAttachInterrupt(timer, &timer_isr, true);
timerAlarmWrite(timer, threshold, true);
timerAlarmEnable(timer);
}
void loop() {
if (sampler>nbrEchantillons) { //400us*10000=4s 800us*2500=2
flagenvoie=1;
offsetV = sommeV / nbrEchantillons;
offsetI = sommeI / nbrEchantillons;
for (uint16_t i = 0; i < nbrsampler; i++)
{
Serial.print(tableV[i]);
Serial.print(",");
Serial.println(tableI[i]);
}
// determination amplitude
amplitudeV=((MaxV-offsetV)*0.47);
amplitudeI=((MaxI-offsetI)*0.0035);
// Calcul RMS tension alternatif
rmsV = sqrt(sommeCarres / nbrEchantillons);
tensionRMS = (rmsV *0.47); //3.3*582/4095=0.47
rmsI = sqrt(sommeCarresI / nbrEchantillons);
currentRMS= (rmsI*0.0035); //3.3* /4095=0.004
tft.setCursor(0, 20, 4);// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.print("V: ");
tft.print(tensionRMS,0);
tft.print(" ");
tft.setCursor(0, 50, 4);// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.print("aV: ");
tft.print(amplitudeV,0);
tft.print(" ");
tft.setCursor(0, 80, 4);// (x,y,taille)
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.print("I: ");
tft.print(currentRMS,3);
tft.print(" ");
tft.setCursor(0, 110, 4);// (x,y,taille)
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.print("aI: ");
tft.print(amplitudeI,3);
tft.print(" ");
sommeCarres=0;
sommeCarresI=0;
sommeV=0;
sommeI=0;
MaxV = 0;
minV = 4095;
MaxI = 0;
sampler=0;
flagenvoie=0;
} //end sampler
if (flag==1) {
flag=0;
if (digitalRead(22)==0) {digitalWrite(22,1); } else {digitalWrite(22,0); }
valeurADC = analogRead(27); //pinZMPT sensor voltage
sommeV += valeurADC; //
if (valeurADC > MaxV) {MaxV = valeurADC;}
signalV = valeurADC - offsetV; // Suppression de l'offset pour RMS
valeurI = analogRead(26); //pin intensity
sommeI += valeurI;
signalI = valeurI - offsetI;
if (valeurI > MaxI) {MaxI = valeurI;}
sommeCarres += signalV * signalV; // Carré du signal
sommeCarresI += signalI * signalI; // Carré du signal
tableV[indexTable] = signalV;
tableI[indexTable] = signalI;
indexTable++;
if (indexTable>=nbrsampler) {indexTable=0; }
} //flag==1
} //end loop
On peut remarquer que le calcul de l’offset est légèrement décalé (amplitude positive n’est pas identique à l’amplitude négative), le ZMT provoque quelques distorsions du signal secteur ainsi que l’ADC.
Le courant a des distorsions souvent à cause des systèmes électroniques qui utilisent des redresseurs filtrés en tension mais aussi si le courant est faible.
Maintenant que la phase tension est bien synchro avec le courant et que les facteurs d’échelles sont bien calibrés avec une précision de la tension à 0.47V et celui du courant 0.0035A.
Alors la puissance apparente et active peut être programmer.
Sur des petits courants, de 0.3A AC, avec un capteur de 1V pour 50A SCT-013-050 , la mesure du courant est assez bruitée comme on peut l’observer sur la figure suivante.
D’ailleurs, ce bruit est mesurable car lorsqu’il n’y a pas de courant qui est de 0.034A.
Ce courant n’est pas significatif par rapport à un système qui peut mesurer 50A.
Il faudrait un amplificateur avec différents calibres pour améliorer cette précision pour les petits courants
Pour un courant efficace de 3.1A, on peut observer le déphase entre la tension et le courant qui est environ 45° donne un facteur de puissance de 0.72
Par contre, la précision de la mesure de la puissance active et apparente est correcte même pour les petits courants en utilisant la puissance instante divisée par 2500 échantillons toutes les 2 secondes
La puissance est bien nulle lorsqu’il n’y en a pas de courant
Voici le programme de base utilisant la somme de puissance instantanée divisée par 2500 échantillons pour avoir la puissance moyenne donc le calcul de l’énergie se fait sur l’intégration de la puissance tous les 2s.
/TTGO dispaly ZMPT101B sensor voltage
// Mesure de tension et intensity AC RMS power energy
#include <TFT_eSPI.h>
#include <SPI.h>
hw_timer_t * timer = NULL;
TFT_eSPI tft = TFT_eSPI(); //library 1,4" color 135, 240
const int nbrEchantillons = 2500; // periodes
int sampler=0;
bool flag;
bool flagenvoie;
float sommeV = 0;
float sommeI=0;
float sommeCarres = 0;
float sommeCarresI = 0;
float sommePower;
int valeurADC; // tension,
int valeurI; //current
const int nbrsampler=50;
const float calibreI=0.019;
const float calibreV=0.5;
int16_t tableV[nbrsampler];
int16_t tableI[nbrsampler];
byte indexTable=0;
int offsetV=3103;
int offsetI=2048;
int signalV;
int signalI;
float rmsV;
float tensionRMS;
float rmsI;
float currentRMS;
float MaxV; //
float minV;
float amplitudeV;
float MaxI; //
float amplitudeI;
float Power;
float S; //power appararente
float FP; //factor power
float joule2;
float Energy;
void IRAM_ATTR timer_isr() { //routine interruption 800u seconde
if (flagenvoie==1) {flag=0;} else {flag=1;} //bloque l'acquisition lors d'envoie des data
sampler++; //100 periode de 20ms
}//fin isr
void setup() {
Serial.begin(115200);
pinMode(22, OUTPUT);
tft.init(); //135 × 240.
tft.setRotation(0); //0 format portrait a l'endroit 2 180°
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0, 2); //// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK); //(couleur police, background police)
tft.println("IUT GEII SOISSONS");
analogReadResolution(12); // ADC 12 bits : 0 à 4095
analogSetAttenuation(ADC_11db); // Plage ADC environ 0 à 3,3 V
uint8_t timer_id = 1;
uint16_t prescaler = 80; // Between 0 and 65 535
int threshold = 800; // 800us
timer = timerBegin(timer_id, prescaler, true);
timerAttachInterrupt(timer, &timer_isr, true);
timerAlarmWrite(timer, threshold, true);
timerAlarmEnable(timer);
}
void loop() {
if (sampler>nbrEchantillons) { //400us*10000=4s 800us*2500=2
flagenvoie=1;
offsetV = sommeV / nbrEchantillons;
offsetI = sommeI / nbrEchantillons;
for (uint16_t i = 0; i < nbrsampler; i++)
{
Serial.print(tableV[i]);
Serial.print(",");
Serial.println(tableI[i]*4);
}
// determination amplitude
amplitudeV=((MaxV-offsetV)*calibreV);
amplitudeI=((MaxI-offsetI)*calibreI);
// Calcul RMS tension alternatif
rmsV = sqrt(sommeCarres / nbrEchantillons);
tensionRMS = (rmsV *calibreV); //3.3*582/4095=0.47
rmsI = sqrt(sommeCarresI / nbrEchantillons);
currentRMS= (rmsI*calibreI); //3.3* /4095=0.004
tft.setCursor(0, 20, 4);// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.print("V: ");
tft.print(tensionRMS,0);
tft.print(" ");
tft.setCursor(0, 50, 4);// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.print("aV: ");
tft.print(amplitudeV,0);
tft.print(" ");
tft.setCursor(0, 80, 4);// (x,y,taille)
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.print("I: ");
tft.print(currentRMS,3);
tft.print(" ");
/*tft.setCursor(0, 110, 4);// (x,y,taille)
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.print("aI: ");
tft.print(amplitudeI,3);
tft.print(" ");
*/
Power=(sommePower*calibreV*calibreI)/ nbrEchantillons; //power real
S=currentRMS*tensionRMS ; //power apparent
if (currentRMS>0.05) {FP=Power/S; } else {FP=1; } //factor power
joule2=joule2+Power; //W*2s
Energy=(joule2*2)/3600; //wh
tft.setCursor(0, 110, 4);// (x,y,taille)
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.print("E: ");
tft.print(Energy,0);
tft.print(" ");
tft.setCursor(0, 140, 4);// (x,y,taille)
tft.setTextColor(TFT_BLUE,TFT_BLACK);
tft.print("P: ");
tft.print(Power,0);
tft.print(" ");
tft.setCursor(0, 170, 4);// (x,y,taille)
tft.setTextColor(TFT_BLUE,TFT_BLACK);
tft.print("S: ");
tft.print(S,0);
tft.print(" ");
tft.setCursor(0, 200, 4);// (x,y,taille)
tft.setTextColor(TFT_BLUE,TFT_BLACK);
tft.print("FP: ");
tft.print(FP,2);
tft.print(" ");
sommePower=0;
sommeCarres=0;
sommeCarresI=0;
sommeV=0;
sommeI=0;
MaxV = 0;
minV = 4095;
MaxI = 0;
sampler=0;
flagenvoie=0;
} //end sampler
if (flag==1) {
flag=0;
if (digitalRead(22)==0) {digitalWrite(22,1); } else {digitalWrite(22,0); }
valeurADC = analogRead(27); //pinZMPT sensor voltage
sommeV += valeurADC; //
if (valeurADC > MaxV) {MaxV = valeurADC;}
signalV = valeurADC - offsetV; // Suppression de l'offset pour RMS
valeurI = analogRead(26); //pin intensity
sommeI += valeurI;
signalI = valeurI - offsetI;
if (valeurI > MaxI) {MaxI = valeurI;}
sommeCarres += signalV * signalV; // Carré du signal
sommeCarresI += signalI * signalI; // Carré du signal
sommePower += signalI * signalV;
tableV[indexTable] = signalV;
tableI[indexTable] = signalI;
indexTable++;
if (indexTable>=nbrsampler) {indexTable=0; }
} //flag==1
} //end loop
Sachant que la puissance instantanée contient une ondulation du double de la puissance secteur donc à 100 Hz. Donc pour avoir la puissance moyenne, il est possible d’utiliser une filtre IIR passe pas de fréquence de coupure de 1s qui donnera une puissance plus lissée.
Dans un premier temps, un filtre du premier ordre sera utilisé qui donne une atténuation de 0.016 donc 1.6% pour une fréquence de coupure de 0.16Hz et une constante de temps de 1s.
Donc l’énergie peut être déterminée toutes les 800us.
Evidemment, un filtre du second ordre aurait pu être utilisée. Mais avec une fréquence de coupure de 1Hz avec 800us d’échantillonnage, l’atténuation sera de 0.04 mais la précision des coefficients du filtre demandé ne pourra être réaliser avec 7 chiffres significatifs
a1 = -1.99289;
a2 = 0.99291;
Par contre, il serait possible de mettre 2 filtres du premier ordre en cascade si l’on veut améliorer la précision.
Voici le programme avec la puissance moyenne par le filtre
La méthode du filtre IIR passe bas peut être utilisée aussi sur la mesure du courant RMS et pour enlever la composante continue un filtre passe haut donc plus besoin de déterminer l’offset
Donc pour mesurer la tension et le courant un filtre passe haut du premier ordre a été utilisé avec une fréquence de coupure de 2Hz pour retirer la composante continue 0Hz mais gardant la composante alternative de 50Hz.
Puis un filtre passe bas du signal pour avoir la valeur efficace RMS du signal
Le temps de calcul pour avoir le courant, la tension et la puissance est de 250us.
Il n’est pas possible de mettre ce temps de calcul dans la routine d’interruption qui est pourtant de 800us car cela bug.
Par contre avec 1000us de la routine cela passe.
mais, on a refait un flag dans la fonction loop pour garder 800us
L’avantage du filtre passe bas est d’avoir un affichage stable qui évolue progressivement donc de façon moins abrupte surtout au niveau du courant qui est assez variable.
Voici le programme ou il n’y a pas besoin de mettre les données dans une table, c’est juste une vérification.
/TTGO dispaly ZMPT101B sensor voltage
// Mesure de tension et intensity AC RMS filtre IIR passe haut et passe bas
#include <TFT_eSPI.h>
#include <SPI.h>
hw_timer_t * timer = NULL;
TFT_eSPI tft = TFT_eSPI(); //library 1,4" color 135, 240
const int nbrEchantillons = 2500; // pour affichage
volatile int sampler=0;
volatile bool flag;
volatile bool flagenvoie;
float valeurADC,valeurADCn ; // tension,
float valeurI,valeurIn ; //current
const int nbrsampler=50;
const float calibreI=0.019;
const float calibreV=0.5;
int16_t tableV[nbrsampler];
int16_t tableI[nbrsampler];
byte indexTable=0;
float signalV,signalVn;
float signalI,signalIn;
float rmsV, rmsVn;
float tensionRMS;
float rmsI, rmsIn;
float currentRMS;
float MaxV; //
float minV;
float amplitudeV;
float MaxI; //
float amplitudeI;
float Powerinstant;
float Power;
float Powern;
float Powerf;
float S; //power appararente
float FP; //factor power
float joule2;
float Energy;
// const float alpha = 1.0f - expf(-0.0008 / cstemps); //0.0016 cstemps=1
const float alphaPB=0.0016;
const float alphaHP =0.9901;
void IRAM_ATTR timer_isr() { //routine interruption 800u seconde
if (flagenvoie==1) {flag=0;} else {flag=1;}
sampler++; //affichage tous les 2s
}//fin isr
void setup() {
Serial.begin(115200);
pinMode(25, OUTPUT);
tft.init(); //135 × 240.
tft.setRotation(0); //0 format portrait a l'endroit 2 180°
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0, 2); //// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK); //(couleur police, background police)
tft.println("IUT GEII SOISSONS");
analogReadResolution(12); // ADC 12 bits : 0 à 4095
analogSetAttenuation(ADC_11db); // Plage ADC environ 0 à 3,3 V
uint8_t timer_id = 1;
uint16_t prescaler = 80; // Between 0 and 65 535
int threshold = 800; // 800us
timer = timerBegin(timer_id, prescaler, true);
timerAttachInterrupt(timer, &timer_isr, true);
timerAlarmWrite(timer, threshold, true);
timerAlarmEnable(timer);
}
void loop() {
if (flag==1) {flag=0;
// if (digitalRead(25)==0) {digitalWrite(25,1); } else {digitalWrite(25,0); }
digitalWrite(25,1); //temps de calcul du flag 250us
valeurADC = analogRead(27); //pinZMPT sensor voltage
signalV = alphaHP * (signalVn + valeurADC - valeurADCn); //filtre passe haut
signalVn=signalV; //valeur precedente
valeurADCn=valeurADC;
rmsV = rmsVn + alphaPB * (signalV*signalV - rmsVn); //filtre passe bas
rmsVn=rmsV; //valeur precedente
tensionRMS=(sqrt(rmsV))*calibreV;
valeurI = analogRead(26); //pin intensity
signalI = alphaHP * (signalIn + valeurI - valeurIn); //filtre passe haut
signalIn=signalI; //valeur precedente
valeurIn=valeurI;
rmsI = rmsIn + alphaPB * (signalI*signalI - rmsIn); //filtre passe bas
rmsIn=rmsI; //valeur precedente
currentRMS= (sqrt(rmsI))*calibreI;
Powerinstant = signalI * signalV;
Powerf = Powern + alphaPB * (Powerinstant - Powern); //puissance flitrée
Powern = Powerf; //n-1
Power=Powerf*calibreV*calibreI;
joule2=joule2+Power; //
Energy=(joule2*0.0008)/3600; //wh
tableV[indexTable] = signalV; //enregiste les 50 derniers mesures
tableI[indexTable] = signalI;
indexTable++;
if (indexTable>=nbrsampler) {indexTable=0; }
digitalWrite(25,0);
}// fin flag
if (sampler>2500) { // 800us*2500=2secondes affichage et bilan
flagenvoie=1;
for (uint16_t i = 0; i < nbrsampler; i++)
{
Serial.print(tableV[i]);
Serial.print(",");
Serial.println(tableI[i]*5); //facteur d'echelle
}
tft.setCursor(0, 20, 4);// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.print("V: ");
tft.print(tensionRMS,0);
tft.print(" ");
tft.setCursor(0, 50, 4);// (x,y,taille)
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.print("aV: ");
tft.print(amplitudeV,0);
tft.print(" ");
tft.setCursor(0, 80, 4);// (x,y,taille)
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.print("I: ");
tft.print(currentRMS,3);
tft.print(" ");
S=currentRMS*tensionRMS ; //power apparent
if (currentRMS>0.05) {FP=Power/S; } else {FP=1; } //factor power
tft.setCursor(0, 110, 4);// (x,y,taille)
tft.setTextColor(TFT_RED,TFT_BLACK);
tft.print("E: ");
tft.print(Energy,0);
tft.print(" ");
tft.setCursor(0, 140, 4);// (x,y,taille)
tft.setTextColor(TFT_BLUE,TFT_BLACK);
tft.print("P: ");
tft.print(Power,0);
tft.print(" ");
tft.setCursor(0, 170, 4);// (x,y,taille)
tft.setTextColor(TFT_BLUE,TFT_BLACK);
tft.print("S: ");
tft.print(S,0);
tft.print(" ");
tft.setCursor(0, 200, 4);// (x,y,taille)
tft.setTextColor(TFT_BLUE,TFT_BLACK);
tft.print("FP: ");
tft.print(FP,2);
tft.print(" ");
sampler=0;
flagenvoie=0;
} //fin flagaencoie et affichage
} //end loop
Pourrait-on utiliser le double core de l’ESP32 entre l’affichage et la mesure ?
Exemple : Core 0 → mesure, Core 1 → TFT avec une synchronisation entre les 2 core
Pour simplifier le code de l’utilisation des 2 core avec la routine d’interruption, seule la tension est affichée.
Core 0 → mesure et calculs, Core 1 → TFT avec une synchronisation entre les 2
Avec l’utilisation des 2 cores, il est possible de diminuer le temps de la routine d’interruption.
Attention, si on diminue la routine d’interruption, on modifie les fréquences de coupures du filtre passe haut et passe bas.
Un autre avantage d’utilisation du filtre c’est que la racine de la tension avec l’offset retiré ne peut etre négative par rapport au calcul de la somme
Maintenant, il faut faire la communication
Au niveau de la communication de ESP 32 de l’energy metre et commander d’autres ESP32 pour faire du délestage via le wifi ou bluetooth, il y a plusieurs possibilités mais je n’ai pas de recul pour savoir ce qui est le mieux et je ne connais pas les limites des possibilités de chacun tout en restant gratuit.
Le net donne 3 possibilités : ESP32 → Wi-Fi → box → Vlan → INTERNET → PC/téléphone
Dans un premier temps, une communication locale sera effectuée et permetra detester la valeur du signal le wifi autour de la box
ESP32 → Wi-Fi → box → INTERNET locale → PC/téléphone
En locale, il faut que le PC ou le telephone ne soit pas loin de la box
Il est possible de se balader avec son ESP32 pour connaitre la valeur du signal dans une maison est de savoir si cela va passer ou pas.
· 30 à -50 dBm : Signal excellent. L'ESP32 est à côté de la box (routeur)
· -60 à -67 dBm : Signal très bon.
· -70 à -75 dBm : Signal correct. La connexion est stable, mais les obstacles commencent à l'atténuer.
· -80 à -85 dBm : Signal faible. Risque de déconnexions fréquentes et de pertes de paquets de données.
· -90 dBm et au-delà : Signal critique. La connexion est instable ou impossible à maintenir (au dela de 10m)
Sinon, il faut un wifi extender pour améliorer la communication
Pour ne pas compliquer le code, voici le programme qui envoie une valeur en temps réel comme la température en page HTML directement sur l’adresse IP que l’ESP32 a envoyé dans la liaison série.
//TTGO wifi server
#include <WiFi.h>
#include <WebServer.h>
#include <TFT_eSPI.h>
const char* ssid = " ";
const char* password = " ";
TFT_eSPI tft = TFT_eSPI();
WebServer server(80); //crée le serveur Web.
float temperature = 23.5; // à remplacer par votre capteur
void handleRoot() //Quand la page web PC demande /, exécute la fonction handleRoot(). »
{
String page = "<!DOCTYPE html>";
page += "<html>";
page += "<head>";
page += "<meta charset='UTF-8'>";
page += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
page += "<meta http-equiv='refresh' content='4'>"; //refraissement 4s
page += "<title>ESP32 Temperature</title>"; //affiché dans les résultats des moteurs de recherche.
page += "</head>";
page += "<body>"; //ouvre l'ecriture
page += "<h1>ESP32</h1>";
page += "<p>Temperature : " + String(temperature) + " °C</p>"; //<p> paragraphe
page += "<p>Signal Wi-Fi : " + String(WiFi.RSSI()) + " dBm</p>";
page += "</body>";
page += "</html>";
server.send(200, "text/html", page); //requete ok
}
void setup()
{
Serial.begin(115200);
// Ecran
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
tft.setCursor(10, 20);
tft.println("Connexion WiFi...");
// Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connecte !");
Serial.print("Adresse IP : "); //indique l'adresse IP locale de l'ESP32
Serial.println(WiFi.localIP()); //sinon regarder dans la box
// Serveur Web
server.on("/", handleRoot);
server.begin();
Serial.println("Serveur Web demarre");
}
void loop()
{
server.handleClient(); //traiter les demandes reçues.
temperature=temperature+0.1; //simuulation
if (WiFi.status() == WL_CONNECTED)
{
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 20);
tft.print("dBm: ");
tft.print(WiFi.RSSI()); //indique la puissance du signal
tft.setCursor(0, 130);
tft.print("T: ");
tft.print(temperature, 1);
tft.print(" C");
}
delay (2000);
}
Voilà ce que donne le script du code précèdent en temps réel
Si l’on désire envoyer une table de valeur glissante des 10 dernières minutes et voir jusque 1 heure en fichier .csv via le wifi.
L’objectif de ce fichier est d’avoir la connaissance de dynamique des données
Voici le code
//TTGO dispaly wifi server table buffer circulaire .CSV
#include <WiFi.h>
#include <WebServer.h>
#include <TFT_eSPI.h>
const char* ssid = " "; // name box WIFI
const char* password = " "; //password
TFT_eSPI tft = TFT_eSPI();
WebServer server(80);
float temperature = 0; // A remplacer par le vrai capteur
const int TAILLE_TAMPON = 300; // 300 mesures x 2 secondes = 600 secondes => 10 minutes
float bufferTemperature[TAILLE_TAMPON];
unsigned long bufferTemps[TAILLE_TAMPON];
int indexActuel = 0;
int nombreValeurs = 0;
unsigned long derniereMesure = 0;
unsigned long tempsEnregistrement = 0;
// Intervalle entre deux mesures
const unsigned long INTERVALLE = 2000; // 2 secondes
void handleRoot() // PAGE WEB PRINCIPALE
{
String page = "";
page += "<!DOCTYPE html>";
page += "<html>";
page += "<head>";
page += "<meta charset='UTF-8'>";
page += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
page += "<meta http-equiv='refresh' content='2'>"; // Actualisation de la page toutes les 2 secondes
page += "<title>ESP32 Temperature</title>";
page += "<style>";
page += "body {";
page += "font-family: Arial;";
page += "margin: 20px;";
page += "background-color: #eeeeee;";
page += "}";
page += "h1 { color: #333333; }";
page += ".temperature {";
page += "font-size: 30px;";
page += "color: red;";
page += "font-weight: bold;";
page += "}";
page += ".csv {";
page += "background-color: white;";
page += "border: 1px solid #999;";
page += "padding: 10px;";
page += "font-family: monospace;";
page += "white-space: pre;";
page += "overflow-x: auto;";
page += "height: 400px;";
page += "overflow-y: scroll;";
page += "}";
page += "button {";
page += "font-size: 18px;";
page += "padding: 10px 20px;";
page += "}";
page += "</style>";
page += "</head>";
page += "<body>";
// ----------------------------------------------------------
page += "<h1>ESP32</h1>";
page += "<p>Temperature en temps reel :";
page += "<div class='temperature'>";
page += String(temperature, 1);
page += " °C";
page += "</div>";
// page += "<h2>Buffer</h2>"; // INFORMATIONS BUFFER
// page += "<p>"+= "buffer : " += String(nombreValeurs);+= " / "+= String(TAILLE_TAMPON) "</p>"; // INFORMATIONS BUFFER
/*
page += "<h2>Donnees CSV</h2>"; // AFFICHAGE CSV
page += "<div class='csv'>";
// En-tête CSV
page += "Temps(s);Temperature(°C)\n";
if (nombreValeurs > 0) {int debut;
if (nombreValeurs < TAILLE_TAMPON) { debut = 0; }
else { debut = indexActuel; }
// Affichage dans l'ordre chronologique
for (int i = 0; i < nombreValeurs; i++)
{
int position = (debut + i) % TAILLE_TAMPON;
page += String(bufferTemps[position]);
page += ";";
page += String(bufferTemperature[position], 1);
page += "\n";
}
}
page += "</div>";
*/
// ----------------------------------------------------------
page += "<br>"; // BOUTON TELECHARGEMENT
page += "<a href='/download'>";
page += "<button>Télécharger le fichier CSV</button>";
page += "</a>";
page += "</body>";
page += "</html>";
server.send(200, "text/html", page);
}
// ============================================================
void handleDownload() // CREATION ET TELECHARGEMENT DU CSV
{
String csv = "";
csv += "Temps(s);Temperature(°C)\r\n";
// ORDRE CHRONOLOGIQUE
if (nombreValeurs > 0) { int debut;
if (nombreValeurs < TAILLE_TAMPON) { debut = 0; } else { debut = indexActuel; }
for (int i = 0; i < nombreValeurs; i++)
{
int position = (debut + i) % TAILLE_TAMPON;
csv += String(bufferTemps[position]);
csv += ";";
csv += String(bufferTemperature[position], 1);
csv += "\r\n";
}
}
// ----------------------------------------------------------
server.sendHeader( // ENVOI DU FICHIER
"Content-Disposition",
"attachment; filename=temperature.csv");
server.send( 200, "text/csv", csv );
}
// ============================================================
void setup() {
Serial.begin(115200);
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
tft.setCursor(10, 20);
tft.println("Connexion WiFi...");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println();
Serial.println("WiFi connecte !");
Serial.print("Adresse IP : ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot); // ENVOI DU FICHIER
server.on("/download", handleDownload);
server.begin();
Serial.println("Serveur Web demarre");
derniereMesure = millis(); // INITIALISATION TEMPS
tempsEnregistrement = 0;
} //fin set up
// ============================================================
void loop() {
server.handleClient(); // SERVEUR WEB
unsigned long maintenant = millis(); // NOUVELLE MESURE TOUTES LES 2 SECONDES
if (maintenant - derniereMesure >= INTERVALLE) { derniereMesure = maintenant;
temperature = temperature + 0.1; // SIMULATION de data TEMPERATURE
bufferTemps[indexActuel] = tempsEnregistrement; // ENREGISTREMENT DU TEMPS
bufferTemperature[indexActuel] = temperature;
tempsEnregistrement += 2; // INCREMENT DU TEMPS
indexActuel++;
if (indexActuel >= TAILLE_TAMPON) {indexActuel = 0; }
if (nombreValeurs < TAILLE_TAMPON) {nombreValeurs++; }
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 20);
tft.setTextSize(2);
tft.print("T:");
tft.print(temperature, 1);
tft.print(" C");
} //fin intervalle
} //End loop
Le fichier s’enregistre directement dans le dossier download
Si l’on desire passer via la 4G, il faudra utiliser MQTT :
│ESP32 IP : 192.168.1.34│ → publish → │Wi-Fi TCP / réseau IP box│ → Broker MQTT mosquito → subscribe (ecoute) → │4G téléphone Home Assistant│
Mais d’abord, on va rajouter dans le code du wifi local, la mesure de la tension et du courant pour avoir la puissance active, et le facteur de puissance
J’ai demandé à une IA de fusionner le programme du wifi local et le programme 2 core avec toutes les mesures (tension et courant, puissance et facteur de puissance)
L’IA donne meme l’algo
Avec les cinq tableaux de 300 valeurs de float 4 octet (10minutes), le compilateur indique que 15% de la mémoire SRAM de 520k de l’ESP32 est utilisé et que Le programme prend 62%.
Avec 1800 valeurs de buffer (1 heure) , (1800*5*4oxter=36koctet), le compilateur indique que la SRAM utilise 24%
Avec 3600 valeurs de buffer (2 heures) , la compilation indique que la SRAM utilise 35%
Avec 5400 valeurs de buffer, le compilateur ne veut plus transmettre le programme à cause du string+csv qui doit prendre pas mal de RAM
Pour faire une étude énergétique poussée et de sauvegarder les données du fichier .CSV automatiquement toutes les 2 heures.
Il est possible de changer le script HTML de l’ESP32 (quand le buffer est plein) vers Google Drive/cloud, par MQTT, par e-mail sans avoir à appuyer sur « Télécharger »
J’ai fait des tests pour faire une comparaison avec du matériel (relais, compteur, disjoncteur numérique) existant que l’on m’a prêté….
Le KWS-303WF ne donne pas la puissance injectée car elle n’est pas bidirectionnelle sur cet appareil !
Il y a une application sur smartphone du KWS-303WF qui trace la puissance et le facteur de puissance mais toutes les heures donc ne permet pas d’étudier un réseau électrique (consommation) ni faire du délestage.
Ce n’est pas pertinent d’avoir un graphique avec une mesure de puissance toutes les heures ! Le taux de rafraîchissement des données de l’application par le wifi est de 1 minute minimum.
Mais, avec l’application, on peut couper ce qu’il alimente manuellement.
J’ai un doute sur la mesure du facteur de puissance qui est trop volatile.
Dans le même genre, j’ai testé le TOMPD-63LW qui lui est bidirectionnel et indique la puissance négative sur l’écran, mais pas sur l’application ????
il mesure le courant différentiel en permanence et on peut savoir quel système a un défaut d’isolement. Le rafraichissement des données par le wifi de l’application est toutes les 2s.
Impossible de récupérer les données via l’adresse IP en wifi local via la plateforme Tuya car le Vlan est bloqué et il faut obligatoirement passer par le cloud tuya payant.
Sur la plateform tuya avec TOMPD-63LW, la data de la puissance n’est pas négative non plus ????
Sur le net, on peut observer que les anciennes versions TOMPD-63LW était plus libre mais s’il faut changer le firmware, c’est pénible. Et certains ont essayé sans succès ou pour avoir une écriture en mandarin ou un ecran tout noir, ce n’est pas gagné.
Etant donné que la puissance négative n’est pas prise en compte, l’energie consommée totale ne prend pas en compte la réinjection dans l’application.
Lorsqu’il y a réinjection, la tension réseau augmente légèrement de 1V par rapport à la chute de la tension dans les câbles.
Des systèmes domotiques existent tel que Shelly Pro 3EM 120A – Smart Meter (130€) via des contacteurs modulaires (50€), il va commander des appareils en tout ou rien. Sachant que la priorité du délestage se ferait avec l’application android (Shelly Smart Control) mais cela n’est pas bien expliqué ????
Il existe plusieurs architectures de l’utilisation des panneaux photovoltaïque avec batterie de stockage, mais là plus utilisé est la suivante à cause que si la batterie de stockage est pleine le surplus ira dans le réseau
Panneaux PV → onduleur hybride ↔ batterie stockage et maison ↔ réseau
Mais cela peut se compliquer à donner des priorités en fonction de metéo futur…
Bref, pas facile de gérer l’énergie et faire du délestage autoconsommation d’énergie photovoltaïque ou éolien, les systèmes deviennent très vite propriétaire, les manuels de ces appareils n’explique pas tout donc ce n’est pas la « smartlife ».
Voici le programme qui envoie les données toutes les 2 heures de façon automatique, ce qui permet de faire autres choses sur son PC sans louper d’enregistrer.
On croit toujours que c’est simple à faire mais c’est toujours plus compliqué à que l’on ne le pense !
On m’a posé la question pourquoi ne pas utiliser ESP home ?
Parce ce que je ne le connais pas bien.
Si la mise en réseau semble assez simple, je n’ai en revanche jamais testé l’imposition du temps d’échantillonnage des mesures !
Bref, avec le programme précèdent, l’ESP32 commandera d’autres ESP32 avec Wi-Fi mais sans passer par la box ce qui sera plus simple mais il ne faudra pas qu’il soit trop éloignée 25m en intérieur et ? m en exterieur
Juste une remarque, dans une information plutôt pédagogique il est préférable d'utiliser nullptr à null en C++ cela peut toujours éviter des surprises désagréables et difficilement compréhensibles pour les débutants en C++
Bonjour,
Attention au post #9 et #7, le réseau et son mot de passe est visible en clair je crois.
Votre post est très intéressant par ailleurs. Je lui suis avec intérêt
Pour un vieux enseignant, je manque de rigueur…pour la bidouille
Pour continuer sur la bidouille voici les programmes de communication en wi ifi entre 2 ESP32
Sur le net, il y a une foule d’explication sur les différents modes de wifi avec l’ESP32 et de commande.
Mais pour simplifier, on va faire un programme simple avec 1 ESP32 en mode serveur qui sera le compteur d'énergie et qui va communiquer directement avec ESP NOW vers d'autres ESP32 qui feront contacteur tout ou rien pour delester.
En effet, ESP NOW a été développé pour cela avec 250 octets de transmission possible.
L’abréviation MAC signifie Media Access Control) gère la façon dont les données se déplacent dans le wifi. Le mode broadcast (diffusion générale) désigne l'envoi d'un même message à tous les appareils à portée qui écoutent sur le même canal adresse mac (FF:FF:FF:FF:FF:FF).
Si on désire une communication qu’a 1 seul ESP32 client, il faut aller lire l’adresse du récepteur.
Tout est bien expliqué sur ce lien
J’utilise l’ESP32 Arduino core 2.0.17 et pas les dernières versions ou les fonctions de la routine d’interruption avait changé avec les nouvelles versions, mais il y a aussi des fonctions avec ESP NOW qui ont changé.
Voici le code pour le TTGO serveur, juste pour une mesure de temperature simulé par simplification
Voici le code pour le TTGO client recepteur
Lors d’un envoie, la valeur en dbm est affichée pour tester la distance de fonctionnement du wifi pour savoir si cela va fonctionner ou pas.
En Europe, la puissance est limité à 89 mW donc par rapport au milliwatt cela donne +19.5mdB qui est poissble à parametrer
WiFi.setTxPower(WIFI_POWER_19_5dBm); //
La portée va dépendre de l’antenne. Avec une petite antenne low tech on peut gagner 10dbm.
Mais sur le display TTGO ce n’est pas facile à souder
Sur la page HTML du serveur, 1 seul bouton commande manuelle ou automatique avec 1 seul bouton on/off serait intéressant à faire pour commander automatiquement ou pas le delestage.
De plus, une perte du wifi à l’ESP32 serveur devrait etre signalé en interrogeant regulierement l’ESP 32 récepteur.
En faisant des essais, on a remarqué qu’entre le capteur de tension ZMPT et le capteur de courant, il y a un déphasage de 28° sur le signal transmis de la puissance avec la courbe bleu correspondant à la tension secteur, la courbe rouge le courant, la courbe verte la puissance instantanée alors que la charge était purement résistive donc déphasage nulle. Sachant que les filtres numériques entrainent aussi de petits déphasages.
on a repris le programme du poste 4
Par conséquent, on a décalé de 2 échantillons, la mesure de la tension pour avoir la courbe suivante
On a fait aussi 3 tours dans le capteur de courant pour améliorer la précision de la mesure du courant
De plus, on a rajouté un filtre passe bas avec une fréquence de coupure de 100Hz sur la mesure de tension et de courant pour minimiser le bruit sur le courant mais cela atténué très légèrement la tension et le courant.
Donc, on a du ajusté le calibre de la tension et du courant et cela fonctionne tres bien à 0.01prés pour le facteur de puissance.
Voici le signal qui donne tension, courant, puissance instantanée pour 1000W pour 232V RMS qui sont bien en phase pour la determination de la puissance instannée
Les améliorations de la mesure avec filtre passe haut et passe bas pour minimiser le bruit pour donner un facteur de puissance fiable, avec la fusion du programme utilisant les 2 core de l’ESP 32 a été fait avec l’envoie des données automatiques toutes les 2 heures.
J’avais un doute sur la mesure du facteur de puissance du Tuya TOMPD-63LW, mais l’ESP32 et ce module donne les mêmes valeurs
Les appareils électroniques faibles puissances qui ont du redressement avec filtrage capacitif ont des facteurs de puissances autour de 0.5 (téléviseur, chargeur de smartphone, chargeur de vélo, chargeur nettoyeur laveur) mais même les alimentations des microcontrôleurs des laves vaisselles, machine à laver….
Tout ce qui est grosse puissance 2000W (résistance four électrique, plaque vitro céramique, chauffage eau machine à laver) sont commandés en tout ou rien…
Aspirateur traineau qui a encore un moteur série DC avec son réglage triac par angle de phase provoque un mauvais facteur de puissance mais en générale, on est à fond.
Est-ce que les gens aurait compris la variabilité de leurs de consommation de leur maison avec le compteur linky qui enverrait tous les 2 secondes les données sur leur box ?
Car on peut observer la grande fluctuation de puissance active
De plus avec la réinjection du photovoltaïque, ces données fluctuent de positif à négatif.
Le facteur fluctue donc aussi de positif à négatif en fonction des charges tout ou rien. Il n’y a pas de batterie qui permettrait de lisser la consommation.
Par contre au niveau graphique, il est possible de faire une enveloppe moyenne et vectorielle pour minimiser les datas ou de faire la derivée de l'energie.
Le facteur de puissance n’est pas obligé d’être mémorisé dans le code car le traceur peut faire le calcul avec la tension, le courant et la puissance active.
En autoconsommation, étant donné que la réinjection est cadeau à cause que les centrales qui n’arriverait pas à faire baisser leur production rapidement et qu’il n’y a pas de volonté politiques à réguler le marché correctement.
Donc, dans le programme l’énergie consommée et réinjecté a été séparée comme dans le compteur linky
Pour faire du délestage, une période d’échantillonnage tous les 2 secondes est un minimum ainsi que l’affichage
Par contre pour avoir une dynamique de la puissance active sur une grande période de plus d’une heure pour avoir la puissance moyenne, on peut utiliser un filtre passe bas du premier ordre avec une fréquence de coupure de 1/600s donc de constante de temps de 10minutes comme on peut l’observer sur la figure suivante.
Ces 10 minutes correspondent aux montées en température et à l’inertie thermique de nos appareils électro-ménagers
Par conséquent, un enregistrement tous les minutes est amplement suffisant pour voir l’évolution de la puissance.
Le facteur de puissance négatif n’est pas très pertinent. Car celui-ci présente le rapport entre le courant actif et apparent.
On peut observer qu’il y a une différence entre la détermination le facteur de puissance qui est déterminé avec la puissance active en valeur absolue et l’apparente moyenne (courbe bleu) et le facteur de puissance déterminer avec le filtre passe bas en valeur absolue (courbe orange).
La dernière méthode est moins sensible lorsque la puissance est faible
Est-ce que le compteur Linky aurait du donner ces informations ?
Est-ce que les usagers auraient compris ces données ?
Les usagers comprennent tout de suite les données de la production photovoltaique des applications de leurs onduleurs donc ils auraient compris les infos de leurs consos
Dans ce programme, il manque la valeur max de la puissance apparente par jour, pour indiquer une disjonction par rapport à la puissance souscrite. Mais l’abonnement ne devrait plus exister depuis longtemps !
Etant donné que les données sont enregistrées dans des tables du TTGO, l’écran du PC peut être éteint avec le navigateur qui fonctionne pour récupérer le fichier .CSV de façon automatique tous les heures ou à tout moment.
Voici les données de puissance active et de son facteur d’une journée de ma maison avec du photovoltaïque d’où la valeur négative de la puissance….et les pics de puissance sont filtrées mais visible quand même malgré la mémorisation des échantillons toutes les minutes. On pourrait même faire toutes les 2 minutes.