Bonjour,
J'essaie péniblement de finir un programmateur d'arrosage, avec une supervision sur page web (pour une future intégration domotique).
Je réalise mon système en 3 mode : 1 mode arrêt (facile !), un mode automatique (avec déclenchement à heures fixes, et suivant une durée déterminée), et un mode manuel.
J'avais commencé par le mode automatique, en autonome sur un arduino mega.
Puis en passant sur le monde manuel, je me suis dit que ce serait pas mal de le faire à distance, d'où l'idée de revoir l'ensemble avec une gestion par un page html (qui ne sera pas généré par l'arduino). L'idée étant d'avoir une page principale avec la possibilité d'afficher 3 pages différentes pour chaque mode.
Je me suis donc lancé dans la partie mode manuel, en essayant de faire allumer mes réseaux d'arrosage (pour l'instant juste représentés par des leds), via une page web, avec un retour d'état.
Je parviens à faire allumer mes leds, mais je voulais également un retour d'état, et là ça bloque.
Je me suis inspiré du blog d'eskimon (Arduino et Ethernet : serveur • Le blog d'Eskimon) mais je ne parviens pas à le reproduire pour mon cas (j'ai d'ailleurs essayé le sien sans rien modifier, ça ne fonctionne pas non plus )
Sur Firefox, j'ai un message dans la console :
XMLHttpRequest { onreadystatechange: onreadystatechange(), readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, responseURL: "", status: 0, statusText: "", responseType: "", response: "" }
ArduinoArrosage.js:49:5
Blocage d’une requête multiorigines (Cross-Origin Request) : la politique « Same Origin » ne permet pas de consulter la ressource distante située sur http://192.168.0.123/?r=1. Raison : l’en-tête CORS « Access-Control-Allow-Origin » ne correspond pas à « (null) ».
et sur Chrome j'ai :
XMLHttpRequest {onreadystatechange: null, readyState: 1, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}onabort: nullonerror: nullonload: nullonloadend: nullonloadstart: nullonprogress: nullonreadystatechange: ƒ ()ontimeout: nullreadyState: 4response: ""responseText: ""responseType: ""responseURL: "http://192.168.0.123/?r=5"responseXML: nullstatus: 200statusText: "OK"timeout:
Réponse reçue:
Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse ()
at afficher (ArduinoArrosage.js:68)
at XMLHttpRequest.requete.onreadystatechange (ArduinoArrosage.js:58)
afficher @ ArduinoArrosage.js:68
requete.onreadystatechange @ ArduinoArrosage.js:58
XMLHttpRequest.send (async)
executer @ ArduinoArrosage.js:50
Je vous mets mon code arduino, sans l'init et le setup :
void loop()
{
// Regarde si un client est connecté et attend une réponse
EthernetClient client = serveur.available();
if (client) {
// Quelqu'un est connecté !
Serial.println("On envoi !");
url = ""; // on remet à zéro notre chaîne tampon
index = 0;
while (client.connected()) { // Tant que le client est connecté
if (client.available()) { // A-t-il des choses à dire ?
// traitement des infos du client
char carlu = client.read(); //on lit ce qu'il raconte
if (carlu != '\n') { // On est en fin de chaîne ?
// non ! alors on stocke le caractère
url[index] = carlu;
index++;
} else {
// on a fini de lire ce qui nous intéresse
// on marque la fin de l'url (caractère de fin de chaîne)
url[index] = '\0';
Serial.println("message reçu de la page HTML :");
Serial.println(carlu);
boolean ok = interpreter(); // essaie d'interpréter la chaîne
if (ok) {
// tout s'est bien passé = on met à jour les réseaux
Serial.println("On allume !");
action();
}
// et dans tout les cas on répond au client
repondre(client);
// on quitte le while
break;
}
}
}
// Donne le temps au client de prendre les données
delay(10);
// Ferme la connexion avec le client
client.stop();
}
}
void repondre(EthernetClient client) {
// La fonction prend un client en argument
Serial.println("\nRepondre"); // debug
// On fait notre en-tête
// Tout d'abord le code de réponse 200 = réussite
client.println("HTTP/1.1 200 OK");
// Puis le type mime du contenu renvoyé, du json
client.println("Content-Type: application/json"); //application/json
// Autorise le cross origin
client.println("Access-Control-Allow-Origin: *");
// Et c'est tout !
// On envoi une ligne vide pour signaler la fin du header
client.println();
// Puis on commence notre JSON par une accolade ouvrante
client.println("{");
// On affiche les réseaux dans un tableau
client.println("\"reseau\": {");
// Le réseau 1
client.print("\t\t\"1\": ");
client.print(etats[0]);
client.println(",");
// Le réseau 2
client.print("\t\t\"2\": ");
client.print(etats[1]);
client.println(",");
// Le réseau 3
client.print("\t\t\"3\": ");
client.print(etats[2]);
client.println(",");
// Le réseau 4
client.print("\t\t\"4\": ");
client.print(etats[3]);
client.println(",");
// Le réseau 5
client.print("\t\t\"5\": ");
client.print(etats[4]);
client.println(",");
// Le réseau 6
client.print("\t\t\"6\": ");
client.println(etats[5]);
client.println("\t\t}");
// Et enfin on termine notre JSON par une accolade fermante
client.println("}");
Serial.println("réponse envoyée !");
}
boolean interpreter() {
// On commence par mettre à zéro tous les états
for (int i = 0; i < 6; i++) {
etats[i] = LOW;
}
// Puis maintenant on va chercher les caractères/marqueurs un par un.
index = 4; // Index pour se promener dans la chaîne (commence à 4 pour enlever "GET "
while (url[index] != 'r' && url[index+1] != '=') { // On commence par chercher le "r="
index++; // Passe au caractère suivant
if (index == 100) {
// On est rendu trop loin !
Serial.println("Oups, probleme dans la recherche de 'r='");
return false;
}
}
// Puis on lit jusqu’à trouver le ' ' de fin
while (url[index] != ' ') { // On cherche le ' '
if (url[index] >= '1' && url[index] <= '6') {
// On a trouvé un chiffre identifiant un réseau
char reseau = url[index] - '0'; // On ramène ça au format décimal
etats[reseau - 1] = HIGH; // Puis on met le réseau dans un futur état haut
}
index++; // Passe au caractère suivant
if (index == 100) {
// On est rendu trop loin !
Serial.println("Oups, probleme dans la lecture des broches");
return false;
}
// NOTE : Les virgules séparatrices sont ignorées
}
// Rendu ici, on a trouvé toutes les informations utiles !
Serial.println("interprétation OK");
return true;
}
Sauriez-vous me dire où est l'erreur ?
Merci par avance, en espérant que ce soir lisible...