Arduino als Webserver einrichten und Webpage von SD-Karte laden

Arduino + Ethernet ShieldIn diesem Beitrag möchte ich zeigen, wie man einen Arduino als Webserver einrichtet, wie man ein Webformular von der, auf dem Ethernet Shield integrierten Micro-SD-Karte lädt und wie man über dieses Webformular Pins des Arduino steuern kann.

Für dieses Beispiel benötigen Sie auf jeden Fall einen Arduino, ein Ethernet-Shield und eine Micro-SD-Karte die in den Slot auf dem Ethernet Shield geschoben wird.

 

Arduino-Sketch

void setup()

Dieses Sketch stellt beim starten oder nach einem Reset eine Ethernet-Verbindung her und startet den Server, der über die in Zeile 7 angegebene IP aufgerufen wird. Danach wird die SD-Karte initialisiert. War diese Initialisierung erfolgreich, dann wird nach der Datei index.htm gesucht, die sich im Root-Verzeichnis auf der SD-Karte befinden muss.

void loop()

In der Funktion loop werden zwei Sachen abgearbeitet. Einerseits wird beim aufrufen der Server IP eine Website angezeigt und andererseits wird ständig auf Anfragen gelauscht die über diese Webseite gesendet werden.

Eine Anfrage wird dann empfangen, wenn Sie im Webbrowser den Server aufrufen indem Sie die oben angegebene ip aufrufen und anschließend einen Port am Arduino schalten indem Sie in dem zu sehenden Webinterface einen Button anklicken um einen Verbraucher ein- bzw. auszuschalten.



Wenn Sie auf einen der Buttons klicken, wird eine Anfrage wie “/?pinD6=1″ an den Arduino gesendet. D steht in diesem Fall für Digital. Möglich wäre auch die Angabe eines A für das schalten eines analogen Pins. Die Zahl hinter diesem Buchstaben steht für die PinNr auf dem Arduino. Die 1 hinter dem = Zeichen bedeutet dass dieser Pin auf HIGH oder bei Angabe einer 0 auf LOW geschaltet wird. Die Angabe “/?pinD6=1″ schaltet also den Digitalen Pin 6 auf HIGH.

Der Arduino durchsucht nun die Anfrage und schaut nach dem Teilstring “pin”. Wenn dieser gefunden wurde. werden die einzelnen Bestandteile der Anfrage in “typ”, “pin” und “val” gespeichert. Danach wird je nach empfangenen Typ entweder ein Digitaler oder ein Analoger Ausgang auf dem Arduino geschaltet.

#if ARDUINO > 18
#include <SPI.h> // Für Arduino Version größer als 0018
#endif
#include <Ethernet.h>
#include <TextFinder.h>
#include <SD.h>

byte mac[] = { 0x5A, 0xA2, 0xDA, 0x0D, 0x56, 0x7A }; // MAC-Adresse des Ethernet-Shield
byte ip[]  = { 192, 168, 2, 102 };                   // IP zum aufrufen des Webservers
byte sdPin = 4;                                      // Pin der SD-Karte

EthernetServer server(80);                           // Server port

File webFile;

void setup()
{  
  Ethernet.begin(mac, ip); // Client starten
  server.begin();          // Server starten
  Serial.begin(9600);
  Serial.println("ARDUINO - STEUERUNG");

  Serial.println("Initialisiere SD-Karte...");
  if (!SD.begin(sdPin)) 
  {
    Serial.println(" - Initialisierung der SD-Karte fehlgeschlagen!");
    return;
  }
  Serial.println(" - SD-Karte erfolgreich initialisiert.");

  if (!SD.exists("index.htm")) 
  {
    Serial.println(" - Datei (index.htm) wurde nicht gefunden!");
    return;
  }
  Serial.println(" - Datei (index.htm) wurde gefunden.");

  Serial.println();
  Serial.println("Verbraucher schalten");
}

void loop()
{
  EthernetClient client = server.available(); // Auf Anfrage warten

  if(client)
  {
    /*****************************************
      Ausgänge über das Webformular steuern  *
    *****************************************/
    TextFinder finder(client);

    if(finder.find("GET"))
    {
      while(finder.findUntil("pin", "\n\r"))
      {
        char typ = client.read();
        int  pin = finder.getValue();
        int  val = finder.getValue();

        if(typ == 'D')
        {
          pinMode(pin, OUTPUT);
          digitalWrite(pin, val);
          Serial.print(" - D"+String(pin));
        }
        else if(typ == 'A')
        {
          analogWrite(pin, val);
          Serial.print(" - A"+String(pin));
        }
        else Serial.print(" - Falscher Typ");

        if(val==1) Serial.println(" ein"); else Serial.println(" aus");
      }
    }

    /************************
      Webformular anzeigen  *
    ************************/
    boolean current_line_is_blank = true;       // eine HTTP-Anfrage endet mit einer Leerzeile und einer neuen Zeile

    while (client.connected()) 
    {
      if (client.available())                   // Wenn Daten vom Server empfangen werden
      {
        char c = client.read();                 // empfangene Zeichen einlesen
        if (c == '\n' && current_line_is_blank) // wenn neue Zeile und Leerzeile empfangen
        { // Standard HTTP Header senden
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();

          // Website von SD-Karte laden
          webFile = SD.open("index.htm");  // Website laden
          if (webFile)
          {
            while(webFile.available())
            {
              client.write(webFile.read()); // Website an Client schicken
            }
            webFile.close();
          }
          break;
        }
        if (c == '\n') 
        {
          current_line_is_blank = true;
        } 
        else if (c != '\r') 
        {
          current_line_is_blank = false;
        }
      }
    }
    delay(1);
    client.stop();
  }
}

 

ArduinoWebServerPage

test.htm

Diese Datei kopieren Sie einfach ins Root-Verzeichnis auf der SD-Karte. Die SD-Karte können Sie anschließend in den Micro-SD-Slot auf dem Ethernet-Shield stecken.

<!DOCTYPE html>
<html>
<head>
  <title>Arduino Steuerung</title>
  <style type="text/css">
    h2 { margin-bottom:5px; }
  </style>
</head>
<body>

  <h1>Heizungssteuerung</h1>

  <h2>Digital Pin3:</h2>
  <a href="/?pinD3=1" target="ifr">Ein</a>
  <a href="/?pinD3=0" target="ifr">Aus</a>
  <br>
  <br>        
  <h2>Digital Pin6:</h2>
  <a href="/?pinD6=1" target="ifr">Ein</a>
  <a href="/?pinD6=0" target="ifr">Aus</a>

  <iframe name="ifr" style="display:none;" width="0" height="0"></iframe>
</body>
</html>



reichelt elektronik – Elektronik und PC-Technik

Über Enrico S.

Programmierer, Webdesigner, Grafiker, Blogger, Screencaster, Arduino- und eMobility Enthusiast. nefilim3006 ist auch bei Google+ vertreten

22 Kommentare zu “Arduino als Webserver einrichten und Webpage von SD-Karte laden

  1. Es gibt eine Beschränkung. Die Größe der SD Karte sollte bis 32GB funktionieren.
    Ich selber habe 32GB SD Karten ohne Probleme verwendet.

  2. Toll, bei mir geht es und es macht lust auf mehr,
    Beim Versuch auf dem Arduino gleichzeitig ein i2c Display anzusteuern bin ich aber gescheitert. Sobald ein ” lcd.print(“Webserver gestartet”); ” ausgeführt wird, ist die Website nicht mehr erreichbar.

    Was mache ich falsch?

    Mein kompletter Code sieht jetzt so aus:

    #if ARDUINO > 18
    #include // Für Arduino Version größer als 0018
    #endif
    #include
    #include
    #include

    //JS Display
    #include
    #include

    LiquidCrystal_I2C lcd(0x3F,20,4); // set the LCD address to 0x3F for a 20 chars and 4 line display

    //JS Display END

    byte mac[] = { 0x5A, 0xA2, 0xDA, 0x0D, 0x56, 0x7A }; // MAC-Adresse des Ethernet-Shield
    byte ip[] = { 192, 168, 178, 222 }; // IP zum aufrufen des Webservers
    byte sdPin = 4; // Pin der SD-Karte

    EthernetServer server(80); // Server port

    File webFile;

    void setup()
    {
    Ethernet.begin(mac, ip); // Client starten
    server.begin(); // Server starten
    Serial.begin(9600);
    Serial.println(“ARDUINO – STEUERUNG”);

    Serial.println(“Initialisiere SD-Karte…”);
    if (!SD.begin(sdPin))
    {
    Serial.println(” – Initialisierung der SD-Karte fehlgeschlagen!”);
    return;
    }
    Serial.println(” – SD-Karte erfolgreich initialisiert.”);

    if (!SD.exists(“index.htm”))
    {
    Serial.println(” – Datei (index.htm) wurde nicht gefunden!”);
    return;
    }
    Serial.println(” – Datei (index.htm) wurde gefunden.”);

    Serial.println();
    Serial.println(“Verbraucher schalten”);

    //JS Display
    lcd.init(); // initialize the lcd
    lcd.init();
    // Print a message to the LCD.
    lcd.backlight();
    lcd.setCursor(0,0);
    lcd.print(“Webserver gestartet”);
    // lcd.setCursor(0,1);
    // lcd.print(“IP 192.168.178.222″);

    //JS Display END
    }

    void loop()
    {
    EthernetClient client = server.available(); // Auf Anfrage warten

    if(client)
    {
    /*****************************************
    Ausgänge über das Webformular steuern *
    *****************************************/
    TextFinder finder(client);

    if(finder.find(“GET”))
    {
    while(finder.findUntil(“pin”, “\n\r”))
    {
    char typ = client.read();
    int pin = finder.getValue();
    int val = finder.getValue();

    if(typ == ‘D’)
    {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, val);
    Serial.print(” – D”+String(pin));
    }
    else if(typ == ‘A’)
    {
    analogWrite(pin, val);
    Serial.print(” – A”+String(pin));
    }
    else Serial.print(” – Falscher Typ”);

    if(val==1) Serial.println(” ein”); else Serial.println(” aus”);
    }
    }

    /************************
    Webformular anzeigen *
    ************************/
    boolean current_line_is_blank = true; // eine HTTP-Anfrage endet mit einer Leerzeile und einer neuen Zeile

    while (client.connected())
    {
    if (client.available()) // Wenn Daten vom Server empfangen werden
    {
    char c = client.read(); // empfangene Zeichen einlesen
    if (c == ‘\n’ && current_line_is_blank) // wenn neue Zeile und Leerzeile empfangen
    { // Standard HTTP Header senden
    client.println(“HTTP/1.1 200 OK”);
    client.println(“Content-Type: text/html”);
    client.println(“Connection: close”);
    client.println();

    // Website von SD-Karte laden
    webFile = SD.open(“index.htm”); // Website laden
    if (webFile)
    {
    while(webFile.available())
    {
    client.write(webFile.read()); // Website an Client schicken
    }
    webFile.close();
    }
    break;
    }
    if (c == ‘\n’)
    {
    current_line_is_blank = true;
    }
    else if (c != ‘\r’)
    {
    current_line_is_blank = false;
    }
    }
    }
    delay(1);
    client.stop();
    }
    }

Kommentar verfassen