Serveur relais interactif ( volets roulants + arrosage )

Bonsoir , voila un serveur interactif de relais qui peut supporter jusqu ' a 200 relais commandé par internet en local ou de l' exterieur ( avec DNS ou IP fixe externe ) .

Je tiens a preciser que le code principal n ' est pas de moi , c ' est notre ami J-M-L qui l ' a gracieusement mis a disposition dans son tuto de serveur web interactif sur le forum .

Moi je n ' ai qu ' ajouter la partie pour gerer les relais et adapter le code principal pour arduino mega 2560 avec shield ethernet 2 a base de chipset wiznet 5500 autant dire pas grand chose :grin: puisque J-M-L avait deja pratiquement tout codé ^^ il m ' aurait fallu que 4 ou 5 ans pour arriver a refaire ce genre de chose ...
Le code est en Piece Jointe a la fin du post mais il ne comprend pas la prise en charge des 74HC95 .( peut gerer avec quelques modifs 60 relais , sans modification 46 relais )

En tout cas un grand merci pour votre tuto qui va pouvoir me regaler et avec je vais pouvoir domotiser ma maison et epater la galerie :grinning:

EDIT et modifs :

  • ajout de la prise en compte de l' acces internet
  • possibilité de fonctionner en IP fixe / DHCP
  • ajout de la RTC DS1307
  • ajout capteur humidité du sol
  • ajout detecteur de pluie
  • ajout de la mise a l' heure automatique de la RTC par serveur NTP via UDP
  • ajout de gestion d ' ouverture fermeture portail coulissant a contact sec
  • ajout de la gestion de relais heures creuses
  • ajout de la gestion automatique de l ' arrosage a intervalles reguliers en fonction des saisons et des zones
  • modification de la gestion des Timers , suppression de MSTimer2 remplacer par la bibliotheque de @J-M-L => AsyncTask qui permet une gestion par ID plus fine
  • ajout dans le code d ' un debug et test desactivable pour faciliter les modifs possibles ulterieures
  • reorganisation du code par categorie de fonction
  • correction de bugs

capture du serveur :

mise a jour du code en PJ + ajout de la bibliotheque de @ J-M-L.

pour la bibliotheque simpleRTC de @bricoleau , se rendre sur le post dedié : [partage]Librairie simpleRTC (DS1307 / DS3231) avec heures été/hiver - Tutoriels et cours - Arduino Forum

AsyncTask.h (3.87 KB)

serveur_volet_arrosage_V_A_P_R_IA_RTC_NTP.UDP_6.302.ino (49.6 KB)

Ethernet2-1.0.4.zip (64.4 KB)

Merci pour le partage

Je jetterais un œil un peu plus approfondi dessus mais je suggèrerai de

  • ne pas mettre 2000 pour le nombre de relais dans le code de demo vu qu'il ne gère pas le contrôle des pins autres que celles existantes et que ça prend beaucoup de mémoire pour rien donc

  • comme votre code n'écoutera que des requêtes pour les relais vous pouvez changer const char * labelsOfInterest[] = {"LED", "V", "W", "R"}; parconst char * labelsOfInterest[] = {"R"}; puisque rien d'autre ne devrait être envoyé par la page web et donc pas la peine non plus d'avoir des variables long V = 0, W = 0; juste la variable R serait nécessaire sans doute et bien sûr enlever dans la page web V,W, et la led

  • vous avez commenté// cause erreur IDE    int commandLength = strlen(urlCommand); en effet c'est une variable que je n'utilise pas dans cette fonction, ce n'est pas une erreur dans l'IDE juste un warning qui dit que le compilateur en fait va virer cela pour vous :slight_smile: mais effectivement autant le commenter

Bonjour , j ' ai passé a 16 le nombre relais , uniformiser l ' ecriture des constantes en maj , et fais les corrections que vous avez demandés .

Il reste que j ' ai oublié la fonction de reset des relais ... que je ferais un peu plus tard .

et du coup bien sur , j ' ai re-edité le fichier piece jointe .

Edit : pas trouvé mieux pour reset la configuration des relais ...

Mise a jour de la piece jointe .

Bonjour,
J'utiliserais votre programme pour conduire des volets roulants. Est-il possible avec une minuterie de varier la durée de la mise en service des relais?

Bonjour

Ne perds pas de vue que la principale difficulté technique d'un tel projet, réside dans la maîtrise des aspects purement électriques.

Arduino + relais = courants faibles + courants forts

Sur le plan purement logiciel, piloter n sorties de l'arduino n'est pas le plus dur.
Par contre, assurer derrière une parfaite isolation et indépendance des circuits, une alimentation des relais dont la puissance doit être correctement dimensionnée, sans parasites qui remontent depuis les circuits de puissance vers l'arduino, ça c'est le plus délicat.

Par ailleurs, il faut absolument rappeler en permanence que jouer avec des courants forts est potentiellement dangereux. Pas question d'avoir des montages approximatifs en aval de l'arduino.

Tu trouveras par exemple sur le forum des écrits très précis de pepe sur ces sujets

Titof2375:
Bonjour,
J'utiliserais votre programme pour conduire des volets roulants. Est-il possible avec une minuterie de varier la durée de la mise en service des relais?

Bonjour oui bien sur , grace a la fonction millis () ou bien une biliotheque doit exister me semble t il .

Il est evident que le 220 Volts presente des risques importants , il faut faire ses branchements soigneusement , dans des boitiers electriques completements isolés et en ayant coupé le courant bien entendu .

Si vous utilisez millis pour attendre ou delay ça va empêcher d'écouter le web... faut une machine à état

Bonjour ,

Depuis j ' ai amelioré le serveur , plus specialisé pour les volets roulants .

Gestion DHCP / IP fixe

j ' y ai ajouté une minuterie non bloquante et auto reinitialisée , mais sans faire de machine a etat ( ou alors je ne suis pas au couant :slight_smile: )
j ' ai aussi ajouté une fonction qui permet d' arreter les volets quand on le desire pendant la montée ou la descente .
j ' ai ajouté quelques options de securité : une delai entre la montée et la descente et l' inverse .

une fonction qui empeche de commuter en meme temps la montée et la descente .

et deux 3 autres bricoles dont je ne me souviens plus .

Code amelioré en piece jointe .

serveur_volets_uni.ino.ino (18.6 KB)

Merci iznobe
J'aimerais en savoir plus sur la manière de brancher le relais sur le volet roulant. Et comment est gérée la fin de course en montée et en descente.

Salut ,

si on part avec 8 volets , il faut 16 relais . constante a modifier dans le code .

les 8 premiers relais sont pour la montée , et les 8 autres pour la descente .

il suffit de cabler les moteurs avec le fil de montée sur le relais avec la phase en NO .
le fil de descente sur le relais avec la phase en NO .

Chez moi la butée est gerée par le moteur en interne , y a un reglage .

le timer permet de s ' assurer d' arriver en butée , j' ai pris le temps que mettait le volet le plus long a se fermer et j ' ai rajouté 2 secondes , ce qui me fait 30 sec ( on peut facilement modifier dans le code , juste une variable )

le bouton stop , reset le timer en cours , et bien sur arrete le volet a l ' endroit desiré .

rien de tres compliqué :-[

Par contre , il faut finir de nettoyer le code , il ya des fonctions et des variables inutiles pour les volets roulants ..

j ' editerai plus propre des que j' ai un peu de temps .

Re-salut ,

voici donc le code nettoyé en PJ j ' ai enlever certaines variables qui me servait a autre chose , capteurs etc .

je n' ai pas teste ce code car pas envie de demonter pour tester .

si il n ' est pas fonctionnel n ' hesiter pas a me le signaler .

toutes suggestions d' amelioration sont les bienvenues .

serveur_volets_uni.ino.ino (17.5 KB)

Salut ,

@J-M-L , si vous passez par là , j ' aurais besoin d' aide sur un probleme au niveau du serveur en lui meme .

voici le probleme :

lorsque ma femme ouvre ou ferme les volets avec son telephone , bien sur elle ne ferme pas la page ni ne l' actualise .

Du coup lorsqu ' elle revient dessus pour fermer ou ouvrir , la " requete est deja lancé " j 'entends par là que l' adresse est par exemple : mon_ip/R=1 , et bien sur l ' arduino prend en compte la commande ...

quelle serait la solution la plus " propre " pour resoudre cette problematique .

j ' ai pensé a ajouter par exemple POST dans les boutons actions et verifier qu il y a bien POST avant de faire une action tout simplement , mais je ne suis pas certain que ca soit tres propre , ca fait penser a du PHP :smiley:

mais du coup je n' aurais que quelques modifications mineures a apporter a 3 ou 4 fonctions dans le code en PJ .

Je ne suis meme pas certain que ca marchera , car l ' adresse sera encore certainement conservé dans la barre du navigateur ...

Note : le " refresh = xx " ne fonctionne pas chez moi .

bref toutes les idees a exploiter sur ce probleme sont bonnes a prendre , merci pour votre aide .

serveur_volet-V5.test.ino.ino (20.4 KB)

quelle serait la solution la plus " propre " pour resoudre cette problematique .

être galant et ne pas laisser votre femme fermer les volets et le faire vous même :slight_smile:

Oui quand on utilise l'URL pour passer des commandes ça peut conduire à des soucis puisque le navigateur reste sur cette URL.

Un moyen à explorer serait de faire un HTTP redirect ou un element avec son attribut http-equiv mis à Refresh dans le de la page --> quand la page s'affiche le browser ira à l'URL indiquée

<head> 
  <meta http-equiv="Refresh" content="0; URL=https://monAdresse/">
</head>

pour que le navigateur change son URL à la page d'accueil du site

J-M-L:
être galant et ne pas laisser votre femme fermer les volets et le faire vous même :slight_smile:

:smiley: , je suis galant ( enfin ca m ' arrive ) , mais parfois , simplement absent ^^ !

J-M-L:
Oui quand on utilise l'URL pour passer des commandes ça peut conduire à des soucis puisque le navigateur reste sur cette URL.

Un moyen à explorer serait de faire un HTTP redirect ou un element avec son attribut http-equiv mis à Refresh dans le de la page --> quand la page s'affiche le browser ira à l'URL indiquée

<head> 

> ``` > > > pour que le navigateur change son URL à la page d'accueil du site

merci pour l ' info . j ' ai modifié mon code , mais pas encore teste .

Salut ,
j ' ai teste , le code de refraichissement , firefox bloque le rafraichissement automatique .

mais bon le probleme n ' est pas la .

ca ne respecte pas le temps donné dans le code HTML et ca ne change pas l' adresse .

du coup ca ne correspond pas a ce que je cherche a faire .

j ' ai modifié le serveur de façon a gerer 6 zones d' arrosage distinctes .

le code n' est pas terminé , il faut encore que j ' ajoute un RTC de façon a pouvoir gerer cela hebdomadairement et par saison .

les commandes manuelles de l' arrosage du serveur sont fonctionnelles ainsi que le capteur de pluie et d' humidité du sol , afin de n ' arroser que quand c ' est necessaire . pour le moment la gestion automatique de l ' arrosage et hebdo ne sont pas implementés .

le code est en PJ pour ceux que ca interrresse :slight_smile:

PS : je ne sais pas qui a telecharge le fichier joint , mais il y avait une erreur ou 2 que j' ai corrigé avec le nouveau fichier .
desolé , j ' en ai profité pour simplifier l ' ecriture du code et ameliorer les fonctions de gestion des relais .

serveur_volet-V6.test.ino.ino (24.4 KB)

Salut ,

Bon je me rapproche d ' une solution finale exploitable .

Cependant , j ' ai plusieurs petits problemes .

le premier l ' IDE arduino , me renvoie pas mal de warning et d' erreurs a la compilation de mon code , je n ' ai pas trouvé de solutions pour les corriger .

2°) pour l' arrosage autonome j ' emet des reserves car je ne suis pas encore sur que ca soit vraiment fonctionnel a 100 % cependant ca en l ' air , bien qu ' il y aura certainement des modifications a faire sur ce premier jet .

je poste en PJ le code pret a etre tester , la partie nouvelle correspondant a l' arrosage se trouve en bas .

je sais que J-M-L suit un peu l ' evolution du code , si a un moment tu as un peu de temps pour jeter un oeil et me dire ce qui peut etre amelioré , doit etre modifié , ou des suggestions .

si d' autres personnes ont aussi des remarques , ou des modifs en vue , n ' hesitez pas :slight_smile:

Merci

serveur_volet_arrosage_RTC.v6.1.ino (29 KB)

quelques commentaires:

essayez de conserver une cohérence dans les noms de variables:

SDCARD_PIN
Pluie_sensor_pin
Pluie_sensor_vcc

--> par exemple

SdCard_pin
capteurPluie_pin
capteurPluieVcc_pin

(idem pour les autres)

pourquoi mettre des Strings ?
const String tableauDeNoms [ (( RELAY_NUMBER_V / 2 ) + RELAY_NUMBER_A ) ] = {"Cuisine", "Sa manger", "Salon", "Salle TV", "Ch Lucie", "Ch parents", "S.D.Bains", "Bureau", "Arbres", "Bordures", "Fruitiers", "Haies", "Jardin", "Potager"};autant mettreconst char* tableauDeNoms [] = {"Cuisine", "Sa manger", "Salon", "Salle TV", "Ch Lucie", "Ch parents", "S.D.Bains", "Bureau", "Arbres", "Bordures", "Fruitiers", "Haies", "Jardin", "Potager"};

un byte est un entier non signé (toujours positif) sur 8 bits. Vous ne pouvez donc pas écrire  byte x = -1;Comme vous l'initialiserez toujours dans cette fonction, un byte x;va suffire

quand vous faites    reInitRelaisTable (calculPinInverse(0) , calculPinInverse(RELAY_NUMBER_V / 2)); // on re-initialise tous les pins de volets inverseou    reInitRelaisTable (calculPinInverse(RELAY_NUMBER_V / 2) , calculPinInverse(RELAY_NUMBER_V)); // on re-initialise les pins des volets inversepourquoi passer par calculPinInverse puisque vous avez des constantes, vous pouvez facilement mettre en dur l'inverse, non ? (par exemple on sait que calculPinInverse(0) c'est toujours RELAY_NUMBER_V / 2 )

Vous utilisez d'ailleurs bcp ce (RELAY_NUMBER_V / 2) --> mettez le dans une constante

vous ne pouvez pas comparer une adresse IP comme cela:  if ( ip != (0, 0, 0, 0) ) { // demarrage du shield en IP staticvous devez comparer deux instance de type IPAddress

IPAddress ipNulle(0, 0, 0, 0);
...
  if (ip == ipNulle) {...}

Ne déclarez pas la mac Adresse en const, ça enlèvera le warning associé

si vous ne voulez pas le warning du paramètre non utilisé, déclarez vos fonctions comme cela avec __attribute__((unused))

void BALCorps (EthernetClient& client __attribute__((unused))) {
}

void portailCorps (EthernetClient& client __attribute__((unused))) {
}

ne déclarez pas  char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};maisconst  char* daysOfTheWeek[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

Vous avez des noms de jours qui sont poétiques dans vos commentaires d'ailleurs        switch (now.dayOfTheWeek()) { // Arbres= 0, Bordures = 1, Fruitiers = 2, Haies = 3, Jardin = 4, Potager = 5 .

ça c'est du test :wink:

  if ( now.hour() == now.hour() ) { // pour tester seulement

Merci pour votre retour avisé et votre aide !

Grace a vos conseils , j ' ai pu corrigé les warnings et bugs ( pour les unsued , ils seront bientot used XD ) donc pas touché

J-M-L:
Vous avez des noms de jours qui sont poétiques dans vos commentaires d'ailleurs

        switch (now.dayOfTheWeek()) { // Arbres= 0, Bordures = 1, Fruitiers = 2, Haies = 3, Jardin = 4, Potager = 5 .

ça c'est du test :wink:

  if ( now.hour() == now.hour() ) { // pour tester seulement

Sur la fin , ca devient parfois difficile d' y voir bien clair :stuck_out_tongue: ca a sauté une paire de lignes lol .

pour ce qui est du test , mon imagination debordante :stuck_out_tongue: ( et surtout ma faignantise ) ce sont exprimés , j ' ai mis ca parceque c' etait deja dans le presse papier :smiley: !

Apres avoir apporté vos modifs ( sauf celle de DayOfTheweek , qui renvoie une erreur , ca m ' a permis d ' economiser 8 % de memoire !! :sunglasses:

en tout cas ca fait plaisir d' avoir un code ( pratiquement ) sans erreur !! ;D
Grand Merci !

serveur_volet_arrosage_RTC.v6.1.ino (29.5 KB)

sauf celle de DayOfTheweek , qui renvoie une erreur

quelle erreur ? y'a pas de raison ! (ou alors vous avez les 2 paires de crochets)

oui comme un tableau a 2 dimensions :

char daysOfTheWeek[7][12] = ....

pour les deux dernieres fonctions d' arrosage nouvellement crées , cela vous parait coherent ? au niveau de l ' automatisme de la chose ?

ou il y a mieux a faire par exemple avec le TimeSpan de la bibliotheque RTC a la place de millis et chrono ?

ou dans le cheminement , la mise en place etc ...