Arduino Shield – Ethernet W5100 – Webserver via SD kaart (simpel)
Dit voorbeeld laat zien hoe je pagina en plaatjes kan tonen via een webbrowser vanaf de SD Kaart, het shield functioneert dan als een webserver.
Hardware: Arduino + Ethernet shield (W5100)
Wat heb je nodig?
1) Standaard wordt de ethernet bibliotheek al meegeleverd met de Arduino IDE.
2) SD Kaart geformatteerd FAT16/32.
Script
Ik heb hieronder het script voorbeeld van deze website een beetje aangepast, vereenvoudigd en de commentaar regels vertaald.
Wat doet het script?
Het script geeft een pagina (index.html) weer met een PNG plaatje, en een link naar een “2e pagina”.
Ps. onderaan deze pagina zijn de bestanden te downloaden die je op de SD kaart kan zetten
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
#include <SPI.h> // Importeer de SPI bibliotheek. #include <Ethernet.h> // Importeer de ehternet bibliotheek. #include <SD.h> // Importeer de SD kaart bibliotheek. // [INSTELLINGEN] byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // Vul het MAC address van de shield in (deze mag je ook verzinnen). IPAddress ip(192, 168, 0, 177); // Kies een vast IP adres in de range van je subnet. int poort = 80; //80 is standaard HTTP. // [VARIABELEN] #define REQ_BUF_SZ 20 // Buffergrootte voor HTTP aanvragen. File webFile; char HTTP_req[REQ_BUF_SZ] = {0}; // gebufferde HTTP aanvraag opgeslagen als een 'null terminated' string. char req_index = 0; // index naar HTTP_req buffer EthernetServer server(poort); // Intialiseer de ethernet server bibliotheek met de poort om te gebruiken. void setup() { pinMode(10, OUTPUT); digitalWrite(10, HIGH); // Schakel Ethernet chip uit. Serial.begin(9600); // Start de seriele poort. // Initialiseer SD Kaart Serial.print("- Initialiseren SD kaart..."); if (!SD.begin(4)) { Serial.println("GEFAALD!"); return; } else { Serial.println("OK"); } // Controleer of het bestand index.htm bestaat. Serial.print("- Bestand index.htm aanwezig..."); if (!SD.exists("index.htm")) { Serial.println("NEE!"); return; } else { Serial.println("OK"); } Ethernet.begin(mac, ip); // Start de Ethernet connectie. server.begin(); // Start de server. Serial.print("[-- De server is actief op IP: "); Serial.print(Ethernet.localIP()); Serial.println(" --]"); } void loop() { EthernetClient client = server.available(); // Luister naar aanvraag van clienten. if (client) { // Er is een nieuwe client aanvraag. Serial.println("[-- Nieuwe client --]"); // Elke HTTP aanvraag eindigd in een lege lijn. boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { // Er is client data aanwezig. char c = client.read(); // Lees 1 byte van de client data. // Buffer het eerste gedeelte van de HTTP aanvraag in de string "HTTP_req array". // Laat het laaste element in de array als 0 om de string te beeindigen met "null" (REQ_BUF_SZ - 1) if (req_index < (REQ_BUF_SZ - 1)) { HTTP_req[req_index] = c; // Bewaar de HTTP aanvraag karakters in een array. req_index++; } Serial.write(c); // Print het karakter naar de seriele monitor. if (c == '\n' && currentLineIsBlank) { // We hebben hier een nieuwe lijn ontvangen en de volgende lijn is leeg, // het verzoek is beeindigd, we kunnen nu een reactie terugsturen. // Open de gevraagde pagina of bestand. if (strstr(HTTP_req, "GET / ") || strstr(HTTP_req, "GET /index.htm")) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connnection: close"); client.println(); webFile = SD.open("index.htm"); } else if (strstr(HTTP_req, "GET /pagina2.htm")) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connnection: close"); client.println(); webFile = SD.open("pagina2.htm"); } else if (strstr(HTTP_req, "GET /plaatje.png")) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: image/png"); client.println("Connnection: close"); client.println(); webFile = SD.open("plaatje.png"); } if (webFile) { while(webFile.available()) {client.write(webFile.read());} // Stuur de gegevens naar de client webFile.close(); } // Reset buffer index en alle buffer elementen naar 0. req_index = 0; StrClear(HTTP_req, REQ_BUF_SZ); break; // Dit is nodig om de connectie te beeindigen. } if (c == '\n') {currentLineIsBlank = true;} // Laatste karakter ontvangen van de client, start een nieuwe lijn met volgende karakters. else if (c != '\r') {currentLineIsBlank = false;} // Je hebt een nieuw karakter ontvangen van de client. } } delay(1); // Geef de browser wat tijd om de data te ontvangen. client.stop(); // Sluit de connectie. Serial.println("[-- Client verbroken --]"); Serial.println(""); } } // Zet elk element van str naar 0 (maak de array leeg) void StrClear(char *str, char length) { for (int i = 0; i < length; i++) {str[i] = 0;} } |
Meer pagina’s of bestanden toevoegen.
Je ziet dat er requests gedaan worden door de client om een bestand of pagina op de halen, deze moet je dan (zoals ze noemen: hardcoded) aan de code toevoegen.
Laadtijden
De laattijd van een plaatje is aanzienlijk (11KB = 3 SEC), het is raadzaam om (kleine) PNG bestanden te laden vanaf de SD kaart
Resultaat browser:
Resultaat Seriele monitor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
- Initialiseren SD kaart...OK - Bestand index.html aanwezig...OK [-- De server is actief op IP: 192.168.0.177 --] [-- Nieuwe client --] GET /index.htm HTTP/1.1 Host: 192.168.0.177 Connection: keep-alive Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 Referer: http://192.168.0.177/pagina2.htm Accept-Encoding: gzip, deflate, sdch Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4 [-- Client verbroken --] [-- Nieuwe client --] GET /plaatje.png HTTP/1.1 Host: 192.168.0.177 Connection: keep-alive Cache-Control: max-age=0 Accept: image/webp,image/*,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 Referer: http://192.168.0.177/index.htm Accept-Encoding: gzip, deflate, sdch Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4 [-- Client verbroken --] [-- Nieuwe client --] GET /favicon.ico HTTP/1.1 Host: 192.168.0.177 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 Accept: */* Referer: http://192.168.0.177/index.htm Accept-Encoding: gzip, deflate, sdch Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4 [-- Client verbroken --] |
Ps. Bovenstaande client is de browser Chrome, je ziet dat deze browser ook altijd een aanvraag doet om het favicon.ico bestand op te halen.
[#/arduino/arduino_ethernet_w5100_webserver_sdkaart_bestanden” ]