Using a simple Arduino 2009, an Ethernet shield and a common LCD is possible to make an interesting small and portable web-server. Following the code with a short descriptions.
What you need is to download and to install (
/****************************************************/
// Written by Marco Ramilli
#include //Ethernet Library by Arduino
#include "Dhcp.h" //DhCP Library
#include //Default String Library
#include // String Library, you have to download it from Arduino web-site
#include // Second String Library, you have to download it from Arduino web-site
#include //Liquid Crystal Output
/****************************************************/
Note1: I've used DHCP library even if a web server should have a static IP ... ...
Note2: I've divided everything in classes, in such way you can divide the code in multiple files.
//defining Pages CLass
class Pages
{
public:
Pages(char *header, char *pageStart, char *body, char *pageEnd) { _header = header; _pageStart = pageStart; _body = body; _pageEnd = pageEnd; }
char *getHeader(){return _header;}
char *getPageStart(){return _pageStart;}
char *getBody(){return _body;}
char *getPageEnd(){return _pageEnd;}
char *getPage(){strcat(_header,_pageStart); strcat(_header,_body); strcat(_header,_pageEnd); return _header; }
void appendToBody(char *stringToAppend){strcat(_body,stringToAppend); }
private:
char *_header;
char *_pageStart;
char *_body;
char *_pageEnd;
};
/****************************************************/
// defining Networkconfig Class
class NetworkConfig
{
public:
NetworkConfig(byte *mac, byte *ip){_mac = mac; _ip = ip;}
NetworkConfig(byte *mac, byte *ip, byte *mask, byte *gw, byte *dhcps, byte *dns) {_mac = mac; _ip = ip; _mask = mask; _gw = gw; _dhcps = dhcps; _dns = dns; }
void setIP(byte *ip){_ip = ip;}
void setMAC(byte *mac){_mac = mac;}
void setMASK(byte *mask){_mask = mask;}
void setGW(byte *gw){_gw = gw;}
void setDHCPS(byte *dhcps){_dhcps = dhcps;}
void setDNS(byte *dns){_dns = dns;}
byte *getIP(){return _ip;}
byte *getMAC(){return _mac;}
byte *getMASK(){return _mask;}
byte *getGW(){return _gw;}
byte *getDHCPS(){return _dhcps;}
byte *getDNS(){return _dns;}
private:
byte *_ip;
byte *_mac;
byte *_mask;
byte *_gw;
byte *_dhcps;
byte *_dns;
};
Of curse, if no DHCP is detected, the server wanna be on 192.168.1.50 .
/****************************************************/
//Defult Network Configuration instances
byte ip[] = { 192, 168, 1, 50 };
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
NetworkConfig defaultconf(mac, ip);
/****************************************************/
Here some useful cost to define.
/*****************************************************/
#define maxLength 25 // preventing BoF
#define serverPort 80 // listening port
String inString = String(maxLength);
Server server(serverPort);
int val, p;
LiquidCrystal lcd(8, 7, 6, 5, 4, 3, 2); //Declare a LDC display, for ping look over
/****************************************************/
Here the real interesting code... ...
void setup() // before going on, we need some stuff
{
Serial.begin(9600); // just for debugginh
lcd.begin(1,8); // configure LCD display size (raw, col)
if(!getNC()){
Ethernet.begin(defaultconf.getMAC(), defaultconf.getIP() );
}
server.begin();
}
/****************************************************/
void loop()
{
Client client = server.available(); //Gets a client that is connected to the server and has data available for reading
if (client) {
boolean current_line_is_blank = true; // html protocol ....
while (client.connected()) {
if (client.available()) { // client is sending something
p = 0; //lets see if the client wants initial page
char c = client.read(); //reading whatever the client sends
if (inString.length() < maxLength) { // currently there is no way to make it dinamic
inString.append(c);
Serial.println(inString); //Only To DEBUG !
}
if (c == '\n' && current_line_is_blank) { //means the client has stopped to end us chars
if (inString.contains("?")) { // means the client wanna communicate with us
int Pos_p = inString.indexOf("p");
p = atoi(inString.substring((Pos_p+2), (Pos_p+4)));
}
This case is useful to figure out POST and/or GET actions.
switch (p){
// due to BoF bug, actually is not possible to write index.getPage(). But late versions of Arduino ... ... ...
case 0:
printonlcd("Index");
client.println(index.getHeader() );
client.println(index.getPageStart() );
client.println(index.getBody() );
client.println(index.getPageEnd() );
break;
case 1:
printonlcd("Page_1");
client.println(page1.getHeader() );
client.println(page1.getPageStart() );
client.println(page1.getBody() );
client.println(page1.getPageEnd() );
break;
case 2:
printonlcd("Page_2");
client.println(page2.getHeader() );
client.println(page2.getPageStart() );
client.println(page2.getBody() );
client.println(page2.getPageEnd() );
break;
default:
printonlcd("Page_D");
client.println(index.getHeader() );
client.println(index.getPageStart() );
client.println(index.getBody() );
client.println(index.getPageEnd() );
break;
}
break;
}
if (c == '\n') {
current_line_is_blank = true;
} else if (c != '\r') {
current_line_is_blank = false;
}
}
}
delay(1);
inString = "";
client.stop();
}
}
Here how dchp library works, thank to Jordan Terrel
/****************************************************/
//DHCP client
int getNC(){
int result = Dhcp.beginWithDHCP(mac);
if (result == 1){
byte buffer[6];
Dhcp.getLocalIp(buffer);
Serial.print("ip address: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getSubnetMask(buffer);
Serial.print("subnet mask: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getGatewayIp(buffer);
Serial.print("gateway ip: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getDhcpServerIp(buffer);
Serial.print("dhcp server ip: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getDnsServerIp(buffer);
Serial.print("dns server ip: ");
printArray(&Serial, ".", buffer, 4, 10);
Serial.print("READY");
printonlcd("READY");
return 1;
}else{
Serial.print("No DHCP, Running in default conf");
printonlcd("DEFAULT");
return 0;
}
}
Here how LCD library works
/****************************************************/
void printonlcd(String text){
lcd.clear();
if (text.length() <= 7){
lcd.print(text);
lcd.blink();
}else{ // n with this lcd
int index =0;
while (index >=0){
delay(200);
for (int positionl = 0; positionl < 8; positionl ++){
lcd.scrollDisplayLeft();
delay(150);
}
for (int positionr = 0; positionr < 8; positionr ++){
lcd.scrollDisplayRight();
delay(150);
}
index--;
}
}
}
//printArray funciton
void printArray(Print *output, char* delimeter, byte* data, int len, int base){
char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int i = 0; i < len; i++)
{
if(i != 0)
output->print(delimeter);
output->print(itoa(data[i], buf, base));
}
output->println();
}
That's all !
Hope to be useful .