Stap 1: Een pagina over falen
Hier zijn enkele dingen die ik geprobeerd... dat niet werkte. Dit zijn de gaten konijn dat ik stapte in en bijna leidde me te geven.
-Ten eerste heb ik geprobeerd om te laden alle pagina's js Vrijboord en alle bijbehorende afhankelijkheden normaal en gewoon voer ze rechtstreeks naar de client door het hergebruik van wifiwebserver en code uit een bekende arduino forumlid, zoomkat. Dit leidde me om te komen met iets wat je hier ziet:
/* Written for the Linkit One * A webserver that looks for index.html in the root dir of the onboard storage * and serves that page... * I am using this to test hosting freeboard for a few projects * Thanks to the user zoomkat on the arduino forums, * and the WifiWebServer and Storage example code from the linkit one team */#include <LTask.h> #include <LWifi.h> #include <LWifiClient.h> #include <LWifiServer.h> #include <LFlash.h> #include <LSD.h> #include <LStorage.h>#define WIFI_AP "blah" #define WIFI_PASSWORD "blah" #define WIFI_AUTH LWIFI_WPA#define Drv LFlash LWiFiServer server(80);String readString, pos;void setup() { pinMode(10, OUTPUT); Drv.begin(); LWiFi.begin(); Serial.begin(115200); // keep retrying until connected to AP Serial.println("Connecting to AP"); while (0 == LWiFi.connect(WIFI_AP, LWiFiLoginInfo(WIFI_AUTH, WIFI_PASSWORD))) { delay(1000); } printWifiStatus(); Serial.println("Start Server"); server.begin(); Serial.println("Server Started"); }int loopCount = 0;void loop() { // put your main code here, to run repeatedly: delay(500); loopCount++; LWiFiClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()){ if (client.available()){ // we basically ignores client request, but wait for HTTP request end char c = client.read(); //read char by char HTTP request if (readString.length() < 100) { //store characters to string readString += c; Serial.print(c); } //if HTTP request has ended if (c == '\n'){ Serial.println("readstring"); Serial.println(readString); if (readString.indexOf("freeboard") >=0){ client.println("HTTP/1.1 200 OK"); //send new page client.println("Content-Type: text/html"); client.println(); LFile myFile = Drv.open("index.html"); if (myFile) { while (myFile.available()) { client.write(myFile.read()); } myFile.close(); } } else { //if the file exists continue String filepath = readString.substring( (readString.indexOf("GET")+5),(readString.indexOf("HTTP")) ); char fullpath[1024]; filepath.toCharArray(fullpath,1024); Serial.println(filepath); String extension = filepath.substring( filepath.lastIndexOf(".") ); Serial.println(extension); if (true){ Serial.println("send response"); // send a standard http response header client.println("HTTP/1.1 200 OK"); if ((extension.indexOf("html") >=0) || (extension.indexOf("htm") >= 0) ){ client.println("Content-Type: text/html"); } if (extension.indexOf("css") >=0){ client.println("Content-Type: text/css"); } if (extension.indexOf("js") >=0){ client.println("Content-Type: application/javascript"); } if (extension.indexOf("map") >=0){ client.println("Content-Type: application/x-navimap"); } if (extension.indexOf("png") >=0){ client.println("Content-Type: image/png"); } client.println(); LFile myFile = Drv.open(fullpath); if (myFile) { while (myFile.available()) { client.write(myFile.read()); } myFile.close(); } } //if the file doesn't exist bail with 404 else{ client.println("HTTP/1.1 404"); client.println("Content-Tyep: text/html"); client.println(); client.println("404 file not found"); } } delay(100); // close the connection: Serial.println("close connection"); client.stop(); } } } }}void printWifiStatus() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(LWiFi.SSID()); // print your WiFi shield's IP address: IPAddress ip = LWiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); Serial.print("subnet mask: "); Serial.println(LWiFi.subnetMask()); Serial.print("gateway IP: "); Serial.println(LWiFi.gatewayIP()); // print the received signal strength: long rssi = LWiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm"); } For now we will focus on this part: if (myFile) { while (myFile.available()) { client.write(myFile.read()); } myFile.close(); } }
Wat hier gebeurt is dat als het bestand stream komt af van de geheugenruimte op de linkit een die het wordt gezet in een stream buffer in het RAM en vervolgens van die buffer gedumpt in de uitgaande wachtrijen van de netwerk stack. Dit stelt twee problemen:
Dat eerste buffer is eigenlijk vrij klein en het lezen van een bestand vanaf de ROM is niet bijzonder snel. Dus, wat je eindigen met zijn zeer langzame laden pagina's. Soms zijn ze een time-out of andere rare dingen doen. Ik wiresharked (https://www.wireshark.org/) de verbinding en het lijkt erop dat het alleen spuugt kleine pakketten van ongeveer 50 bytes (later begon dit zinvol voor mij als de buffer die wordt gebruikt wanneer het lezen van bestanden in waarschijnlijk ongeveer die grootte is). Vrijboord heeft eigenlijk een heleboel afhankelijkheden die het nodig heeft om te laden. Sommige van deze gelijktijdige dingen doen en dynamisch laden van spullen. Dit werkt niet in een eenvoudige lineaire programma. Waarschijnlijk zijn er manieren om dit werk op een arduino, maar niet gemakkelijk (een begin zou moeten kijk hier: https://learn.adafruit.com/multi-tasking-the-ardu... .
Ik probeerde met behulp van verschillende methoden van het lezen van het bestand in en ervoor te zorgen dat de buffer was bijna vol voordat meer gegevens worden verzonden naar de client. maar niet heel ver komen. Ik heb het ook geprobeerd met readUntil en haar varianten. Geen van deze deed de truc
Sommige geassorteerde Verwijzigingen doorgebladerd ik tijdens deze konijn gat verkenning:
http://forum.Arduino.CC/index.php?topic=279849.msg...
http://Playground.Arduino.CC/code/WebServerST
http://forum.Arduino.CC/index.php?topic=279849.msg...
https://www.Arduino.CC/en/Reference/StreamReadStr...
Tot slot ik brak en zocht iets heel licht om te voldoen aan mijn verlangen naar een grafische weergave van gegevens samen met de json-blootstelling van de gegevens. Wat ik kwam met rellies op de HTML-5 "meter" en/of "progress" elementen. Dit zijn hoofdzakelijk kleine bar grafieken maken zonder externe JS pagina bevat of zwaargewicht styling. Dit zijn de kale botten.
De paginacode die ik kwam met iets dergelijks keek (en werd gelezen door iets dergelijks de vermelding hierboven, maar met een toevoeging aan de batterij lezingen presenteren als json op /bat):
<!DOCTYPE html><html> <body> <h3>Simple Sensor Meters Demo</p> <p>battery(using meter element): <meter id="bat" min="0" max="100" value="0"></meter></p> <p>battery(using progress element): <progress id="batp" max="100" value="0"></meter></p> <p>charging: <h3 id="charging"></h3></p> <script>function Get(yourUrl){ var Httpreq = new XMLHttpRequest(); // a new request Httpreq.open("GET",yourUrl,false); Httpreq.send(); return Httpreq.responseText; } function updateMeters() { var jsonBat = JSON.parse(Get("/bat")); window.alert(jsonBat); document.getElementById("bat").value = jsonBat.batteryLevel; document.getElementById("batp").value = jasonBat.batteryLevel; document.getElementById("charging").innerHTML = jsonBat.chargingStatus; } updateMeters(); setInterval(updateMeters,5000); </script> </body> </html>
Ik kwam echter in een ander probleem met mijn code...
Als ik moest laden zou een HTML-pagina en die html-pagina proberen te doen een HTTP GET op iets op het linkit men dan niets zou gebeuren. Ik was verbaasd, totdat mij postuur op uiterlijk. De code was één schroefdraad en blokkeren. Dus, het was te wachten tot de beginpagina gebeurde laden de volgende pagina te laden. Dit nooit gebeurd, en dus het bleef steken.