Arduino als Webserver

Hallo

Ich habe eine Frage zu dem Befehl "char c = Client.read();"
Bei meinem Skatch wird die Anfrage von einem Client zum Arduino so angenommen, nun möchte ich den Inhalt von "c" in eine String Variable übertragen, kann mir einer sagen wie ich das machen kann?

Danke

Sketch:

void serverDemo()
{
  // available() is an ESP8266Server function which will
  // return an ESP8266Client object for printing and reading.
  // available() has one parameter -- a timeout value. This
  // is the number of milliseconds the function waits,
  // checking for a connection.
  ESP8266Client client = server.available(500);
  
  if (client) 
  {

    Serial.println(F("Client Connected!"));
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
      
    while (client.connected()) 
    {
      if (client.available()) 
      {        
     
        char c = client.read();

        
        if (c == '\n' && currentLineIsBlank)
        {
          Serial.println(F("Sending HTML page"));
          // send a standard http response header:
          
          client.print(htmlHeader);
          client.println("</html>\n");                  
          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(500);
   
    // close the connection:
    client.stop();
    Serial.println(F("Client disconnected"));
  }
  
}

Im ersten Schritt solltest Du einfach c mit Serial.print(c) ausgeben, damit Du siehst, was und wieviel da ankommt.
Danach kannst Du einen Puffer (char-Array) für Deine Zeilen bemessen und die Zeichen dort eintragen.
Wenn die Zeile voll ist ('\n') wieder die Zeile ausgeben.
Ansonsten schau Dir mal Zeichenketten in C an.

Gruß Tommy

Hallo

Das ist mein Problem, wenn ich Serial.print(c); mache kommt nichts :frowning:

Wie rufst Du den Webserver denn auf?

Gruß Tommy

ESP8266Server server = ESP8266Server(80);

So, ich glaube du meinst das so oder?

Hier mal das ganze Sketch.

#include <SoftwareSerial.h> 
#include <SparkFunESP8266WiFi.h> 
 
const char mySSID[] = "SSID";
const char myPSK[] = "Kennwort";

ESP8266Server server = ESP8266Server(80);

const String htmlHeader = "HTTP/1.1 200 OK\r\n"
                          "Content-Type: text/html\r\n"
                          "Connection: close\r\n\r\n"
                          "<!DOCTYPE HTML>\r\n"
                          "<html>\r\n";

void setup() 
{
  Serial.begin(9600);
  initializeESP8266();
  connectESP8266();
  displayConnectInfo();
  serverSetup();  
}

void loop() 
{
  WebServer(); 
}

void initializeESP8266()
{
  int test = esp8266.begin();
  if (test != true)
  {
    Serial.println(F("Error talking to ESP8266."));
    errorLoop(test);
  }
  Serial.println(F("ESP8266 Shield Present"));
}

void connectESP8266()
{
  int retVal = esp8266.getMode();
  if (retVal != ESP8266_MODE_STA)
  { // If it's not in station mode.
    // Use esp8266.setMode([mode]) to set it to a specified
    // mode.
    retVal = esp8266.setMode(ESP8266_MODE_STA);
    if (retVal < 0)
    {
      Serial.println(F("Error setting mode."));
      errorLoop(retVal);
    }
  }
  Serial.println(F("Mode set to station"));
  retVal = esp8266.status();
  if (retVal <= 0)
  {
    Serial.print(F("Connecting to "));
    Serial.println(mySSID);
    retVal = esp8266.connect(mySSID, myPSK);
    if (retVal < 0)
    {
      Serial.println(F("Error connecting"));
      errorLoop(retVal);
    }
  }
}

void displayConnectInfo()
{
  char connectedSSID[24];
  memset(connectedSSID, 0, 24);
  int retVal = esp8266.getAP(connectedSSID);
  if (retVal > 0)
  {
    Serial.print(F("Connected to: "));
    Serial.println(connectedSSID);
  }

  // esp8266.localIP returns an IPAddress variable with the
  // ESP8266's current local IP address.
  IPAddress myIP = esp8266.localIP();
  Serial.print(F("My IP: ")); Serial.println(myIP);
}

void serverSetup()
{
  server.begin();
  Serial.print(F("Server started! Go to "));
  Serial.println(esp8266.localIP());
  Serial.println();
}

void WebServer()
{

  ESP8266Client client = server.available(500);
  
  if (client) 
  {

    Serial.println(F("Client Connected!"));
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
      
    while (client.connected()) 
    {
      if (client.available()) 
      {        
     
        char c = client.read();

        
        if (c == '\n' && currentLineIsBlank)
        {
          Serial.println(F("Sending HTML page"));
          // send a standard http response header:
          
          client.print(htmlHeader);
         //HTML Code
          client.println("</html>\n");                  
          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(500);
   
    // close the connection:
    client.stop();
    Serial.println(F("Client disconnected"));
  }
  
}

// errorLoop prints an error code, then loops forever.
void errorLoop(int error)
{
  Serial.print(F("Error: ")); Serial.println(error);
  Serial.println(F("Looping forever."));
  for (;;)
    ;
}

Der Grund Code ist aus dem Sparkfun esp8266, das funktioniert soweit auch ganz gut ohne das siech der Arduino als aufhängt, allerdings möchte ich die die vom Browser kommenden GET Variablen auswerten.

neuling321:
ESP8266Server server = ESP8266Server(80);

So, ich glaube du meinst das so oder?

Nö, meine ich nicht.
Ein Webserver ist eine Software, die für einen Client einen Service anbietet. Dazu muss der Client erst mal sagen, dass er den Service nutzen will.
Genau so, wie Du mit einem Browser dem Webserver vom Forum sagst, dass Du einen Thread lesen willst. Erst dann sendet er ihn Dir zu. Vorher tut er für Dich nichts.

Genau so ist das mit Deinem Webserver. Den musst Du erst aus dem Browser heraus aufrufen, bevor er etwas tut.

Gruß Tommy

Ja das klappt ja auch alles. Das ist nicht das Problem, das Problem ist das ich die "char c" nicht ausgeben kann, bzw. nicht weiter verarbeiten kann.
Ich muss diese quasi zweimal weiter verarbeiten. Einmal um den Respons vom Client fertig abzufangen und dann eine Meldung an den Client zu senden, das klappt ja bisher, und zweitens muss ich aus der Anfrage die vom Client kommt das GET raus filtern, um den Arduino zusagen was er machen soll.

Wenn Du sie nicht ausgeben kannst, kommt nichts an.

Gruß Tommy

Doch da kommt was an, sonst würde ja die If Abfrage "if (c == '\n' && currentLineIsBlank)" nicht funktionieren.
Wenn ich den Befehl "Serial.print(client.readStringUntil(' '));" benutze bekomme ich folgende Ausgabe:

+IPD,0,271:GETTTP/1.1
Accept:ext/html,pplication/xhtml+xml,mage/jxr,/*
Accept-Language:e-CH,de;q=0.5
User-Agent:ozilla/5.0WindowsT0.0;OW64;rident/7.0;v:11.0)ikeecko
Accept-Encoding:zip,eflate
Host:92.168.100.106
Connection:eep-Alive

Das wäre auch ok, aber leider funktioniert dann die If Abfrage "if (c == '\n' && currentLineIsBlank)" nicht mehr :frowning:

Die gleiche Ausgabe mußt Du ach bekommen, wenn Du hier das Serial.println ergänzt:

  char c = client.read();
  Serial.print(c);

Etwas anderes hatte ich nicht geschrieben.

Gruß Tommy

Eben nicht, ich bekomme dann die Ausgabe leider nicht.

Wo hattest Du denn "Serial.print(client.readStringUntil(' '));" eingebaut?

Gruß Tommy

Direkt nach "Serial.print(c);" habe auch Serial.print aus kommentiert, geht auch nicht
Ich bin echt am verzweifeln. Da übersehe ich doch irgendwas :frowning:

Bei Deiner Ausgabe in #9 fällt mir gerade auf, dass da immer Buchstaben am Wortanfang fehlen.
Was für einenESP8266 benutzt Du?

Wofür hast Du Softwareserial includiert?

Gruß Tommy

Die Daten werden nicht über die "Hardware" Schnittstelle Serial" ausgegeben. Hier das Original Sketch von Sparkfun esp8266. Die Softserial brauch ich ja nur solange bis alles läuft, dann kann ich die ja weg lassen :slight_smile:

Keine Ahnung was ich da falsch mache :frowning:

Im Anhang ist das Original, wie gesagt es funktioniert soweit auch, doch sobald ich die "char c" ausgeben oder weiter verarbeiten will geht es nicht mehr.

ESP8266_Shield_Demo.ino (8.66 KB)

Hallo

Kann da keiner weiterhelfen?
Wieso um alles in der Welt macht man eine Char Variable die man nicht weiter verarbeiten kann? wo Steckt den da der Sinn?

Hi

Da Das, eine char-Variable, Die man NICHT weiter verarbeiten kann, keinen Sinn ergibt, lässt sich schließen, daß das Problem eher in Deinem Code/Deiner Umgebung zu suchen ist.

Ich denke, Du kannst die char's auswerten, aber nur, wenn Du nicht 'Alles am Stück in einen String' abrufst - denke, danach sind für Dein char einfach keine Daten mehr vorhanden, da der Puffer nach dem Abruf gelöscht ist - habe Deinen Sketch aber nur überflogen und nicht Alles ins Kleinste durchgekaut.

MfG

Ich verstehe das irgendwie nicht ganz. Mit "char c = Client.read();" lese ich aus was mir der Client gibt, danch mache ich gleich ein String "buffer += c;" nun müsste mir doch der buffer gefüllt werden. Was auch komisch ist, sobald ich den buffer fülle, funktioniert der Rest des Codes nicht mehr und im buffer ist nichts drin.

Sorry, aber das ist doch ein Bug in der Sprache C/C++, ich kann den Char nicht weiterverarbeiten, das ist doch nicht möglich.
Kann mir da niemand helfen? es muss doch eine Möglichkeit geben das char in ein String zu schreiben und die Char Variable trotzdem weiter zu verwenden. Das geht in C#, in Delphi in VBS, VBA, PHP und in Javascript, nur in C/C++ nicht???