Maak een web interface voor je Arduino
Veel van de op Engineer@Home beschreven Arduino-projecten kunnen niet zonder een grafische user interface. Daarom beschrijf ik in dit artikel hoe je met behulp van een Ethernetshield een goede web interface voor je Arduino kunt bouwen.
Arduino Ethernet Shield
Het spreekt voor zich dat je, naast een Arduino, ook een Ethernetshield nodig hebt om via ethernet te kunnen communiceren. Met behulp van de webserver tutorial van de Arduino website kun je vervolgens een eenvoudige webpagina serveren om de poorten van je Arduino aan te sturen of uit te lezen. Allemaal leuk en aardig, maar het mag allemaal wel wat spannender, het oog wil ook wat!
HTML & CSS voor Arduino
Websites worden normaal gesproken geschreven in HTML en CSS: HTML voor de structuur, CSS voor de opmaak. De webserver tutorial tekent bijvoorbeeld een eenvoudige HTML-pagina zonder verdere opmaak. Zodra we deze pagina gaan uitbreiden en ook nog CSS-regels gaan toevoegen wordt het bestand al gauw erg groot. Zo groot zelfs dat het RAM-geheugen van de Arduino vol loopt. De eerste redding is dan het programma-geheugen wat je kunt benaderen met behulp van de pgmspace library.
Web pagina serveren vanaf SD-kaart
Met een beetje web-interface loopt het programma-geheugen ook al snel vol, maar gelukkig beschikt het ethernetshield over een micro-SD kaart aansluiting. Het zou ideaal zijn als we de HTML- en CSS-bestanden op de SD-kaart konden opslaan, en vanaf daar konden aanbieden via ethernet.
Met behulp van de SDFat-library kun je de micro-SD kaart benaderen, en in combinatie met de webserver tutorial kun je vervolgens de bestanden via het netwerk aanbieden. Er is alleen een probleem: vanaf SD kun je alleen statische bestanden aanbieden, hoe zorg je er dan voor dat je statussen van knoppen of sensors kan weergeven? Eigenlijk willen we een soort zeer eenvoudige PHP-oplossing maken. (PHP is een taal die bij websites wordt gebruikt om allerlei zaken aan HTML-pagina’s toe te voegen voordat ze naar de gebruiker worden gestuurd.)
Sensor data op je Arduino web interface
Goed, we willen een mooie webinterface weergeven met onze Arduino, zoveel mogelijk van de HTML en CSS moet op de SD-kaart staan om het geheugen van de Arduino te sparen, maar het moet wel mogelijk zijn voor de Arduino om daar dynamisch gegevens aan toe te voegen voordat het geheel via ethernet wordt verstuurd.
Om het zo eenvoudig mogelijk te maken ga ik geen volledige PHP-implementatie bouwen of een nieuwe programmeertaal uitvinden. Omdat ik maar één pagina serveer weet ik precies de volgorde van de diverse sensors en knoppen die ik wil invullen, het enige wat ik van de HTML-pagina wil weten is op welke plek ik de data moet invullen. Hiervoor gebruik ik een simpele marker in mijn HTML-document, het ASCII Control Character 28: de File Separator.
In een goede editor zoals Notepad++ worden deze control characters weergegeven, in Word of Kladblok zie je ze niet. Je typt een file-separator met ALT + 0028 (op het numpad). De Arduino kent hem gewoon als een char-waarde van 28 bij het uitlezen van de bestanden van SD.
HTML verwerken met de Arduino
Met behulp van de volgende code laat ik de Arduino het HTML-bestand parsen:
myFile.open("home.htm", O_READ);
Read_File_Upto_FS();
// huismodus
if (Status) {
client.print(F("aan"));
Read_File_Upto_FS();
client.print(F("uit"));
}
else {
client.print(F("uit"));
Read_File_Upto_FS();
client.print(F("aan"));
}
// etcetera...
De functie Read_File_Upto_FS() leest het html-bestand van de SD-kaart tot aan de File Separator, vervolgens voegt de Arduino de huisstatus in, en gaat Read_File_Upto_FS() weer verder tot aan de volgende File Separator.
void Read_File_Upto_FS() {
while ((buffer = myFile.read()) != 28) {
client.print((char)buffer);
}
}
Deze hele routine wordt overigens pas aangeroepen nadat de webserver een verbinding heeft opgezet, dus de client.print() schrijft de data meteen weg naar de webclient.
Grafische vormgeving van de web interface
De interface is responsive gebouwd met behulp van de nieuwste CSS3 technieken. Dit wil zeggen dat de widgets automatisch rangschikken voor zover de schermafmetingen dit toelaten. Ook de diverse gradients en dropshadows kunnen tegenwoordig eenvoudig met CSS worden gemaakt. Hieronder vind je een stukje van de CSS-code die de opmaak van de een blokje definieert.
li, li p a {
background: linear-gradient(top, #4d4d4d 0%, #333333 100%);
border-radius: 5px;
box-shadow: inset 1px 1px 0px 0px rgba(255, 255, 255, 0.5), 1px 1px 0px 0px rgba(0, 0, 0, 0.5);
}
li span {
border-radius: 5px 5px 0 0;
box-shadow: inset 1px 1px 0px 0px rgba(255, 255, 255, 0.5);
color: #fff;
display: block;
height: 23px;
padding: 5px 10px;
}
li span, li p a.aan {
background-color: #004080;
background: linear-gradient(top, #0066cc 0%, #004080 100%);
}
Om de gradients en box-shadows in diverse browsers goed te laten werken heb je soms nog wel vendor-prefixes nodig. Met de CSS3 generator verkrijg je in een keer de juiste codes.
Iconen voor de Arduino interface
De iconen voor de diverse apparaten en sensors kun je natuurlijk zelf maken, maar in dit geval ben ik lui geweest en heb ik ze gedownload van Iconfinder.com.
Ik hoop dat dit artikel genoeg handvatten biedt voor het zelf bouwen van een Arduino web interface. Mochten er toch nog vragen zijn stel ze dan hieronder, dan probeer ik ze daar te beantwoorden, of het artikel uit te breiden.
30-04-2014: Op veler verzoek kun je hier een voorbeeld van de web interface en een voorbeeld van de Arduino code voor de web interface downloaden.