Est ce qu'il y en a parmi vous qui ont une installation de panneaux photovoltaïques ? Je poste ce sujet icicar çà pourrait les intéresser.
J'ai construit une installation PV il y a un peu plus d'un an. 9 panneaux qui délivrent un peu plus de 3Kw. Après 1an d'utilisation on constate qu'on a divisé notre conso par 2 et qu'on devrait amortir le truc en 4 ou 5ans.
Donc çà vaut le coup.
MAIS... on s'aperçoit également qu'on redonne gratos au réseau ce qu'on ne consomme pas (une grosse partie de la production en plus) : on paie à EDF ce qu'on lui demande et en retour il nous prends gratos ce qu'on a en trop. Ca a tendance à m'énerver.
La solution: un routeur, système qu'on branche sur l'arrivée secteur du domicile pour mesurer ce qui entre et ce qui sort et utiliser ce qui sort en trop pour piloter un appareil électrique. De cette manière on peut utiliser ce qui sort en trop soit pour chauffer une piscine, faire fonctionner une clim l'été ou alimenter un radiateur électrique l'hiver. Le système fournit le trop plein sur une prise commandée, trop de soleil et trop de production (été comme hiver) le système alimente la prise commandée à l'intérieur de la maison (clim, radiateur, chauffe-eau, etc.), dés qu'on ne produit plus en trop la prise n'est plus alimentée. On fait ainsi fonctionner un appareil gratos ce qui n'est pas négligeable par les temps qui courrent.
Le schéma:
Principe: L'idée est de mesurer la tension secteur et le courant secteur en sortie de domicile, on calcule le déphasage entre les deux. Si courant et tension sont en phase on sait qu'on est en demande a EDF, si courant et tension sont en opposition de phase on sait qu'on produit trop et qu'on en rejette sur le réseau, et çà c'est ce qu'on veut éviter.
- Pour mesurer la tension on utilise un petit transformateur qui transforme le secteur en basse tension AC genre 6v pour moi, çà dépend de ce qu'on trouve comme transfo abaisseur. Juste par qu'on ne veut pas mettre directement du 230v sur une pin de microcontroleur, l'ADC a ses limites.
- Pour mesurer le courant on utilise une sonde de couplage sur la phase du secteur, on en extrait le courant divisé par une certaine valeur (1/100 pour moi), on le mesure aux bornes d'une résistance pour en extraire une tension résultante. Pareil le but est d'être dans les clous pour les pins ADC du microcontroleur.
- ces deux tensions sont envoyée aux bornes ADC d'un microcontroleur et on calcule la puissance résultante. Pour calculer une puissance on fait P=UI (Puissance=Tension x Intensité), ce qui nous donne une valeur positive. Ici on veut avoir une puissance positive ou négative suivant ce qui entre ou sort, pour cela on va utiliser une tension de ref qui se situe au centre de la tension admise par le microcontroleur, par exemple 2.5v pour des pins fonctionnant en 5v.
Quand l'ADC mesurera une tension en alternance positive il sera positif par rapport a vref, quand il mesurera une tension en alternance négative il sera négatif par rapport a vref. Aussi simple que cela.
De P=UI le calcul deviendra P=(I-ref) x (U-ref), ce qui nous donnera une valeur positive ou négative, ce qu'on souhaite.
Par exemple si le courant en phase avec la tension ils seront tous les deux ensembles en alternance positive ou négative, on aura P positif. Par contre si le courant est en déphasage par rapport a la tension, par exemple quand la tension est en alternance positive le courant sera en alternance négative et vice versa, et cela nous donnera une valeur négative.
Voilà pour le principe.
Le matos: j'aurai pu utiliser un PIC si je les programmais en C mais en asm çà va être la misère de travailler en nombres signés. Pour le programmer en C il faudrait installer l'usine a gaz MPLABX que je ne connais pas. Sur mon PC j'ai déjà VSCode d'installé, à partir de là j'ai hésité entre un arduino dont j'en ai un plein tiroir ou un ESP32. J'ai opté pour l'ESP32 parce que j'en avais un sur le bureau ce jour-là, comme quoi çà ne tient pas a grand chose. J'aurai pu utiliser un rapberry PI pico mais je n'y ai pas pensé sur le coup, çà m'aurait fait travailler mon python.
L'ESP32 fonctionnant en 3.3v j'ai fait un PCB équipé de ponts diviseurs pour descendre les tensions issues du transfo 6v, celle issue de la R courant en 3.3v et la Vref. L'ESP32 commandera un relais SSR sur lequel sera la prise radiateur ou clim.
Pour la partie hard je me suis inspiré du travail de F1ATB mais pas plus suivi ses traces car le cahier des charges est différent. Son code est très abouti et gère un système domotique, le wi-fi, etc. J'ai tout recodé a ma sauce pour faire plus simple.
On mesure 100 échantillons pendant chaque alternance (50Hz=20ms), on calcule la puissance et on fait la moyenne, négative on ouvre le relais, positive on ferme.
Deux leds sur le boitier indiquent si on est en demande ou en production.
Le PCB
Le code pour ESP32:
Code : Tout sélectionner
// Routeur Photovoltaïque d'après le hardware de F1ATB.
// Code F6FCO V.1 mars 2026
// ESP32-WROOM-32U
#include <Arduino.h>
/* --- CONSTANTES --- */
#define ADC_REF 35
#define ADC_V 32
#define ADC_I 33
#define RELAY_PIN 4
#define LED_RED 18
#define LED_GREEN 19
#define CYCLE_TIME 20000
#define SEUIL_SURPLUS -200
#define SEUIL_CONSO 50
/* --- VARIABLES --- */
long sum = 0;
int compteur_echantillon = 0;
long PW = 0;
bool valid_relais = false;
unsigned long micro_old = 0;
void Init_Hardware(void) {
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
analogSetAttenuation(ADC_11db);
// Séquence de test (Debug visuel)
digitalWrite(LED_RED, HIGH); delay(500); digitalWrite(LED_RED, LOW);
digitalWrite(LED_GREEN, HIGH); delay(500); digitalWrite(LED_GREEN, LOW);
}
void MesurePuissance(void) {
int rawV = analogRead(ADC_V);
int rawI = analogRead(ADC_I);
int ref = analogRead(ADC_REF);
sum += (long)(rawV - ref) * (rawI - ref);
compteur_echantillon++;
if (compteur_echantillon >= 100) {
PW = sum / 100;
sum = 0;
compteur_echantillon = 0;
valid_relais = true;
}
}
void ControleRelais(void) {
if (PW < SEUIL_SURPLUS) {
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_RED, LOW);
} else if (PW > SEUIL_CONSO) {
digitalWrite(RELAY_PIN, LOW);
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_RED, HIGH);
}
}
void setup() {
Init_Hardware();
micro_old = micros();
}
void loop() {
MesurePuissance();
if (valid_relais) {
ControleRelais();
valid_relais = false;
}
while (micros() - micro_old < CYCLE_TIME) {}
micro_old = micros();
} 