Messages : 242
Sujets : 10
Inscription : Feb 2025
Réputation :
20
Sur une UNO il y a des ports compatibles PWM et d'autres non. De toutes les façons il faudra modifier le code.
Pour avancer de manière efficace il ne suffit pas de changer de port mais déjà de savoir si ton ballon est compatible avec ce type d'alimentation. Ensuite il te faut une mesure de puissance bidirectionnelle afin de gérer le routage.
Messages : 449
Sujets : 1
Inscription : Sep 2024
Réputation :
54
14-08-2025, 07:44 PM
(Modification du message : 15-08-2025, 10:47 AM par Lolo69.)
si j ai juste pour faire du pwm tu peux tenter de commander ta GPIO comme ceci
dans les declarations
int ledPWM = 9;
dans le setup
pinMode(ledPWM, OUTPUT); // Déclare la broche comme sortie
dans la loop
analogWrite(ledPWM, 128); // ~50% de puissance
la valeur c est un 8 bit donc pour 0-100% c est une mise à l echelle entre 0 et 255
sur un UNO les GPIO 3, 5, 6, 9, 10, 11 ont la capacité à faire du PWM
Si c'est toi qui decide d'un pourcentage d'ouverture ca peut marcher, fais nous tes retours
Avec un SSR classique la variation de puissance sera très imprecise et chaotique. Si tu prends un ssr « aléatoire » ca fonctionnera mieux mais ca va faire swinger tes résistances et génèrer plein de parasite sur tout le réseau électrique.
Il faudrait passer en « burst mode » mais pour cela t as besoin de detecter le passage à zero du secteur (zc) donc de l electronique en +
Donc en conclusion si tu veux un résultat avant 10 ans tu as vraiment un enorme interet d acheter un esp32 à 3.2euros et partir sur la base du programme du routeur d André
Messages : 55
Sujets : 2
Inscription : Oct 2024
Réputation :
3
Ça va être compliqué sur ce forum de faire un routeur avec un UNO !
Mais demande à Google..."routeur pour les nuls"
Tu auras déjà des infos.
Messages : 7
Sujets : 1
Inscription : Aug 2025
Réputation :
0
(14-08-2025, 07:44 PM)Lolo69 a écrit : si j ai juste pour faire du pwm tu peux tenter de commander ta GPIO comme ceci
dans les declarations
int ledPWM = 9;
dans le setup
pinMode(ledPWM, OUTPUT); // Déclare la broche comme sortie
dans la loop
analogWrite(ledPWM, 128); // ~50% de puissance
la valeur c est un 8 bit donc pour 0-100% c est une mise à l echelle entre 0 et 255
sur un UNO les GPIO 3, 5, 6, 9, 10, 11 ont la capacité à faire du PWM
Si c'est toi qui decide d'un pourcentage d'ouverture ca peut marcher, fais nous tes retours
Avec un SSR classique la variation de puissance sera très imprecise et chaotique. Si tu prends un ssr « aléatoire » ca fonctionnera mieux mais ca va faire swinger tes résistances et génèrer plein de parasite sur tout le réseau électrique.
Il faudrait passer en « burst mode » mais pour cela t as besoin de detecter le passage à zero du secteur (zc) donc de l electronique en +
Donc en conclusion si tu veux un résultat avant 10 ans tu as vraiment un enorme interet d acheter un esp32 à 3.2euros et partir sur la base du programme du routeur d André
Bonjour et merci de votre retour constructif
J’ai pas mal fait de recherche « routeur pour les nuls mais débrouillard et passionné » sur Google et ce site et je vais tester la methode train de sinus sur 990ms car mon ssr gère déjà le zéro cross, j’ai juste « normalement » à ajouter la détection de passage à zéro
Bien sûr que je peux acheter un esp à 3 € et mettre le programme d’André je suppose qu’il est excellent et c’est top d’avoir des personnes comme ça mais bon pas très cérébralement motivant de copier coller
Messages : 131
Sujets : 0
Inscription : Jun 2024
Réputation :
5
Bonjour,
"mon ssr gère déjà le zéro cross, j’ai juste « normalement » à ajouter la détection de passage à zéro"
Si le SSR gère le ZC, c'est pas la peine de chercher à le récupérer aussi ...
On a pas encore le matériel dispo,
on va partir d'hypothèse : un UNO sans wifi = pas d'interface html, une source de mesure type UxI (quelques gpio analogique + un peu de composants) ou UxIx2/UxIx3 (un port série RxTx) ou Linky (un port série Rx + un opto 814)
une petite moulinette pour obtenir un nombre entre 0 et 100 représentatif du % de puissance a laisser passer vers le résistance du ballon (dés qu'on commence a injecté on va donner l'ordre de consommer pour ne pas injecté)
Pour la regul en sortie avec train de sinus fixe sur 990ms (du PWM a 1Hz), on ajuste % de temp ON et son complément OFF a chaque cycle
Le SSR avec sa gestion passage a zéro fera le reste (quand le gpio est a l'état 1, le SSR attend le prochain ZC pour commencer a conduire et quand le gpio repasse a l'état bas, le triac dans le SSR continu de conduire jusqu'au prochain changement d'alternance)
extraire ces parties de programme pour réduire drastiquement la taille du programme du RMS et que ça compile sur du UNO, c'est faisable (mais est ce que ça en vaut la peine ?)
Merci André  ,
Routeur V15.01 (since V2.01) / 1xESP32 (IP fixe) / Source UxI / 5 actions
Panneaux 1680Wc
1 Triac : ECS 2000W
1 SSR (multi) : ECS 1800W
1 SSR (On-Off) : Circulateur plancher chauffant eau 50W
1 SSR (multi) : circuit d'eau 1500W
1 SSR (multi) : Ultime 2000W
Messages : 7
Sujets : 1
Inscription : Aug 2025
Réputation :
0
Bonjour,
j'espère que mon message passera et que je n'aurais pas de retour négatif ...
(16-08-2025, 09:54 AM)michy a écrit : "mon ssr gère déjà le zéro cross, j’ai juste « normalement » à ajouter la détection de passage à zéro"
Si le SSR gère le ZC, c'est pas la peine de chercher à le récupérer aussi ...
est ce qu'on ne risque pas de louper des périodes si on ne détecte pas, pour se synchroniser en quelques sortes ?
voila un bout de mon code arduino :
Code : if (now - windowStart >= WINDOW_MS) {
windowStart += WINDOW_MS;
}
unsigned long onTime = (WINDOW_MS * (unsigned long)powerPercent) / 100;
if ((now - windowStart) < onTime) {
digitalWrite(SSR_PIN, HIGH); // cycles ON
} else {
digitalWrite(SSR_PIN, LOW); // cycles OFF
}
powerPercent est récupéré de mon application web qui sous API envoi le pourcentage à lancer.
Exemple :
Code : {"surplus_chauffeeau":100,"production":2.5,"consumption":0.4,"surplus":2.1}
code serveur qui permet de générer le pourcentage de la puissance à envoyer :
Code : /**
* Méthode qui renvoie le pourcentage du surplus par rapport à la puissance du chauffe eau
*
* @param float $production
* @param float $consumption
* @return int
*/
public static function estOKDeclenchementChauffeEau(float $production, float $consumption): int
{
// *** gestion données à 0
if($production <= 0 || $consumption <= 0){
return 0;
}
$surplus = round($production - $consumption,1);
// *** on produit plus qu'on consomme
if($surplus > 0){
// *** assez pour lancer le chauffe eau
if($surplus >= Site::$ChauffeEauSeuilDeclenchement) {
// *** on est entre la consommation et 100%
if($surplus <= Site::$ChauffeEauPuissance){
return round(($surplus / Site::$ChauffeEauPuissance) * 100);
} else {
// *** on est à au moins 100%
return 100;
}
} else {
// *** mais pas assez pour lancer le chauffe eau
return -99;
}
} else {
if($surplus <= Site::$ChauffeEauSeuilDeclenchementHaut*-1){
// *** on coupe car on dépasse la production + limite
return 0;
} else {
// *** on est dans la limite autorisé
return -99;
}
}
}
enfin :
(16-08-2025, 09:54 AM)michy a écrit : extraire ces parties de programme pour réduire drastiquement la taille du programme du RMS et que ça compile sur du UNO, c'est faisable (mais est ce que ça en vaut la peine ?)
je n'ai pas extrait de code du programme F1ATB, il me manquait quelques connaissances en "chauffe eau", j'ai juste récupéré la logique multi sinus expliqué sur ce site et avec l'aide de vos explications j'ai un peu réfléchi pour aboutir à un résultat satisfaisant. J'avais déjà conçu une application web pour suivre la production de mes panneaux + météo + stats.
Je trouve cela un peu plus gratifiant que d'acheter, copier coller un programme et faire 2-3 clics pour le configurer.
quand on est passionné d'électronique et ingénieur en développement de métier on essaie de créer les choses soit même et puis ça occupe pendant les vacances  .
Messages : 242
Sujets : 10
Inscription : Feb 2025
Réputation :
20
Faire soi-même est toujours plus gratifiant mais à un moment il faut être pragmatique, ca existe, pourquoi le réinventer ?
Pour ma part, je préfère copier et améliorer éventuellement, ou alors, si ca n'existe pas, le créer.
En ce qui concerne le routeur F1ATB, ce qui est intéressant c'est la multiplicité des options disponibles, ce qui demande un gros travail de développement et de tests. Ce forum permet de multiplier les tests et de proposer des améliorations souvent pertinentes.
C'est un peu comme avec les imprimantes 3D, sans la communauté, le travail aurait été pénible et surtout très long avant d'avoir des imprimantes 3D véritablement fiables.
Messages : 449
Sujets : 1
Inscription : Sep 2024
Réputation :
54
Tout seul on avance plus vite
Ensemble on avance plus loin
Messages : 131
Sujets : 0
Inscription : Jun 2024
Réputation :
5
Il y a 6 heures
(Modification du message : Il y a 6 heures par michy.)
(Hier, 02:08 PM)bkvin38 a écrit : Bonjour,
j'espère que mon message passera et que je n'aurais pas de retour négatif ...
(16-08-2025, 09:54 AM)michy a écrit : "mon ssr gère déjà le zéro cross, j’ai juste « normalement » à ajouter la détection de passage à zéro"
Si le SSR gère le ZC, c'est pas la peine de chercher à le récupérer aussi ...
est ce qu'on ne risque pas de louper des périodes si on ne détecte pas, pour se synchroniser en quelques sortes ?
voila un bout de mon code arduino :
Code : if (now - windowStart >= WINDOW_MS) {
windowStart += WINDOW_MS;
}
unsigned long onTime = (WINDOW_MS * (unsigned long)powerPercent) / 100;
if ((now - windowStart) < onTime) {
digitalWrite(SSR_PIN, HIGH); // cycles ON
} else {
digitalWrite(SSR_PIN, LOW); // cycles OFF
}
powerPercent est récupéré de mon application web qui sous API envoi le pourcentage à lancer.
Je trouve cela un peu plus gratifiant que d'acheter, copier coller un programme et faire 2-3 clics pour le configurer.
quand on est passionné d'électronique et ingénieur en développement de métier on essaie de créer les choses soit même et puis ça occupe pendant les vacances .
Bonjour,
tout refaire, ça part d'une bonne intention pour comprendre les fins rouage (j'approuve l'idée) / a voir vous avez déjà une base avec votre propre code
que souhaitez vous faire avec l'info ZC ? (1 signal ZC toutes les 10ms en 50Hz pour une régul on/off sur un cycle de 990ms, il n'y a pas de syncro a gérer, le SSR fera le job de manière transparente)
Dans le bout de code Arduino, la ligne " unsigned long onTime = (WINDOW_MS * (unsigned long)powerPercent) / 100;"
powerPercent est un nombre float entre 0.0 et 100.0?
WINDOW_MS est la base cycles haut/bas soit 990ms
comme vous recalculer onTime a chaque itération (pour actualiser l'état du gpio) , il faudrait pas que powerPercent change plusieurs fois de manière extrême pendant le cycle de 990ms
now c'est la fonction now() ou c'est une variable actualisée ailleurs?
Merci André  ,
Routeur V15.01 (since V2.01) / 1xESP32 (IP fixe) / Source UxI / 5 actions
Panneaux 1680Wc
1 Triac : ECS 2000W
1 SSR (multi) : ECS 1800W
1 SSR (On-Off) : Circulateur plancher chauffant eau 50W
1 SSR (multi) : circuit d'eau 1500W
1 SSR (multi) : Ultime 2000W
Messages : 7
Sujets : 1
Inscription : Aug 2025
Réputation :
0
Bonjour,
(Il y a 6 heures)michy a écrit : que souhaitez vous faire avec l'info ZC ? (1 signal ZC toutes les 10ms en 50Hz pour une régul on/off sur un cycle de 990ms, il n'y a pas de syncro a gérer, le SSR fera le job de manière transparente)
si je démarre un cycle de 990ms à 40%, je vais donc envoyer HIGH 396ms et donc quand je vais enclencher le HIGH si je ne le cale pas au début d'un cycle ZC je vais louper peut être une 1/2 période. Je me fais peut être des nœuds au cerveau ...
(Il y a 6 heures)michy a écrit : Dans le bout de code Arduino, la ligne " unsigned long onTime = (WINDOW_MS * (unsigned long)powerPercent) / 100;"
powerPercent est un nombre float entre 0.0 et 100.0?
j'envoie toujours un entier entre 0 et 100 sinon un -99 pour dire continue pas besoin de changer de %
(Il y a 6 heures)michy a écrit : comme vous recalculer onTime a chaque itération (pour actualiser l'état du gpio) , il faudrait pas que powerPercent change plusieurs fois de manière extrême pendant le cycle de 990ms
c'est géré côté serveur, avec le -99. Pour moi l'arduino ne fait que commandé on/off. Le serveur gère l'intelligence.
Code : public static function estOKDeclenchementChauffeEau(float $production, float $consumption): int
{
// *** gestion données à 0
if($production <= 0 || $consumption <= 0){
return 0;
}
$surplus = round($production - $consumption,1);
$percent = 0;
// *** on produit plus qu'on consomme
if($surplus > 0){
// *** assez pour lancer le chauffe eau
if($surplus >= Site::$ChauffeEauSeuilDeclenchement) {
// *** on est entre la consommation et 100%
if($surplus <= Site::$ChauffeEauPuissance){
$percent = round(($surplus / Site::$ChauffeEauPuissance) * 100);
} else {
// *** on est à au moins 100%
$percent = 100;
}
} else {
// *** mais pas assez pour lancer le chauffe eau
$percent = -99;
}
} else {
if($surplus <= Site::$ChauffeEauSeuilDeclenchementHaut*-1){
// *** on coupe car on dépasse la production + limite
$percent = 0;
} else {
// *** on est dans la limite autorisé
$percent = -99;
}
}
// *** on ne prend que 90% de la valeur
if($percent > 0){
$percent = $percent * 0.9;
}
return $percent;
}
(Il y a 6 heures)michy a écrit : now c'est la fonction now() ou c'est une variable actualisée ailleurs?
c'est la fonction millis() appelé à chaque début loop
Code : void loop() {
unsigned long now = millis();
if (now - lastApiCall >= API_INTERVAL) {
lastApiCall = now;
if (client.connect(server, serverPort)) {
// Envoi de la requête HTTP GET
client.print(String("GET ") + apiPath + " HTTP/1.1\r\n" +
"Host: " + ipToString(server) + "\r\n" +
"Connection: close\r\n\r\n");
} else {
Serial.println("Connexion échouée");
}
// Attente de la réponse
String payload = "";
while (client.connected() || client.available()) {
if (client.available()) {
char c = client.read();
payload += c;
}
}
client.stop();
// Extraction du JSON (dans le corps HTTP)
int jsonStart = payload.indexOf("{");
if (jsonStart >= 0) {
String jsonString = payload.substring(jsonStart);
Serial.println("Réponse API : " + jsonString);
StaticJsonDocument<200> doc;
DeserializationError err = deserializeJson(doc, jsonString);
if (!err) {
int val = doc["surplus_chauffeeau"];
if (val >= 0 && val <= 100) {
powerPercent = val;
Serial.print("Nouveau powerPercent = ");
Serial.println(powerPercent);
}
} else {
Serial.println("Erreur parsing JSON");
}
}
}
if (now - windowStart >= WINDOW_MS) {
windowStart += WINDOW_MS;
}
unsigned long onTime = (WINDOW_MS * (unsigned long)powerPercent) / 100;
if ((now - windowStart) < onTime) {
digitalWrite(SSR_PIN, HIGH); // cycles ON
} else {
digitalWrite(SSR_PIN, LOW); // cycles OFF
}
}
|