Forum: Mikrocontroller und Digitale Elektronik Arduino Webserver mit mehreren Seiten


von Jonny H. (jonny123) Flattr this


Lesenswert?

Hallo,

ich möchte im Rahmen einer Arduino Smart Home Steuerung mehrere Seiten 
auf meiner Web Oberfläche zur Verfügung haben.
Aber leider lädt die Web Oberfläche nicht.
Kann mir vielleicht jemand sagen, wo der Fehler sitzt?

Diese Seite:
http://fluuux.de/2013/03/arduino-als-webserver-einrichten-und-webpage-von-sd-karte-laden/
diente mir als Vorlage.

Da das Sketch sehr lang ist habe ich nur das Wesentliche reinkopiert.
Vielen Dank!

Gruß
Jonny

1
/**************************************************************************
2
  Pojekt: Haussteuerung 
3
4
  
5
6
  Inhalt der Steuerung:
7
  - Dämmerrungsschlter für Beleuchtungssteuerung im Treppenhaus
8
  - 2. Dämmerrungsschlter für Schaltbare Steckdosen
9
  - Jalousiesteuerung in Wohnküche
10
  
11
  
12
 **************************************************************************/
13
14
15
#if ARDUINO > 18
16
#include <SPI.h> // Für Arduino Version größer als 0018
17
#endif
18
#include <Ethernet.h>
19
#include <TextFinder.h>
20
#include <SD.h>
21
#include <DS1307RTC.h>
22
#include <Time.h>
23
#define REQ_BUF_SZ   60     // size of buffer used to capture HTTP requests
24
25
26
byte mac[] = { 0x5A, 0xA2, 0xDA, 0x0D, 0x56, 0x7A }; // MAC-Adresse des Ethernet-Shield
27
byte ip[]  = { 192, 168, 3, 21 };                    // IP zum aufrufen des Webservers
28
byte sdPin = 4;                                      // Pin der SD-Karte
29
30
EthernetServer server(80);                           // Server port
31
32
File webFile;
33
34
String readString = String(100);                      // Benötigt um Daten von HTML in Arduino einzulesen
35
36
37
/***************************************
38
          ENTFERNT
39
 ***************************************/
40
41
42
43
44
void setup()
45
{
46
47
 /***************************************
48
          ENTFERNT
49
 ***************************************/
50
51
  Ethernet.begin(mac, ip);                   // Client starten
52
  server.begin();                            // Server starten
53
  Serial.begin(9600);
54
  Serial.println("ARDUINO - STEUERUNG");
55
56
  Serial.println("Initialisiere SD-Karte...");
57
  if (!SD.begin(sdPin))
58
  {
59
    Serial.println(" - Initialisierung der SD-Karte fehlgeschlagen!");
60
    return;
61
  }
62
  Serial.println(" - SD-Karte erfolgreich initialisiert.");
63
64
  if (!SD.exists("index.htm"))
65
  {
66
    Serial.println(" - Datei (index.htm) wurde nicht gefunden!");
67
    return;
68
  }
69
  Serial.println(" - Datei (index.htm) wurde gefunden.");
70
71
  Serial.println();
72
  Serial.println("Haussteuerung v1.31 23.01.2016 von Jobst Hartwig");
73
}
74
75
76
void loop()
77
{
78
 /***************************************
79
          ENTFERNT
80
 ***************************************/
81
  EthernetClient client = server.available(); // Auf Anfrage warten
82
83
  if (client)
84
  {
85
86
    /*****************************************
87
      Arduino über das Webformular steuern  *
88
    *****************************************/
89
90
91
    TextFinder finder(client);
92
93
    if (finder.find("GET"))
94
    {
95
      while (finder.findUntil("var", "\n\r"))
96
      {
97
        char typ = client.read();
98
        int  var = finder.getValue();
99
        int  val = finder.getValue();
100
101
        if (typ == 'S')                              // Schwellwert für Dämmerungsschalter steuern und Ereignise löschen
102
        {
103
104
          if (var == 2)                               // Schwellwert Treppenleuchte
105
          {
106
            schwellwert ++;
107
            Serial.print("Neuer Schwellwert Treppenleuchten: ");
108
            Serial.println(schwellwert);
109
          }
110
          else if (var == 3)
111
          {
112
            schwellwert --;
113
            Serial.print("Neuer Schwellwert Treppenleuchten: ");
114
            Serial.println(schwellwert);
115
          }
116
          else if (var == 4)                           // Schwellwert schaltbare Steckdosen
117
          {
118
            schwellwert2 ++;
119
            Serial.print("Neuer Schwellwert schaltbare Steckdosen: ");
120
            Serial.println(schwellwert);
121
          }
122
          else if (var == 5)
123
          {
124
            schwellwert2 --;
125
            Serial.print("Neuer Schwellwert schaltbare Steckdosen: ");
126
            Serial.println(schwellwert);
127
            //          }
128
            //          else if (var == 6)                            // Ereignise löschen
129
            //          {
130
            //            Fehler = 0;
131
            //            Serial.println("Ereignise gelöscht");
132
            //          }
133
134
          }
135
        }
136
      }
137
138
139
      /************************
140
        Webformular anzeigen  *
141
      ************************/
142
      boolean current_line_is_blank = true;       // eine HTTP-Anfrage endet mit einer Leerzeile und einer neuen Zeile
143
144
      while (client.connected())
145
      {
146
        if (client.available())                   // Wenn Daten vom Server empfangen werden
147
        {
148
          char c = client.read();                 // empfangene Zeichen einlesen
149
          if (c == '\n' && current_line_is_blank) // wenn neue Zeile und Leerzeile empfangen
150
          {
151
            // Standard HTTP Header senden
152
            client.println("HTTP/1.1 200 OK");
153
            client.println("Content-Type: text/html");
154
            client.println("Connection: close");
155
            client.println();
156
157
            // Website laden
158
            //webFile = SD.open("index.htm");
159
160
            char HTTP_req[REQ_BUF_SZ] = {0};
161
162
            if (StrContains(HTTP_req, "GET / ") || StrContains(HTTP_req, "GET /index.htm"))
163
            {
164
              webFile = SD.open("index.htm");
165
            }
166
            else if (StrContains(HTTP_req, "GET /leuchten.htm"))
167
            {
168
              webFile = SD.open("leuchten.htm");
169
            }
170
            else if (StrContains(HTTP_req, "GET /einstellungen.htm"))
171
            {
172
              webFile = SD.open("einstellungen.htm");
173
            }
174
175
            if (webFile)
176
            {
177
              while (webFile.available())
178
              {
179
                client.write(webFile.read()); // Website an Client schicken
180
              }
181
              webFile.close();
182
            }
183
          }
184
185
186
          if (c == '\n')
187
          {
188
            current_line_is_blank = true;
189
          }
190
          else if (c != '\r')
191
          {
192
            current_line_is_blank = false;
193
          }
194
        }
195
      }
196
      delay(1);
197
      client.stop();
198
    }
199
    delay(1);
200
  }
201
}
202
203
204
char StrContains(char *str, char *sfind)
205
{
206
  char found = 0;
207
  char index = 0;
208
  char len;
209
210
  len = strlen(str);
211
212
  if (strlen(sfind) > len) {
213
    return 0;
214
  }
215
  while (index < len) {
216
    if (str[index] == sfind[found]) {
217
      found++;
218
      if (strlen(sfind) == found) {
219
        return 1;
220
      }
221
    }
222
    else {
223
      found = 0;
224
    }
225
    index++;
226
  }
227
228
  return 0;
229
}

von Christian M. (Gast)


Lesenswert?

Hast Du schon eine einfache TCP oder UDP Verbindung hingekriegt? Mit 
copy/paste kommst Du nicht weit!

Gruss Chregu

von PittyJ (Gast)


Lesenswert?

Noch mehr Serial.print() in loop einbauen, damit man sieht, wohin das 
Programm überhaupt kommt.


Vielleicht sollte man hier mal ein Tutorial über das Debuggen von 
Programmen erstellen. Wenn die Leute schon nicht auf die einfachsten 
Dinge kommen....

von Uwe D. (monkye)


Lesenswert?

Dem TO werden die Kritiken nicht wirklich helfen - wie wäre es mit einem 
Vorschlag WIE IHR DAS MACHT.

Wenn der Webserver nur eine Seite lädt, dann liegt das vielleicht an dem 
Teil Deines Codes, der nicht sichtbar ist. Wieviele Dateien kannst Du 
denn gleichzeitig öffnen (Datei Händler)?
Fragen:
Welchen Arduino verwendest Du - kann sein dass der RAM nicht reicht...?!
Funktionieren die verlinkten Webseiten auf dem PC im Browser?

Hinweis: Es fehlt noch ein ELSE-Zweig, denn Seiten die es auf dem Server 
nicht gibt sollen ja die übliche 404-Seite bekommen - und da 
sinnvollerweise mit einem Link auf die Index.html.

von Jonny H. (jonny123) Flattr this


Lesenswert?

Christian M. schrieb:
> Hast Du schon eine einfache TCP oder UDP Verbindung hingekriegt?

Ja, das ganze ist schon seit August lezten Jahres in Betieb. Allerings 
mit nur einer Seite.
Das ganze läuft mit folgendem Code:
1
 /************************
2
      Webformular anzeigen  *
3
    ************************/
4
    boolean current_line_is_blank = true;       // eine HTTP-Anfrage endet mit einer Leerzeile und einer neuen Zeile
5
6
    while (client.connected())
7
    {
8
      if (client.available())                   // Wenn Daten vom Server empfangen werden
9
      {
10
        char c = client.read();                 // empfangene Zeichen einlesen
11
        if (c == '\n' && current_line_is_blank) // wenn neue Zeile und Leerzeile empfangen
12
        { // Standard HTTP Header senden
13
          client.println("HTTP/1.1 200 OK");
14
          client.println("Content-Type: text/html");
15
          client.println("Connection: close");
16
          client.println();
17
18
          // Website von SD-Karte laden
19
          webFile = SD.open("index.htm");  // Website laden
20
21
          if (webFile)
22
          {
23
            while (webFile.available())
24
            {
25
              client.write(webFile.read()); // Website an Client schicken
26
            }
27
            webFile.close();
28
          }
29
          break;
30
        }
31
        if (c == '\n')
32
        {
33
          current_line_is_blank = true;
34
        }
35
        else if (c != '\r')
36
        {
37
          current_line_is_blank = false;
38
        }
39
      }
40
    }
41
    delay(1);
42
    client.stop();
43
  }
44
  delay(1);
45
}


Uwe D. schrieb:
> Fragen:
> Welchen Arduino verwendest Du - kann sein dass der RAM nicht reicht...?!
> Funktionieren die verlinkten Webseiten auf dem PC im Browser?
>
> Hinweis: Es fehlt noch ein ELSE-Zweig, denn Seiten die es auf dem Server
> nicht gibt sollen ja die übliche 404-Seite bekommen - und da
> sinnvollerweise mit einem Link auf die Index.html.

Ich verwende einen Arduino Mega
Der Ram reicht:

"Der Sketch verwendet 32.404 Bytes (12%) des Programmspeicherplatzes. 
Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 2.131 Bytes (26%) des dynamischen Speichers, 
6.061 Bytes für lokale Variablen verbleiben. Das Maximum sind 8.192 
Bytes."
1
            if (StrContains(HTTP_req, "GET / ") || StrContains(HTTP_req, "GET /index.htm"))
2
            {
3
              webFile = SD.open("index.htm");
4
            }
5
            else if (StrContains(HTTP_req, "GET /leuchten.htm"))
6
            {
7
              webFile = SD.open("leuchten.htm");
8
            }
9
            else if (StrContains(HTTP_req, "GET /einstellungen.htm"))
10
            {
11
              webFile = SD.open("einstellungen.htm");
12
            }
13
           else
14
            {
15
              webFile = SD.open("index.htm");
16
            }
Meinst du es so? Ich bin leider noch nicht so fit im Programmieren

von Uwe D. (monkye)


Lesenswert?

Guten Morgen Jonny,

beim Aufruf einer nicht vorhandenen Seite ist es üblich eine 404 - 
Dokument nich gefunden Seite zu bauen. Kannst Du Dir zu Hause auch 
sparen, aber das ist nebensächlich.

OK, RAM hat Dein Mega noch- prima.

Zudem würde ich die Antwort des Arduinos mit Client.prinln("HTTP/1.1 200 
OK") und den 3 Folgezeilen erst vor dem Senden der Webseite platzieren. 
So wie das Programm jetzt gebaut ist funktioniert nur GET als Methode, 
spätestens beim Schalten/Eingeben von Werten die an den Arduino gesendet 
werden sollen, brauchst Du auch POST.

Mal so am Rande: Gibts echt keine Beispiele mit mehr als einer 
HTML-Datei von SD-Card?

Bau doch ein paar (printline) Zeilen zum Debuggen ein, damit Du 
überhaupt siehst ob die Anfrage vom Browser die andere Datei enthält. 
Kann es sein, dass der Dateiname case sensitive behandelt wird 
(Groß-/Kleinschreibung) und deshalb die Datei auch nicht angezeigt wird?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.