Aquaboun's /// gestion d'aquarium recifal

Le AT+RST est envoyé sans doute à l’initialisation, donc pas la peine à mon avis (à vérifier dans le code source). le reset hardware est physique, ça veut dire que si pour une raison quelconque l’interpretteur De commandes AT ne répond pas ça force un vrai reset matériel

Pourquoi pas de pin reset? vous n’en n’avez plus de dispo?

Pour les pin dispo j'attend de recevoir mon dernier CI pour vérifier que les 7pin mentionné plus haut, normalement pris par l’écran son dispo.
sinon, non plus de dispo :confused:

Pour le reset physique ... j'utilise un adaptateur

Ah c'est un adaptateur qui n'expose pas toutes les pins... il en existe d'autres qui sont plus complets

i2.png

i1.png

mais vous pouvez toujours attaquer directement la pin RST du ESP-01 (avec un pont diviseur de tension pour passer en 3.3V)

Je vais faire plus simple, je vais souder le pin reset dans l'autre sens pour qu'il ne soit pas sur l'adaptateur :slight_smile:

pin rst Ok,
Bon je lit des poste sur le net mais affecter les boutons a des fonction (et je ne parle pas de la sauvegarde) a l'air hard core et ça m’inquiète beaucoup ... surtout que je ne trouve rien de tres bien expliquer, enfin, surtout compréhensible pour moi :slight_smile:

bon 4h a lire tout se que je trouve en cherchant "arduino html bouton" et rien de concluant.
La plus par des exemple trouvé me font par exemple "http://192.*****/mavariable=1" et donc page d'erreur.

djbouns:
Je doit a présent affecté les bouton a une fonction et sauvegarder ... connaissez vous un tuto bien fait a lire ?

Si vous regardez mon tuto sur le shield ethernet vous verrez comment je propose une approche relativement simple pour cela et le code HTML de base pour un bouton.

L’idée c’est que la page principale soit générée par http://adresse.ip et les boutons dans le code html sont définis et appellent le site principal mais avec une url différente

http://adresse.ip/param<ici des paramètres>

Vous avez vu ci dessus que l’on est capable de savoir quelle resource est demandée (/ pour la page principale, /admin pour la page d’admin) et là il faut soit que chaque bouton ait son url, soit aller un cran plus loin et passer des paramètres que votre fonction va analyser pour déterminer quoi faire

Vous verrez que cette approche simple a été reprise dans cet exemple (serveur interactif de relais qui peut supporter jusqu ' a 2000 relais commandé par internet) qui au final n’est pas loin de ce que vous faites

Après on peut faire plus compliqué avec de l’ajax, des requêtes de type POST etc, mais je pense que ça va dépasser vos compétences et besoins

Merci, je lit et essai de comprendre et d'adapter et je revient ... dans une semaine :slight_smile: :slight_smile: :slight_smile:

alors, le code avec les relais ne me correspond pas trop puisque il ne fait que duplique une même fonction ON/OFF selon une suite de déterminé de boutonx=PINx ect...
j'ai compris le principe du bouton qui complète l'url.
Le code du tuto correspondrait a mes besoin puisque il ajoute ou diminue des valeurs mais j'ai un problème de compréhension même si j'ai compris le principe.

J'ai don testé la chose , simpliste, suivante :
Sur ma page principale :
client.print(F("<button onclick="location.href='/V=1'" type='button'>sfgqrg"));
puis
else if (!strcmp(urlRequest, "/V=1")) {
test = test +1;
}
Le positif est que ma variable test est bien modifié a +1
Le problème c'est le retour aussi tôt a la page principal ...
J'ai tenté un return lol sa aurais été trop simple :slight_smile:

Je continu ma croisade ...

Il faut régénérer la page totale

J-M-L:
Il faut régénérer la page totale

on est bien d'accord

j'ai tenté urlRequest == "/";

avec ce que j'ai vu sur le net,
client.print("location.href='/'");
devrait marché :frowning:

J'ai trouvé ca qui marche, que je trouve assez simple mais il faut attendre plusieurs seconde entre chaque click sinon sa marche pas :frowning:
une idée pourquoi si long ?

client.println("<button onClick=location.href='./?LED=ON'>ON");

et dans le loop

cadena.concat(c);

int posicion=cadena.indexOf("LED=");
if(cadena.substring(posicion)=="LED=ON")
{
test = test +1;
}

Que me conseille tu ? cette méthode est bonne et peut être adapter a tout mes nombreux bouton ou faut il que je creuse sur ton code, il ne me manque que le retour a la page après le clic ... et vu ton niveau, je pencherais pour ton code :slight_smile:

la librairie n'est pas top pour plusieurs requêtes trop rapide en provenance du même navigateur et l'ESP-01 a ses propres contraintes aussi de ce côté là - un shield ethernet ou une carte wifi de plus haut niveau est bien utile si vous voulez plus de robustesse .

Sinon vous retombez dans l'usage de la classe String... pas bon...

avecclient.println("<button onClick=location.href='./?LED=ON'>ON</button>");

l'URL va être capturée par mon code du post #6 quand la loop appelle la fonction:

envoyerPageWeb(WiFiEspClient &client, const char * urlRequest)

la variable urlRequest vaudra alors "/?LED=ON" vous pouvez regardez dans mon autre tuto comment on analyse proprement cette requête si vous voulez de la dynamité (LED qui peut être autre chose et ON aussi) ou si vous avez peu de boutons faire comme dans mon code ci dessus en comparant la requête reçue avec "/" ou "/admin" --> tester avec "/?LED=ON"

si vous retournez toujours la même page web après modif éventuellement de certains param lors de la requête il suffit de modifier un peu la fonction pour d'abord tester l'URL et faire les modifs puis ensuite balancer la page

void envoyerPageWeb(WiFiEspClient &client, const char * urlRequest)
{
  static int reqCount = 0;

  // ************* ICI TESTER L'URL RECUE POUR DECIDER QUOI FAIRE *************
  if (!strcmp(urlRequest, "/")) {  // page de base
     reqCount = 0; // par exemple une requête sur la home page remet à 0 le compteur du serveur
  } else if (!strcmp(urlRequest, "/?LED=ON")) {  // requête d'un bouton
     reqCount++; // par exemple on modifie une variable utilisée plus tard dans la page
  } else if (!strcmp(urlRequest, "/?LED=OFF")) {  // requête d'un bouton
     reqCount--;  // par exemple on modifie une variable utilisée plus tard dans la page
  } 

  // **********************************************************************

  // puis on génère la page qui va bien
  // On envoie un en tête de réponse HTTP standard  client.print(
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Connection: close\r\n" // la connexion sera close par le navigateur à la fin de la réponse
    "\r\n");                // une ligne vide marque la fin du header HTTP
  client.print(F("<!DOCTYPE HTML>\r\n"));
  client.print(F("<html><head>\r\n"));
  client.print(F("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\r\n"));
  client.print(F("<title>AQUABOUN</title>\r\n"));

    // On envoie la page web
  client.print(F("<style type=\"text/css\">\r\n"));
  client.print(F("body {background-color: #00979c}\r\n")); // couleur arduino
  client.print(F("</style></head>\r\n"));
  client.print(F("<body>\r\n"));
  client.print(F("<h1>Salut djbouns !</h1>\r\n"));
  client.print(F("Nb de demandes ="));
  client.print(reqCount);
  client.print(F("
\r\n"));
  client.print(F("Valeur lue sur A0: "));
  client.print(analogRead(0));
  client.print(F("
\r\n"));
  client.print(F("</body>"));
  client.print(F("</html>\r\n"));

  // un peu d'attente pour que le module ESP ait fini de tout envoyer
  delay(10);
}

pour tester même s'il n'y a pas de boutons dans la page générée, vous pouvez taper directement dans la barre d'adresse du navigateur http://<ip>/?LED=ON ou http://<ip>/?LED=OFF et vous allez voir la variable s'incrémenter ou se décrémenter

OK ?

Bonjour à toutes et à tous,

Ayant un peu galéré sur le sujet avant d'arriver à quelque chose de cohérent et qui marche, je me permets d'intervenir sur la façon de faire générer une requête à un navigateur...

Regardons cela sur un exemple, une page et la requête que le navigateur génère quand on clique sur un bouton après avoir rempli les champs de saisie. Le code complet de la page est en PJ.

La requête est une GET, la plus employée, qui ressemble à cela, aux variations de navigateur près:

GET /BTS10.htm?T80=admin&T81=pass&N01=01 HTTP/1.1
Host: 192.168.1.236
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.236/BTS10.htm?T80=&T81=&N01=01
Connection: keep-alive
Upgrade-Insecure-Requests: 1

Cette requête demande une ressource (URI) dont l'identification complète est :
192.168.1.236/BTS10.htm?T80=admin&T81=pass&N01=01
Il y a 3 parties:

  • un site "192.168.1.236", ici identifié par une adresse IP. Le navigateur la place dans la ligne "Host".
  • une page "BTS10.htm" située à la racine du site,
  • des informations passées au serveur pour qu'il génère la page: "T80=admin&T81=pass&N01=01" (*) Cette partie est aussi appelée "tail" par les anglosaxons. Je garderai le mot anglais...

Comment mettre ce qu'il faut dans une page html pour que le navigateur génère une requête bien propre ?

Regardons cela sur l'exemple :

Le site : sauf si on veut en changer, il n'y a rien à mettre. Par défaut, le navigateur reste sur le site où il est,

La page : elle se précise dans la balise ouvrante qui ouvre un formulaire. S'il n'y en a qu'une appelez la "index.htm" comme tout le monde,

Les infos passées à la page sont générées par chacune des commandes sur le formulaire : boutons, entrées, sélecteurs, etc. Cette partie peut être vide, par ex. pour la requête initiale sur un serveur,
Ici, deux boîtes de texte et un bouton.
Pour chaque commande, le même format au retour: "name=value"

Voyons comment décrire cela en html pour la première boîte de texte :

Un champ "name", mais pas de "value", car le champ s'affiche vide avant la saisie. Si j'avais voulu mettre une valeur par défaut, j'aurais ajouté : value='defaut', écrit ici sans l'accent.
Il s'agit d'une saisie de texte type='text' et le reste sont des formatages.

A l'exécution, j'ai tapé "admin" que l'on retrouve au retour dans le champ "T80=admin".

La boîte de texte T2 est identique, sauf qu'il s'agit d'un mot de passe :

Ayant saisi "pass", elle retourne T81=pass.

Maintenant, le bouton :

Valider

Les champs importants sont le "name" et la "value" que l'on retrouve au retour dans la requête : "N01=01".

Comment cela marche t'il ?

Rien de plus simple : lorsqu'on clique un bouton, le navigateur collecte toutes les "values" des boîtes d'entrée et termine par celle du bouton cliqué (il ne peut y en avoir qu'un).
Il met le tout à la file, les entrées étant séparées par "&" et l'on obtient :
"T80=admin&T81=pass&N01=01" placé, dans une requête GET, après la page séparé par un "?", sur la première ligne, après le GET et un blanc, soit :
/BTS10.htm?T80=admin&T81=pass&N01=01

Le "/" indique le page demandée est sur la racine du site.

Le traitement de la requête reçue comprend deux étapes :

  • isoler la page et le "tail" dans la requête,
  • dans le "tail", extraire les informations nécessaires.

Il y a plein de bibliothèques et de routines (dont celles de J-M-L) qui font cela, mais il faut d'abord avoir le bon code html pour générer une requête correcte.

Dans votre cas, vous utilisez le "onClick=selection.href="...". C'est du Javascript. Ca a marché dans votre exemple, mais cela n'est pas fait pour cela. Réservez le pour changer de site, pas pour passer des infos à votre serveur.

Voila, j'espère que cela va vous aider. Le fichier joint est le code html de la page exemple. Vous pouvez l'ouvrir avec votre navigateur. En cliquant sur un bouton, le navigateur générera une erreur, mais il affichera la page et le "tail" de sa requête (en tout cas Firefox le fait).

Je vous invite à bidouiller le code de la page, en regardant en direct sur votre navigateur ce qu'il fait. C'est super pour mettre au point une page.

Pour le détail du html, format, commandes, accents, couleurs, etc, un site un peu ancien mais très complet, avec plein d'exemples, même si la navigation y est un peu touffue:

Bon courage, ce n'est pas simple au début, mais une fois que l'on a quelque chose qui marche, cela fait plaisir. On perfectionne ensuite au fur et à mesure.

Enfin, il y a de multiples façons de faire, à chacun la sienne...

A+

MicroQuettas

(*) Les puristes auraient utilisé une requête POST pour ce cas. Ils ont raison, mais c'est pour un exemple de la requête GET.

Page 12b.zip (1019 Bytes)

J-M-L:
l'ESP-01 a ses propres contraintes aussi de ce côté là
une carte wifi de plus haut niveau est bien utile si vous voulez plus de robustesse .

Plusieurs fois ou vous aborder ce sujet/problème.
Que me conseiller vous ? (il doivent etre utiliser via tx/rx)

esp12 ?

esp32 ?

Je ne vais pas rester bloquer sur ce projet a cause d'un composant ... j'ai déjà assez avec le code ... :slight_smile:

J-M-L:
OK ?

J'ai bien compris le principe dont cela doit fonctionner mais je doit continuer a travailler un code a partir de : envoyerPageWeb(WiFiEspClient &client, const char * urlRequest)
ou pas.
Il semblerais que ce ne soit pas adapter a mon utilisation au dire de MicroQuettas.

Pourtant, cela fonctionne mise a par se problème de vitesse avec le bouton qui n'est pas pris en compte.
Sinon, pour contrer cela, il est peut être possible de faire un champs pour saisir directement la valeur voulu et valider, se qui ne ferait qu'une demande ... ??? qu'en penser vous ?

J'arrive vraiment a un problème de compréhension a ce niveau a cause d'une chose assez simple.
Jusque a présent, mis a par les thermes d’écriture qui m’était inconnu, la saisie des ligne de commande avait une logique et un sens.
Ce qui me bloque dans les exemple ect ... c'est ce genre de chose :
httpLine[indexMessage++] = c;
(c == '\n' && currentLineIsBlank)
char * ptrGET, *ptrEspace;
Qui n'ons ni queue ni tète pour moi et ce n'est pas faute de lire et relire, de faire des recherche avec l'IDE avec la fonction trouvée pour essayer de comprendre a quoi se rapporte chaque élément.
Je passe ~3h le matin et ~4h la nuit depuis plusieurs jour a vous lire et lire des dizaines de post sur le net.
Ma motivation est vraiment importante mais j’arrive a un point ou je me demande si le poisson n'est pas trop gros et je suis conscient du temps que vous prenez.

MicroQuettas:
Bon courage, ce n'est pas simple au début, mais une fois que l'on a quelque chose qui marche, cela fait plaisir. On perfectionne ensuite au fur et à mesure.

Bonjour MicroQuettas

Merci pour ton explication détaillé.
Je vais prendre le temps de tester cette page afin de comprendre les conséquence de chaque Click.

Pour comprendre cette ligne [color=blue]httpLine[/color][[color=purple]indexMessage[/color][color=red]++[/color]] =  [color=green]c[/color]; il faut la décomposer

[color=blue]httpLine[/color] est un tableau de caractères d'une certaine taille dans lequel on va ranger les uns après les autres les caractères que l'on reçoit sur la ligne Série. dans notre cas la variable

c

. Pour les mettre les uns après les autres il nous faut une variable qui va parcourir le tableau et se souvenir de l'endroit où l'on doit ranger le prochain caractère. J'utilise la variable [color=purple]indexMessage[/color] pour cela.

donc pour mettre c dans le tableau à la position indexMessage, on écrirait simplement

[color=blue]httpLine[/color][[color=purple]indexMessage[/color]] =  [color=green]c[/color];
ensuite il faut se souvenir qu'on a rempli cette case et donc passer à la case d'après. Donc après avoir stocké c au bon endroit on devrait faire un un truc du genre [color=purple]indexMessage[/color] = [color=purple]indexMessage[/color] + 1;

il existe dans le langage C une instruction ++ qui incrémente (ajoute 1 unité) directement une variable.

donc au lieu de faire [color=purple]indexMessage[/color] = [color=purple]indexMessage[/color] + 1;, je pourrais écrire [color=purple]indexMessage[/color][color=red]++[/color]; et mon code serait

[color=blue]httpLine[/color][[color=purple]indexMessage[/color]] =  [color=green]c[/color];
[color=purple]indexMessage[/color][color=red]++[/color];

Il faut savoir que l'on peut mettre le ++ avant ou après le nom de la variable et ça ne fait pas tout à fait la même chose:

a = 3;

b = a++; // ici on met a dans b et ensuite on augmente a de 1, donc b vaut 3 et a vaut 4 après exécution
b = ++a; // ici on augmente a de 1 d'abord puis met a dans b ensuite, donc b vaut 4 et a vaut 4 après exécution

En tenant compte de cette information on voit que l'on peut faire donc tout d'un seul coup:

httpLine[indexMessage[color=red]++[/color]] = c;

ça veut dire mettre c dans le tableau httpLine à la position indexMessage, puis ensuite augmenter de 1 indexMessage

OK ?

if (c == '\n' [color=red]&&[/color] currentLineIsBlank) ça c'est plutôt simple. l'opérateur && c'est le ET logique (si condition1 est vraie ET condition2 est vraie alors...). Ici on regarde donc si j'ai reçu un retour chariot et que la ligne précédente était vide (une variable que l'on maintient pendant qu'on reçoit les caratères) alors faire quelque chose --> la raison de cela est expliquée dans mon tuto, une requête HTTP se termine par une ligne vide, c'est comme cela que l'on repère la fin de la demande du navigateur.

OK?

char * ptrGET, *ptrEspace; ça déclare simplement 2 pointeurs sur des caractères;
l'objectif du code qui suit est d'extraire du tableau la partie qui concerne l'URL reçue. c'est ce code

if (ptrGET = strstr(httpLine, "GET")) {
   // c'est la requête GET, la ligne continent "GET /URL HTTP/1.1", on extrait l'URL
   ptrEspace = strstr(ptrGET + 4, " ");
   *ptrEspace = '\0';
   strncpy(urlRequest, ptrGET + 4, maxURL);
   urlRequest[maxURL] = '\0'; // par précaution si URL trop longue
}

En supposant que la ligne contient bien "GET /ADMIN HTTP/1.1" on veut alors extraire /ADMIN pour s'en souvenir et le passer ensuite à la fonction d'affichage de la page web.

voici ce que fait ce code

est clair ?