2017-06-28 4 views
5

J'ai un serveur Web sur un ESP32 et une page d'accueil sur ce serveur. Je voudrais mettre à jour les valeurs de capteur sur la page d'accueil toutes les x secondes automatiquement (sans entrée de l'utilisateur). Je ne peux pas accéder au système de fichiers.Serveur Web sur ESP32: Comment mettre à jour et afficher automatiquement les valeurs des capteurs du serveur?

Le capteur est directement connecté à l'ESP32. Les valeurs des capteurs sont dans mon programme C, stockées dans des variables et mises à jour régulièrement. Les variables sont globales pour une utilisation plus facile.

Je pensais à Ajax (je n'ai aucune expérience), mais tous les exemples et méthodes que je peux trouver utilisent un fichier pour charger des données (dans la partie 'url' de XMLHttpRequest(). Open (... url. ...)). Je n'ai pas de fichier mais seulement des chaînes dans lesquelles mon code HTML et Javascript est généré et envoyé au client.

Je n'ai aucune idée de comment mettre à jour mes valeurs et espère de l'aide.

Je pensais à essayer quelque chose comme les exemples de W3Schools, mais je ne sais pas comment obtenir les valeurs là:

Exemple d'une autre page (je ne pas utiliser ce code - Je ne peux pas utiliser des fichiers !)

function loadDoc() { 
    var xhttp = new XMLHttpRequest(); 
    xhttp.onreadystatechange = function() { 
    if (this.readyState == 4 && this.status == 200) { 
     document.getElementById("demo").innerHTML = this.responseText; 
    } 
    }; 
    xhttp.open("GET", "ajax_info.txt", true); 
    xhttp.send(); 
} 

Voici une partie de mon programme C sur l'ESP:

HTML-String:

String html_document() { 
    String sHTML; 
    sHTML = "<!doctype html>"; 
    sHTML +="<html>"; 
    sHTML +="<html lang=\"de\">"; 
    /***************** head ****************/ 
    sHTML +="<head>"; 
    /****** avoid favicon requests ** ** <link rel=\"shortcut icon\" href=\"data:image/x-icon;,\" type=\"image/x-icon\"> **/ 
    sHTML +="<link rel=\"icon\" href=\"data:;base64,iVBORw0KGgo=\"> "; 
    sHTML +="<meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"; 
    //Anpassung an Viewport für unterschiedliche Devices 
    /***************** title ***************/ 
    sHTML +="<title>LetsgoING IoT</title>"; 
    sHTML +="<style>h1{display: flex; flex-flow: row wrap; justify-content: center;} </style>"; 
    sHTML +="<style>h1{ color: green;}</style>"; 
    sHTML +="<style>h2{display: flex; flex-flow: row wrap; justify-content: center;} </style>"; 
    sHTML +="<style>h2{ color: blue;}</style>"; 
    sHTML +="<style>h5{display: flex; flex-flow: row wrap; justify-content: center;} </style>"; 
    sHTML +="<style>p{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 3%;} </style>"; 
    sHTML +="<style>p1{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 0%;} </style>"; 
    sHTML +="<style>p2{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 0%;} </style>"; 
    sHTML +="</head>"; 
    /***************** body ****************/ 
    sHTML+= "<body>"; //onload=\"window.setInterval(updateDiv, 15000);\" 
    sHTML+= "<h1>LetsgoING</h1>"; 
    sHTML+= "<h2>Internet der Dinge</h2>"; 
    sHTML+= "<p1><a style=\"width:38%;\"></a><a style=\"width:20%;color: green\">LED ein</a> <a style=\"width:15%;\" href=\"LEDON\"><button> EIN </button></a> </a><a style=\"width:27%;\"> </a></p1>"; 
    sHTML+= "<p><a style=\"width:38%;\"></a><a style=\"width:20%;color: red\" >LED aus</a> <a style=\"width:15%\"; href=\"LEDOFF\"><button>AUS</button></a><a style=\"width:27%;\"> </a></p>"; 
    sHTML+= "<h5>RGB-LED PWM-Werte</h5>"; 
    sHTML+= "<form><p2>"; 
    sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: red\"> Rot</a> <a style=\"width:15%;\" ><input name=\"rot\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\" ></a><a style=\"width:27%;\"> </a>"; 
    sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: green\">Grün</a><a style=\"width:15%;\" ><input name=\"gruen\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\"></a><a style=\"width:27%;\"> </a>"; 
    sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: blue\">Blau</a> <a style=\"width:15%;\" ><input name=\"blau\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\"></a><a style=\"width:27%;\"> </a>"; 
    sHTML+= "</p2>"; 
    sHTML+= "<p><a style=\"width:38%;\"></a> <a style=\"width:20%;\">   </a> <label style=\"width:15%;\" ><input type=\"submit\" value=\"senden\"></label><a style=\"width:27%;\"></a></p>"; 
    sHTML+= "</form>"; 
    sHTML+= "<h5>analoger Schwellwert</h5>"; 
    sHTML+= "<form><p2><a style=\"width:38%;\"></a> <a style=\"width:20%;\"> <input name=\"schwell\" type=\"number\" min=\"0\" max=\"1024\" step=\"10\" value=\"300\"> </a> <a style=\"width:15%;\"><input type=\"submit\" value=\"senden\"></a><a style=\"width:27%;\"> </a></p2>"; 
    //sHTML+= "<p><a style=\"width:28%;\"></a> <a style=\"width:30%;\">   </a> <label style=\"width:15%;\" ><input type=\"submit\" value=\"senden\"></label><a style=\"width:27%;\"></a></p>"; 
    sHTML+= "</form>"; 
    sHTML+= "<h5>PWM-Wert</h5>"; 
    sHTML+= "<form><p2><a style=\"width:38%;\"></a> <a style=\"width:20%;\"> <input name=\"pwm\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"0\"> </a> <a style=\"width:15%;\"><input type=\"submit\" value=\"senden\"></a><a style=\"width:27%;\"> </a></p2>"; 
    sHTML+= "</form>"; 
    sHTML+= "<h5>Messwerte</h5>"; 
    sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"an1\"; style=\"width:20%;\" href=\"anlg1\">#-Wert-#</p3><a style=\"width:22%;\">Analoger Pin 36 </a><a style=\"width:20%;\"></a></p>"; 
    sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"an2\"; style=\"width:20%;\">#-Wert-#</p3><a style=\"width:22%;\">Analoger Pin 39 </a><a style=\"width:20%;\"></a></p>"; 
    sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"dig\"; style=\"width:20%;\">#-Wert-#</p3><a style=\"width:22%;\">Digitaler Pin 5 </a><a style=\"width:20%;\"></a></p>"; 
    sHTML+= "</body>"; 
    sHTML+= "</html>"; 
    return sHTML; 
} 

Loop:

void loop() { 
    if (millis() - startTime >= 2000) { 
    startTime = millis(); 
    /* Check if a client has connected */ 
    client = server.available(); 
    if (!client){ 
     return; 
    } 
    /*Wait for the client to send data */ 
    Serial.println("neuer Client verbunden------------------------------"); 
    /*Count requests: */ 
    request_counter ++; 
    unsigned long clTimeout = millis()+250; 
    while(!client.available() && (millis()<clTimeout)) { 
     delay(1); 
    } 
    /*** publish Homepage ***/ 
    client.print(html_document()); 
    /* Read the first line of the clients request string "sHTML" until carriage return \r */ 
    sHTMLRequest = client.readStringUntil('\r'); 
    #ifdef DEBUGMODE 
    Serial.println("Antwort: "); 
    Serial.println(sHTMLRequest); 
    #endif 
    client.flush(); 
    /* stop client, if request is empty */ 
    if(sHTMLRequest=="") { 
     Serial.println("Leere Anfrage! - client gestoppt"); 
     client.stop(); 
     return; 
    } 
    #ifdef DEBUGMODE 
    Serial.println("Antwort2: "); 
    Serial.println(sHTMLRequest); 
    Serial.println ("---------"); 
    Serial.print("DEBUG: Remote IP - Address : "); 
    for (int i = 0; i < 3; i++) { 
     Serial.print(client.remoteIP()[i]); 
     Serial.print("."); 
    } 
    Serial.println(client.remoteIP()[3]); 
    Serial.print("Seitenaufrufe: "); 
    Serial.println(request_counter); 
    Serial.println ("---------"); 
    #endif 
    /**** call event handler **********/ 
    eventHandler(); 
    #ifdef DEBUGMODE 
    Serial.println("Zugewiesene PWM-Werte"); 
    Serial.print("rot: "); 
    Serial.println(rot); 
    Serial.print("gruen: "); 
    Serial.println(gruen); 
    Serial.print("blau: "); 
    Serial.println(blau); 
    #endif 
    /* write PWM values for colors to channels*/ 
    ledcWrite(1, rot); 
    ledcWrite(2, gruen); 
    ledcWrite(3, blau); 
    #ifdef DEBUGMODE 
    Serial.println(analog1); 
    #endif 
    } 
    UpdateValues(); 
} 

/**** reads pin values **/ 
void UpdateValues() { 
    analog1 = analogRead(pinAnalog1); 
    analog2 = analogRead(pinAnalog2); 
    DigiOut = digitalRead(LEDpin); 
} 

Voici la fonction qui met à jour les valeurs et crée la chaîne JSON:

void UpdateValues() { 
    analog1 = analogRead(pinAnalog1); 
    analog2 = analogRead(pinAnalog2); 
    DigiOut = digitalRead(LEDpin); 
    String strJson; 
    strJson = "(200,\"application/json\",\"{\"pin36\": "; 
    strJson+=analog1; 
    strJson+=", \"pin39\":"; 
    strJson+= analog2; 
    strJson+=", \"pin5\": "; 
    strJson+=DigiOut; 
    strJson+="}\")"; 
    server.print(strJson); 
} 
+0

Donc vous avez un capteur et vous voulez envoyer ses données sur le serveur web esp32? Quel genre de capteur? Pouvez-vous le connecter directement à l'esp32? Le capteur a-t-il une capacité sans fil? etc? – Musa

+0

voir ci-dessus: sensordata est juste n'importe quelle valeur d'entrée analogique. Pas de capteur sans fil. L'idée est d'utiliser le wifi d'esp. – carousally

+0

Vous effectuez un appel ajax pour récupérer 'ajax_info.txt'. Pouvez-vous poster le contenu de cela? – styfle

Répondre

2

Option 1:

La façon la plus simple est de demander à la rafraîchir la page elle-même toutes les 5 secondes en ajoutant ceci à <head>:

sHTML +="<meta http-equiv=\"refresh\" content=\"5\">"; 

Puis modifiez votre chaîne sHTML pour concaténer les valeurs de vos variables globales. Chaque fois que la page se rafraîchit, elle devrait (devrait) reconstruire le code HTML et retourner les dernières valeurs.

Option 2:

Vous pouvez utiliser ajax pour récupérer les dernières valeurs, puis mettre à jour fréquemment la petite section de la page Web qui affiche les données.

Ce qui se passe ici, c'est que vous configurez votre ESP32 pour fournir une deuxième URL, une qui renvoie uniquement les dernières valeurs en tant qu'objet json. Les valeurs sont ensuite injectées dans la page, écrasant l'ancien.

d'abord ajouter un lien vers jQuery dans le <head>:

sHTML +="<script src=\"https://code.jquery.com/jquery-3.2.1.min.js\"></script>"; 

Dans le <body> ajouter spans avec ids pour maintenir les valeurs à jour.Quelque chose comme:

sHTML+= "<h5>Messwerte</h5>"; 
sHTML+="<p>Analoger Pin 36</p>&nbsp;<span id='pin36'></span>"; 
sHTML+="<p>Analoger Pin 39</p>&nbsp;<span id='pin39'></span>"; 
sHTML+="<p>Analoger Pin 5</p>&nbsp;<span id='pin5'></span>"; 

Créer le sHTML pour le javascript suivant qui fait une demande ajax toutes les 5 secondes, et met à jour les dernières valeurs dans le navigateur:

<script> 
    $(function() { 

    // request data every 5 seconds 
    setInterval(requestData, 5000); 

    function requestData() { 

     // ajax request for latest sensor data 
     $.get("/sensors") 
     .done(function(data) { 

      console.log(data); // debugging - remove when satisfied 

      if (data) { // if the returned data is not null, update the values 
      $("#pin36").text(data.pin36); 
      $("#pin39").text(data.pin39); 
      $("#pin5").text(data.pin5); 
      } else { // a problem occurred 
      $("#pin36").text("?"); 
      $("#pin39").text("?"); 
      $("#pin5").text("?"); 
      } 
     }).fail(function() { 
      console.log("The was a problem retrieving the data."); 
     }); 
    } 

    }); 
</script> 

Lorsque vous détectez la chaîne /sensors dans sHTMLRequest vous voulez retourner le format json suivant:

{"pin36": 5.2, "pin39": 0.322, "pin5": 1}

À ce stade, je ne sais pas assez sur votre configuration de conseiller trop loin, mais ces liens devraient nous espérons aider avec le code C: http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web-server.html & http://randomnerdtutorials.com/esp32-web-server-arduino-ide/

Si vous utilisez ESP32WebServer.h de https://github.com/nhatuan84/esp32-webserver (voir second semestre http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web-server.html pour plus de détails), vous pouvez utiliser quelque chose comme:

server.on("/sensors", handleSensorData); 

avec

/* this callback will be invoked when user request "/sensors" */ 
void handleSensorData() { 
    /* server responds 200 with a json payload */ 
    /* although preferably concatenate your real sensor data here */ 
    server.send(200, "application/json", "{\"pin36\": 5.2, \"pin39\": 0.322, \"pin5\": 1}"); 
} 
+0

Cela a l'air génial, je vais essayer dès que possible! – carousally

+0

Bonjour K Scandrett, est-il possible que ce code ne fonctionne que lorsqu'il est connecté à Internet? (ESP32 fonctionne en mode AP et sans connexion Internet) Pour cette partie: ".... https: //code.jquery.com/jquery-3.2.1.min.js ..." Je reçois un message d'erreur dans le navigateur: "Impossible de charger la ressource: net :: ERR_NAME_NOT_RESOLVED -------- jquery-3.2.1.min.js" – carousally

+1

Oui, dans ce cas, j'ai supposé que l'ordinateur à partir duquel vous vous connectez a une connexion internet. Je ne peux pas répondre correctement maintenant, mais je vais essayer de le faire demain –