Werte vom Webserver an den Arduino übergeben

Hallo,

ich versuche seit einiger Zeit Werte vom Webserver an den Arduino zu übertragen.

Habe das ganze Netz durchsucht und finde keine passende Lösung/Erklärung.

Zu meinem Problem:

Ich baue mir über HTML eine Seite auf, wo ich einen Namen und ein Passwort eingebe und diese dann übertrage.

Nun würde ich gerne 2 Variablen im Arduino definieren, die mir den Namen und das Passwort vom Webserver speichern.

Und hier komme ich gerade nicht weiter.

Anbei mein Code für Diskussionen.

Hoffe ihr könnt mir helfen.

Zum Aufbau:

Benutze einen Arduino Uno mit ESP-E01

#include <SPI.h>
#include <Ethernet.h>
#include <ESP8266WiFi.h>
/*byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,128);
EthernetServer server(80);
*/
const char* ssid = "ESP-Accesspoint";
const char* password = "12345678"; 
WiFiServer server(80);

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, password);
  server.begin();
 /* Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  */
}


void loop() {
  // listen for incoming clients
  WiFiClient client = server.available();
 // EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && currentLineIsBlank) {
          client.println("<!DOCTYPE html>");
          client.println("<html>");
          client.println("<body>");
          client.println("</form>");
          client.println("USER NAME:<input type='text' name='firstname'>
");
          client.println("PASSWORD:<input type='password' name='pwd'>
");
          client.println("<input type='submit'>");
          client.println("</form>");
          client.println("<body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }

      }
    }

    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

Der Befehl Serial.write(c) gibt mir nur das Grundgerüst der HTML Seite wieder, aber keine Information der eingetragen Texte im Inputfeld.

Wie muss ich da vorgehen?

Erfüllt die Submit Funktion doch nicht das Übertragen der Daten?

Benötige ich eine weitere Bibliothek?

Danke & Gruß,

Muki

          client.println("<html>");
          client.println("<body>");
          client.println("</form>");               // <<<<<<<<<<<<<   ???

Ich denke, das wird auch nie richtig funktionieren wenn du ihm keinen definierten Anfang für ein Eingabe-Formular vorgibst. Du hast zweimal im Code, aber keinen Anfang wie oder so. Nimm beim ersten mal den Slash raus und gebe ihm die korrekten Ziel-Parameter vor, wo er das Formular hinsenden soll.

Mukiknack:
Wie muss ich da vorgehen?

Ergänzend zu Rudis Posting: https://wiki.selfhtml.org/wiki/HTML/Tutorials/Formulare_erstellen_und_gestalten

Gruß

Gregor

Jau danke Gregor,
ich war gerade dabei den Link zu kopieren, aber du warst schneller! 1:0 für dich handshake
:smiley:

RudiDL5:
ich war gerade dabei den Link zu kopieren, aber du warst schneller!

Mach Dir nichts draus. Als gut trainierter Zehn-Finger-Tipper bin ich Dir vermutlich haushoch überlegen :slight_smile:

Gruß

Gregor

So so, aha?? :smiley:

Danke für eure Antworten.

Ja das mit der GET-Funktion hatte ich vergessen und nun ergänzt.

Nun wird mir auch beim betätigen des Button der Name und das PW in der Adressleiste vom Browser angezeigt.

if (c == '\n' && currentLineIsBlank) {
          client.println("<!DOCTYPE html>");
          client.println("<html>");
          client.println("<body>");
          client.println("</form>");
          client.println("</p><form method='get' action='setting'><label>SSID: </label><input name='ssid' length=32><input name='pass' length=64> </p>");
          /*client.println("USER NAME:<input type='text' name='firstname'>
");
          client.println(firstname);
          client.println("PASSWORD:<input type='password' name='pwd'>
");*/
          client.println("<input type='submit'>");
          client.println("</form>");
          client.println("<body>");
          client.println("</html>");
          break;
        }

Direkt meine nächste Frage. Wenn das alles als Klartext in der Adressleiste steht, kann das von außen abgefangen und gelesen werden, womit der Fremde Zugriff auf Daten hätte.

Kann man diese Übermittlung verschlüsseln?

Wie kann ich später die Übermittlung verschlüsseln, wenn der ESP sich anmeldet? Sendet der ESP dies auch noch als Klartext?

Wie kann ich mir später die Antwort von der HTML Seite aufteilen, um mir die beiden Werte zu speichern?

Mukiknack:
... Wenn das alles als Klartext in der Adressleiste steht, kann das von außen abgefangen und gelesen werden ...

Wie das?!

Mukiknack:
Kann man diese Übermittlung verschlüsseln?

Vorher würde ich meine E-Mails verschlüsseln.

Gruß

Gregor

client.println("");

Ist falsch. In HTML Beginnt man so: und beendet so :slight_smile: Dazu musst du ihm sagen wo das ganze hin geht. Du brauchst also eine weitere Seite, die das ganze ausliest.

Du könntest per MD5 Verschlüssen, wenn du das Passwort übergibst.

Heimdall:
... Du könntest per MD5 Verschlüssen, wenn du das Passwort übergibst.

Aber nicht ohne Cloud und Twitter-Account!

Was Du meinst, ist ein Algorithmus für die Berechnung eines Hash-Wertes. Den kann man z. B. benutzen, um manipulierte Daten zu erkennen. Für Paranoiker ist der „Message Digest Algorithm 5“ allerdings indiskutabel, da er nicht sicher ist.

Gruß

Gregor

Ich weiss zwar nicht, ob das bei der Verbindung Arduino+Internet machbar ist - aber zu GET fällt mir die Alternative POST ein, also . Bei POST sieht man im Browser lediglich die Adresse, sonst nichts. Verlangt dann aber (so weit ich das bisher gemacht habe) einen PHP-Script zur Auswertung der übergebenen Parameter im Hintergrund. Ist nur so 'ne Idee...

Ich sehe in Deinem Code nur einen Teil der HTML an den Browser schickt, da ist nichts, was die Eingaben beim Absenden des Formulars auswertet. Also wenn der Browser Daten an den Arduino schickt.

Auch der Titel des Threads ist irreführend, denn Du schickts keine Daten von einem Webserver an den Arduino, sondern der Arduino ist der Webserver und ist damit sowohl für die Ausgabe der HTML-Seite als auch für die Verarbeitung der Daten nach dem Abschicken des Fomulars zuständig.

Im Prinzip hast Du insgesamt 2 Aufgaben

  1. Ausgabe eine HTML-Seite mit einem Fomular wenn ein GET-Request kommt, an dem keine Parameter hängen
  2. Erkennen das ein GET oder POST Request vom Browser kommt an dem die Logindaten hängen. Einlesen der Daten aus dem Request, vergleichen auf Gültigkeit und dann die dazugehörigen Aktion (was auch immer das dann ist) ausführen. Danach wieder HTML-Code generieren, damit der Browser das Ergebnis anzeigen kann.

GET und POST unterscheiden sich dabei in der Art und Weise wie die Formulardaten übermittelt werden. GET ist evtl.etwas einfacher zu verarbeiten, weil die Daten in einer Zeile an der URL anhängen. Nachteil ist, das die Daten und damit das Passwort in der Browserzeile angezeigt werden.

Verschlüsselung geht in der Regel per HTTPS, das ist abermit dem Arduino aufgrund von Speichermangel und zu geringer Rechenkapazität nicht möglich. Grundsätzlich ist ein Arduino auch kein guter Webserver, aus den eben genannten Gründen.

Was willst Du denn eigentlich genau machen? Evtl. wäre ja ein Raspberry Pi für Dein Vorhaben besser geeignet. Der kostet weniger als ein Arduino mit WiFi Shield und hat deutlich mehr Rechenleistung. Einen Arduino kann man dann entweder per serieller Schnittstelle an den Raspberry koppeln, oder die z.B. Schalt-Aufgaben gleich über die GPIO Pins von Raspi machen.

gregorss:
Aber nicht ohne Cloud und Twitter-Account!

Was Du meinst, ist ein Algorithmus für die Berechnung eines Hash-Wertes. Den kann man z. B. benutzen, um manipulierte Daten zu erkennen. Für Paranoiker ist der „Message Digest Algorithm 5“ allerdings indiskutabel, da er nicht sicher ist.

Gruß

Gregor

Klar ist das nicht 100% sicher und schlau. Aber wahrscheinlich immer noch das einfachste. Im PHP Bereich war es vor 10 Jahren jedenfalls standard, wenn man Passwörter in der Datenbank gespeicher hat, damit man diese nicht direkt auslesen kann.

Das auslesen ist echt schwer. PHP dürfte für den Arduino zu viel sein. Aber Javascript würde vielleicht funktionieren.

<html>
<head>
<title>Test</title>
<script type="text/javascript">
function GetText() {
alert(document.getElementById("Passwort").value);}
</script>
</head>
<body>
<form>
<input type="text" id="Passwort">
<input type="button" value="Passwort abfragen" onclick="GetText()">
</form>
</body>
</html>

Das ganze im head Bereich des HTML Docs liest eigentlich den Text aus dem Feld mit dem Namen Passwort aus. Wie genau er das jetzt an den Arduino weiter gibt weiß ich auch nicht. Dafür bin ich selber zu sehr Neuling. Sorry

JavaScript wird im Browser ausgeführt, das hat noch nichts mit dem Arduino zu tun. Allerdings könnte man damit das Übertragen von User und Passwort tatsächlich etwas vereinfachen. Per JavaScript kann man einfach einen HTTP-Request generieren, der dann die Werte in einem Format enthält, die sich leicht auf dem Arduino parsen lassen. Allerdings ist das dann trotzdem noch unverschlüsselt.

Das weiß ich auch. Aber mit PHP wird er es wohl kaum auslesen können. Da ist Javascript die einzige Möglichkeit.

Hallo,

vielen Dank für die vielen Anregungen.

Zu der Frage was ich umsetzen möchte:

Ich möchte das der ESP einen AP erstellt, wenn er sich nicht in das heimische WLAN einwählen kann.

Wenn er sich im AP befindet,möchte ich gerne meine SSID und mein PWD ein geben und diese sollen dann im EEPROM gespeichert werden.

Wird nun der ESP neu gestartet, liest er die Werte aus dem EERPOM und verbindet sich mit meinem WLAN.

Sollte dies nicht funktionieren, eröffne wieder ein AP und warte auf Eingaben. Wird dann wieder eine SSID und ein PWD eingetragen, werden die alten Daten gelöscht und die neuen Werte im EEPROM gespeichert.

So soll sich der Vorgang beliebig wiederholen.

Ist der ESP nun im heimischen Netzwerk, möchte ich über die neue IP eine weitere HTML Seite aufrufen, wo ich dann per Taster die Ausgänge am ESP einschalten und auschalten kann.

Stichwort --> WLAN Schalter.

Ich möchte anmerken, dass ich nicht viel Erfahrung in HTML oder PHP habe, aber bereit mir das anzueignen.

Habe den Code nun so erweitert, dass mir PWD und SSID in der Explorerleiste angezeigt werden, das schon mal der nächste Schritt.

Nun müsste ich die Antwort vom Server auswerten.

#include <SPI.h>
#include <Ethernet.h>
#include <ESP8266WiFi.h>
/*byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,128);
EthernetServer server(80);
*/
const char* ssid = "ESP-Accesspoint";
const char* password = "12345678"; 

String firstname;
WiFiServer server(80);

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, password);
  server.begin();
 /* Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  */
}


void loop() {
  // listen for incoming clients
  WiFiClient client = server.available();
 // EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && currentLineIsBlank) {
          client.println("<!DOCTYPE html>");
          client.println("<html>");
          client.println("<body>");
          client.println("</form>");
          client.println("</p><form method='get' action='setting'><label>SSID: </label><input name='ssid' length=32><input name='pass' length=64> </p>");
          client.println("<input type='submit'>");
          client.println("</form>");
          client.println("<body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }

      }
    }

    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

Wie wäre es mit dem PI möglich?
Da ich gerne mehrere WLAN Schalter aufbauen möchte und dann per App diese einschalten oder ausschalten möchten.

Könnte der ESP mit dem PI kommunizieren?

Dann müsste der PI den Befehl zum ESP schicken und dieser den ausführen?

Gruß,

für den ESP gibt es den wifimanager.h

macht was du willst bzgl. wifi Daten speichern

Bin ich ehrlich kein Freund von diesem Programm.

Möchte das einfacher und praktischer halten und zudem meinen eigenen Code den ich auch verstanden habe nutzen.

Bin kein Freund fertiger Sachen :slight_smile: