/*********************************************************************************************
**********************************************************************************************
Dieses Programm dient der Initialisierung des Ethernet-Shields, des Starten des Webservers und
**************der Kommunikation zwischen dem Arduino und der Website.*************************
**Das Programm wurde von Kathrin Liedmann, Benedikt Schulte und Dominik Rebein im Rahmen des**
***********Elektrotechnik Fachpraktikums an Hochschule Hamm-Lippstadt entwickelt.*************
***************Die Grundstruktur stammt von der Seite http://www.fluuux.de.*******************
**********************************************************************************************
*********************************************************************************************/
#if ARDUINO > 18 // Überprüfung ob Arduino Version größer als 18
#include <SPI.h> // Einbinden der spi.h (Bibliothek)
#endif
#include <Ethernet.h> // Einbinden der benötigten Bibliotheken
#include <TextFinder.h>
#include <SD.h>
/************************
* Variablen Deklaration *
***********************/
boolean grillAn = false; // Erstellen der Variable grillAn und setzen des Ausgangswertes auf false
boolean statusrequest = true; // Unterscheidung, ob Daten abgerufen werden sollen oder die HTML Seite abgerufen werden soll
char actionString[16]; // Anlegen der Variable actionString vom Typ char
const int fileStringLength = 24; // Anlegen der Variable fileStringLength vom Typ const Integer für die Länge der Datenabfrage
const int typeLength = 6; // Anlegen der Variable typeLength vom Typ const int
char requestTypeString[typeLength];
char fileString[fileStringLength];
/**********************************
* Ethernetshield Grundeinstellungen *
**********************************/
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x57, 0x90 }; // MAC-Adresse des Ethernet-Shields (Steht auf dem Ethernetshield)
byte ip[] = { 192, 168, 0, 88 }; // IP zum aufrufen des Webservers festlegen
byte sdPin = 4; // Pin der SD-Karte am Arduino
EthernetServer server(80); // Server port festlegen
File webFile;
/********************************
* Ethernetshield Initialisieren *
********************************/
void setup()
{
Ethernet.begin(mac, ip); // Client starten
server.begin(); // Server starten
Serial.begin(9600); // Baudrate, also Anzahl der übertragenen Symbole pro Zeiteinheit
Serial.println("ARDUINO - STEUERUNG"); // Statusausgabe für den Serialmonitor
Serial.println("Initialisiere SD-Karte..."); // Statusausgabe für den Serialmonitor
if (!SD.begin(sdPin))
{
Serial.println(" - Initialisierung der SD-Karte fehlgeschlagen!"); // Statusausgabe für den Serialmonitor
return;
}
Serial.println(" - SD-Karte erfolgreich initialisiert."); // Statusausgabe für den Serialmonitor
if (!SD.exists("index.htm"))
{
Serial.println(" - Datei (index.htm) wurde nicht gefunden!"); // Statusausgabe für den Serialmonitor
return;
}
Serial.println(" - Datei (index.htm) wurde gefunden."); // Statusausgabe für den Serialmonitor
Serial.println(); // Leerzeile ausgeben
Serial.println("Verbraucher schalten"); // Statusausgabe für den Serialmonitor
}
/***************
* Hauptprogramm *
***************/
void loop()
{
EthernetClient client = server.available(); // Auf Anfrage warten
int requestType = 0; // Welche Art der Nachfrage (GET or POST);
int requestedFileLength = 0;
if(client)
{
/*****************************************
* Ausgänge über das Webformular steuern *
*****************************************/
TextFinder finder(client); // Den Befehl "finder" aus der Finderbibliothek laden
if(finder.getString("","/", requestTypeString,typeLength)) // Unterscheidung des Strings, GET or POST
{
if(String(requestTypeString) == "GET " ) // Wenn der String == GET dann requestType Variable auf 1
{
requestType = 1;
}
else if(String(requestTypeString) == "POST ") // Wenn der Strink == Post dann requestType Variable auf 2
{
requestType = 2;
}
// Ansammeln was nach dem / in das Array geschrieben wird
// Der Dateiname den der Client benötigt:
requestedFileLength = finder.getString("", " ", fileString, fileStringLength);
switch (requestType)
{
case 1: // GET Aufruf, Daten von der Seite werden abrufen
if (requestedFileLength < 2)
{
statusrequest = false;
Serial.println("HTML Steuerungsseite ausgeben");
}
else
{
statusrequest = true;
Serial.println("Status ausgeben");
}
break;
case 2: // POST, Schaltvorgang durchführen
// Hier wird nur nach der Länge des Anfragestrings unterschieden, da ein Suchen in der Anfrage nicht gut funktioniert hat (zu lange Wartezeiten)
Serial.println(requestedFileLength);
switch (requestedFileLength)
{
case 22: // /?action=switchgrillon = 22 Zeichen
//Hier muss die Variable aus dem Grillprogramm eingebunden werden: Code zum Anschalten bei Implementierung das Grillprogramm
//Aufruf als POST
grillAn = true;
Serial.println("Grill anschalten");
break;
case 23: // /?action=switchgrilloff = 21 Zeichen
//Hier muss die Variable aus dem Grillprogramm eingebunden werden:Code zum Abschalten bei Implementierung in Grillprogramm
//Aufruf als POST
grillAn = false;
Serial.println("Grill ausschalten");
break;
}
break;
}
}
/************************
* 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
switch (requestType) {
case 1: //GET, entweder Status oder Datei ausgeben
if(statusrequest){
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: application/json");
client.println("Access-Control-Allow-Origin: *");
client.println("Connection: close");
client.println();
client.print("{\"temperature\" : \"");
//Hier muss die Variable aus dem Grillprogramm eingebunden werden: Hier die Temperatur ausgeben
client.print(random(10,4000));
client.print("\", \"grillstatus\": \"");
//Hier muss die Variable aus dem Grillprogramm eingebunden werden: Hier den Grillstatus ausgeben
client.print(grillAn ? "an" : "aus");
client.println("\"}");
}
else
{
// Website von SD-Karte laden
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Access-Control-Allow-Origin: *");
client.println("Connection: close");
client.println();
webFile = SD.open("index.htm"); // Website laden
if (webFile)
{
while(webFile.available())
{
client.write(webFile.read()); // Website an Client schicken
}
webFile.close();
}
}
break;
case 2: //POST, wir kennen keine Fehlerfälle beim umschalten, geben immer OK zurück!
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: application/json");
client.println("Access-Control-Allow-Origin: *");
client.println("Connection: close");
client.println();
client.print("{\"result\" : \"OK\"}");
break;
}
break;
}
if (c == '\n')
{
current_line_is_blank = true;
}
else if (c != '\r')
{
current_line_is_blank = false;
}
}
}
delay(1);
client.stop();
}
}