Projet : Serveur domotique a ameliorer .

Bonjour je sais bien qu il existe deja pas mal de code sur ce sujet sur le net , mais pas jusqu ' a 9999 :slight_smile:

j ' ai pris des bases de code un peu partout mais principalement sur le site du zero ( openclassroom ) et ici meme ( d' ailleurs je remerci ceux qui m ' ont apporté leur aide ) pour faire une esquisse de pilotage de relais sur base serveur a partir d' un mega 2560 + shield ethernet ( wiznet 5500 ) .

Ca marche actuellement pas sur tous les navigateurs ( je ne peux pas tester IE ) .

je met a disposition le code que j ' ai pondu afin de l ' ameliorer car je sais que je suis tres mauvais en C C# et C ++ et qu il y a de tres bon programmeur qui pourront donc faire evoluer ce code .

Pour le moment je ne me suis pas pencher sur un bus I2C ou une matrice + 74HC595 , je ne sais meme pas ce qu il est possible de faire .

la limite actuelle est donc la limite physique des pins du mega 2560 soit un peu plus de 50 relais pilotable sur une page web .

j ' espere pouvoir ameliorer la rapidité ,ainsi que les fonctionalités de ce code pour la communauté .

De mon coté 50 relais me suffisent et je sais pertinemment qu il est possible d ' heberger la partie fichier serveur sur la carte SD , je m ' y pencherais un peu plus tard quand le code sera fonctionnel avec tous les navigateurs .
( je n ' ai pas implementer de CSS , la partie utile m ' importe plus que le style )

Il est aussi possible de piloter d' autres choses facilement par le meme biais , il est d' ailleurs prevu une partie a cet effet .

Le top serait d' amener ce projet sur le rang d ' un serveur domotique a long therme , toute aide , remarques objectives , conseils sont les bienvenus !

voici donc le code en piece jointe , soyez indulgent svp , c ' est mon premier programme en C ...

PS j ' ai remarqué qu ' en sortie de fonction decodage , la valeur est bonne , mais en entrée de la fonction gestionRelais elle ne l ' est plus , pourtant elle est juste transmise de l ' une a l ' autre sans aucune action ...
Si une personne arrive a m ' expliquer pourquoi je suis preneur .

test_relais_reseau.ino (11.6 KB)

Bonjour

Merci de la contribution - elle serait sans doute mieux dans les Réalisation et Projets finis

Si je peux me permettre quelques remarques constructives

quand vous donnez du code faites l'effort

  • de l'indenter correctement (ctrl-T dans l'IDE)
  • de virer toutes les sections qui sont en commentaires, on s'y perd et elles ne servent à rien
  • quand vous mettez des commentaires assurez vous qu'ils soient pertinents
    (genre case '0':// on teste si le code est 'a')
  • Il vaudrait mieux aussi tout ré-écrire en n'utilisant pas la classe String pour la stabilité

Là je ne peux pas vraiment lire le code sur mon tel...

Bonsoir et merci pour vos remarques , je ne code pas avec l ' ide arduino mais avec notepad QQ , mrci pour l ' indentation ( meme si c ' est l ' arduino qui me desindente tout ... ) je vais tester cela .

les sections en commentaire , sont ( generalement ) d ' autres façons d' arriver au meme resultat , bien qu ' un nettoyage est indispensable effectivement :slight_smile: .

pour le string , je ne suis pas arrivé sans , dsl ( probleme de conversion a priori ) .

quand a poster cela dans la section fini , je ne pense pas que ce soit necessaire actuellement .

il reste trop de modifications et ameliorations avant comme vous l ' avez dit .

J ' ai vu dans l ' IDE qu on pouvait utiliser un editeur externe .
vous avez testé cela ? sous quelle condition , comment choisir celui que l ' on desire ?

voila j ' ai nettoyé vaguement le code , et mis des commentaires qui expliquent pourquoi j ' ai laissé les grosses sections en com .

Sachant que generalement ce sont des parties pour justement eviter les " String " , sauf que a la fin impossible de transmettre l ' info dans la fonction suivante , meme avec un tableau specialement créer pour l ' occasion , j ' ai du zapper un truc ...

du coup je vais mettre a jour la piece jointe dans le 1er post .

OK j'ai jeté un oeil rapidement, il faut vraiment du nettoyage... mais il faut bien commencer quelque part - donc continuez

Quelques commentaires:

  • la partie qui reçoit l'information d'internet n'est pas "bonne" en théorie: vous dépendez d'un "delay(1)" plus ou moins aléatoire pour vous assurer d'avoir lu toute la requête HTTP. c'est assez arbitraire, d'une part vous allez grandement ralentir le code avec 1ms d'attente par caractère, et au pire potentiellement saturer et dépasser la taille mémoire du buffer ethernet si vous attendez trop... De plus vous allouez plein de mémoire pour stocker toute la réponse HTTP alors que la seule partie qui vous intéresse est après le ? --> il faut lire et parser au fur et à mesure ou ligne par ligne jusqu'à recevoir une ligne vide après un retour charriot

--> vous pouvez vous inspirer d'un petit tuto que j'avais écrit et de la fonction handleClient() et vous verrez au passage comment ne pas utiliser la classe String et il y a aussi une fonction parseCommand() qui sait gérer plusieurs attributs dans l'URL genre lire les valeurs v1, v2 et v3 pour x, y et z dans une requête http://domain.com/x=v1,y=v2,z=v3. ça vous donnera des idées sur comment écrire un parser sans faire tous les calculs compliqués que vous effectuez

  • Pour gagner en mémoire RAM, partout où vous avez des affichage de chaînes statiques, passez en chaînes stockée en mémoire flash --> par exemple au lieu de
  //infos pour le navigateur
  cl.println("HTTP/1.1 200 OK"); // type du HTML
  cl.println("Content-Type: text/html; charset=ascii"); //type de fichier et encodage des caractères
  cl.println("Connection: close");  // fermeture de la connexion quand toute la réponse sera envoyée
  cl.println();
  //balises d'entête
  cl.println("<!DOCTYPE HTML>");
  cl.println("<html>");
  cl.println("<head><title>Relais</title></head>");
  cl.println("<body><h1>Relais</h1><hr>
");

préférez

  //infos pour le navigateur
  cl.println(F("HTTP/1.1 200 OK")); // type du HTML
  cl.println(F("Content-Type: text/html; charset=ascii")); //type de fichier et encodage des caractères
  cl.println(F("Connection: close"));  // fermeture de la connexion quand toute la réponse sera envoyée
  cl.println();
  //balises d'entête
  cl.println(F("<!DOCTYPE HTML>"));
  cl.println(F("<html>"));
  cl.println(F("<head><title>Relais</title></head>"));
  cl.println(F("<body><h1>Relais</h1><hr>
"));

Pour éviter de saturer le tas (heap) avec des demandes sur la classe String (allocation mémoire, désallocation etc), au lieu de faire

    //<a href="?r4" target="_self"> OFF </a>
    cl.println("
Relais numero " + String(i) + " <a href=\"?r" + String(i) + "\" target=_self >");
    if (tableau_Etat_Relais [i]) { //si état sur 1
      cl.print("ON ");
    }
    else { // sinon
      cl.print("OFF ");
    }
    cl.println("</a>");//fin du lien

découpez en petits bouts votre affichage

  for ( int i = 0; i < nombre_De_Relais; i++ ) {
    //<a href="?r4" target="_self"> OFF </a>
    cl.print(F("
Relais numero "));
    cl.print(i);
    cl.print(F(" <a href=\"?r"));
    cl.print(i);
    cl.println(F("\" target=_self >"));
    cl.print(tableau_Etat_Relais [i] == HIGH ? F("ON ") : F("OFF ")); // déclarez le tableau en byte et mettez des HIGH et LOW plutôt que des 1 et 0
    cl.println(F("</a>"));//fin du lien
  } // fin de boucle

bref - jetez un petit coup d'oeil à mon exemple (sans prétention) ça devrait vous aider

Bonjour , ouah c ' est enorme le gain de place en memoire , je suis passé de 26 % a 14 % maintenant !!!

Merci beaucoup pour les conseils .

je suis allé voir vite fait carr pas eu le temps d' approfondir pour le moment votre lien ( je vous remercie au passage pour le partage et le lien ) .

Je vais etudier cela de pres , merci a vous !

Bonjour , bonjour !

Effectivement votre exemple parait bien plus pratique , cependant plusieurs questions .

la premiere , je n' arrive pas a me connecter une fois uploadé , et il n ' y a pas d' adresse ip fixe a entrer nulle part ...( ca marche en DHCP , ca ok , enfin cencé , puisque ca ne marche pas chez moi )

commentpuis je voir et / ou apprecier le resultat ?

  1. le parser peut il capter une commande du style " GET /?R=999 " ? ou le max sera 99 ? ( pas trop compris le parser , faut que je me penche plus en detail dessus , je manque un peu de temps en ce moment ( et de connaissance , je ne connais pas la moitié des fonctions utilisées )...

on peut facilement rajouter le R dans : const char * labelsOfInterest[] = {"LED", "V", "W", "R"};

et ajouter un case 3: // R
R += labelValue;
break;

Mise a jour du code et nettoyage , suppression de pas mal de String .

Reste cependant , ce qui me semblerait etre un depassement memoire a partir de 21 relais que je n ' avais pas auparavant ... avec 20 relais max , ca marche au poil .