Example self-announcing webserver which controls a servo through a smallHTML userinterface.

Dependencies:   mbed

main.cpp

Committer:
dirkx
Date:
2010-08-14
Revision:
0:a259777c45a3

File content as of revision 0:a259777c45a3:

#include "mbed.h"

#include "Servo.h"

#include "EthernetNetIf.h"
#include "HTTPServer.h"

#include "mDNSResponder.h"

#include "RestMeterHandler.h"


#define __DEBUG
#include "dbg/dbg.h"

// Hardware I/O
//
Servo myservo(p21);
DigitalOut netPoll(LED1);
DigitalOut servoChange(LED2);

// Ethernet, webserver and Bonjour responder
//
EthernetNetIf eth;
HTTPServer srv;
mDNSResponder mdns; // make sure LWIP_IGMP is set in netCfg.h !

#define MYNAME "Ampere Meter"   // Human readable/descriptive name
#define LUDN "amp-meter"        // Local unqualified DNS name

#define RANGE 0.80    // scale of 0 .. 1 -- see Servo 
#define MIN 0.36      // scale of 0 .. 1
#define STEP (RANGE / 20)

float pos = MIN + RANGE/2;

const char * restCallback(const char * cmd)
{
  static char resp[2048];
  
  if (cmd && (!strcmp(cmd,"min")))
    pos -= STEP;
  if (cmd && (!strcmp(cmd,"plus")))
    pos += STEP;
  
  if (pos > MIN+RANGE) pos = MIN + RANGE;
  if (pos < MIN) pos = MIN;

  myservo = pos;
  servoChange = !servoChange;

  snprintf(resp, sizeof(resp), 
    "<head><title>%s</title></head>"
    "<body>"
    "<center><h1><hr/>%s<hr/></h1>", MYNAME, MYNAME);

  // small HTML table to give a visual display
  // of the value as a VU style bar.
  snprintf(resp+strlen(resp), sizeof(resp)-strlen(resp),
    "<table cellpadding=2><tr>");

  for(int i = 0; i < 20; i++) 
    snprintf(resp+strlen(resp), sizeof(resp)-strlen(resp),
      "<td bgcolor=%s width=10px height=10px>&nbsp;</td>",
        ((pos - MIN) * 20 / RANGE > i) ? "444444" : "dddddd");
        
  snprintf(resp+strlen(resp), sizeof(resp)-strlen(resp),
      "</tr><table><br>");

  // footer with the 2 plus/minus command options.
  //        
  snprintf(resp+strlen(resp), sizeof(resp)-strlen(resp),
    "<a href='?cmd=min'>&lt;</a> <font size=+5>[%1.3f]</font> <a href='?cmd=plus'>&gt;</a>"
    "</center></body>", pos);
    
    return resp;   
}

int main() {
    DBG("\n\r\n\r"
        "Compiled " MYNAME " (" LUDN ") on " __DATE__ " " __TIME__ 
        "\r\n"
    );
    netPoll = 0;

    // middle the servo
    pos = MIN + RANGE/2;
    myservo = pos;

    EthernetErr ethErr = eth.setup();
    if (ethErr) {
        printf("Error %d in setup on DHCP.\r\n", ethErr);
        return -1;
    }
    
    // for general static content.    
    FSHandler::mount("/webfs", "/htdocs");     // Mount /webfs path on html docroot
    srv.addHandler<FSHandler>("/icons");      
    
    // handling the commands/dynamic pages
    //    
    RestMeterHandler::attach(&restCallback);
    srv.addHandler<RestMeterHandler>("/");
    
    // start the webserver    
    srv.bind(80);
    
    // Announce above web server - and keep doing that every minute or so.
    //
    mdns.announce(
        eth.getIp(),                // (My) IP address - where announced service runs.
        LUDN,                       // DNS name server or service
        "_http._tcp",               // protocol
        80,                         // Port number
        MYNAME,                     // User interface name service
        (char *[]) {                // NULL terminated list of KV's = see                                     
            "path=/",               // http://www.zeroconf.org/Rendezvous/txtrecords.html
            NULL
        }
    );
    
#if __DEEBUG
    Ip ip = eth.getIp();
    DBG("Visible as http://" LUDN ".lcoal/ or http://%d.%d.%d.%d/\r\n", ip[0],ip[1],ip[2],ip[3]);
#endif
    
    netPoll = 1;
    unsigned char c = 0;
    while(true) {
        netPoll = ! netPoll;    // flash net polling LED for geedback.
        Net::poll();
    }
} // main