Internet Of Things

Sunday, 8 June 2014

Embedded Web Server Using ARM

Abstract

Computer communication systems and especially the Internet are playing an important role in the daily life. Using this knowledge many applications are imaginable. Home automation, utility meters, appliances, security systems, card readers, and building controls, which can be easily, controlled using either special front-end software or a standard internet browser client from anywhere around the world.

Web access functionality is embedded in a device to enable low cost widely accessible and enhanced user interface functions for the device. A web server in the device provides access to the user interface functions for the device through a device web page. A web server can be embedded into any appliance and connected to the Internet so the appliance can be monitored and controlled from remote places through the browser in a desktop.

The aim of the project is to control the devices or equipment’s from the remote place through a web page. Here all the devices, which are to be controlled, are connected to the Arm 7 evaluation board. The web-server circuit is connected to LAN or Internet. The client or a person on the PC is also connected to same LAN or Internet. By typing the IP-address of LAN on the web browser, the user gets a web page on screen; this page contains all the information about the status of the devices. The user can also control the devices interfaced to the web server by pressing a button provided in the web page.

Block Diagram
block-diagram-of-arm7-friendly-web




Concept

The aim of the project is to control the devices or equipment’s from the remote place through a web page. Here all the devices, which are to be controlled, are connected to the Arm 7 evaluation board. Initially connect the 9V adaptor with ARM 7 Evaluation Board and Connect the SPI Ethernet Board using 10 pin FRC cable, then Program the ARM 7 with Flash magic. Connect Ethernet cable to SPI Ethernet Board. From end user side type the IP address 192.168.1.60 and this web page will be opened. Web page is created using HTML program and the device is controlled through Ethernet, user can control the Device from kit side or from this web page

Hardware requirements

  • ARM 7 (LPC 2148) Microcontroller (ARM7 Evaluation Board)
  • Power Supply (9V Adaptor, 5V Adaptor)
  • SPI Ethernet Board
  • 10 pin FRC cable
  • LAN cable

Software requirements

  • Programming Language: Embedded C
  • KEIL U Vision IDE
  • Flash magic

ARM& LPC214x

WEB SERVER

Reload

ADC
AN0
0
 
AN1
0
 
 

P1[31..24]
BUTTON #0
ON
BUTTON #1
ON
BUTTON #2
ON
BUTTON #3
ON
BUTTON #4
ON
BUTTON #5
OFF
BUTTON #6
ON
BUTTON #7
ON
 

P1[23..16]
LED #0
OFF
Toggle
LED #1
OFF
Toggle
LED #2
OFF
Toggle
LED #3
OFF
Toggle
LED #4
OFF
Toggle
LED #5
OFF
Toggle
LED #6
OFF
Toggle
LED #7
OFF
Toggle
 

This project aims at implementing embedded web server for temperature measurement, LED and Switch control. Here the embedded microcontroller is programmed to act as the web server. The web page is designed and uploaded in the embedded microcontroller. Since, the Internet is the network of networks we can access this web server from anywhere in the world. If anyone wants to access the web server for device control automation, he has to enter the domain name of the web page in the browser of his/her PC. Each PC, which has Internet connection, is identified by the unique address called IP address. The communication within this network is established with the help of IP addresses. The Ethernet controller receives the request from the user PC. The Ethernet controller is the stand-alone device in which the function of the Ethernet protocol is written. The Ethernet controller checks whether the incoming information corresponds to it or not. If the information corresponds to it, the information is conveyed from Ethernet controller to embedded microcontroller. Otherwise it is ignored. After receiving the requisition from the user PC the web page designed in the web server is sent. So, the user can see the web page in his PC. The software model for device control automation is developed in the web page. The user can control the device control unit from his PC by accessing with web page. If the user accesses the web page the commands to control the automation unit is sent to the web server. The embedded microcontroller process the information. The embedded microcontroller controls the device control automation unit as per the command.

Basics of TCP/IP, cables and connectors

TCP/IP Protocol Suite

The Ethernet system is also referred to as the TCP/IP protocol suite, which is named after two of the most important protocols in it: the Transmission Control Protocol (TCP) and the Internet Protocol (IP), which were also the first two networking protocols defined. The TCP/IP protocol suite is layered protocol with four layers.


tcp-ip-protocol-layer


  • Lowest Level Protocol – “Sending & Receiving Data” – any data-using specific network hardware.
  • Top Level Protocol – Designed specifically for tasks like “Transferring files or delivering emails”.
  • In – between Protocols – Concerned with “Routing & Reliability”.

Connectors and Cables

  • Color-coding is used to fit the cables properly
  • PC to PC - crossed wiring (TX+ is connected with TX+ and TX- is connected with TX-)
  • PC to Hub/Hub to PC - Straight wiring is used (TX+ is connected with RX+ and TX- is connected with RX-)


connectors-and-cables


Pin Number
Color Code
Specification
1
2
3
4
5
6
7
8
White/Orange
Orange/White
White/Green
Blue/White
White/Blue
Green/White
White/Brown
Brown/White
TX+
TX-
RX+
NC
NC
RX-
Power Over Ethernet
Power Over Ethernet
 

Data Format

A frame sent on the cable has eight different fields. Except the data and pad fields, the lengths of fields are fixed. The first field, preamble, is sent at the beginning of every frame. It synchronizes the receiving devices in every MAC unit before the important frame contents are received. The bit pattern of the preamble field is just 7 bytes of the pattern 10101010. The start-Of-frame delimiter (SFD) is the single byte 10101011 which follows the preamble and indicates the start of a valid frame. The destination and source addresses indicate the addresses of the DTEs that the packet is going to and coming form. Each address field can be either 16 or 48 bits, depending on the installation of the LAN. The first bit of the destination address field denotes whether the address is an individual address or a group address. The length indicator field is 2 bytes that informs about the number of bytes in the data field. The data field contains the data to be sent. If the length of the data field is less than the lower limit, sequences of bytes are added as the pad field. Lastly, the frame check sequence (FCS) field contains a four byte CRC value that is used for error detection.


frame-check-sequence


Source code



/* Project name:
     DEMO (Ethernet controller ENC28J60 mini library)
    
 * Description:
        This library is designed to embed tiny servers.
        No Ethernet knowledge is necessary to use it.
        It has a very small footprint.

        Features:
                Driver for ENC28J60 Microchip SPI Ethernet controller
                Supports IPV4 protocol
                Does not support fragmented packets
                Replies to :
                        - ARP requests
                        - ICMP echo requests
                        - UDP requests
                        - TCP requests (no stack, no packet reconstruction)
 * Test configuration:
     MCU:             LPC21xx
     Oscillator:      12.0 MHz (cclk = 60.0 MHz, Fcco = 240.0 MHz)
     SW:              KEIL uVision3 v3.50
     
 * BOARD NOTES:
     - Setup PC Ethernet Card "Speed and Duplex" to 10Mb/s Full Duplex
      (P0.7/SSEL0 must be high for SPI to operate)
     - From Command prompt try to ping IP address defined below (deault 192.168.20.60)
     - In web browser type URL http://192.168.20.60
*/

/********************************************************************************/
//                                                          Hardware settings (ADK Board)
/********************************************************************************/
//
// CN4 (LED)    - Connector (JP8) to LED Output    --> Port1 (P1.16 to P1.23)
// CN2(Switch) - Connector (JP12) to Switch Input -->  Port1(P1.24 to P1.31)
//
// SW33 - DIP Switch
// ==================
// Turn On - SCK, MISO, MOSI   (SPI Communication)
//
// SW34 - DIP Switch
// ==================
// Turn On - ETHR.CS, ETHR.RST, ETHR.INT, ETHR.WOL (Ethernet ENC28j60)
//
/********************************************************************************/
//                    In web browser type URL http://192.168.1.60
/********************************************************************************/

#include <LPC213X.H>
#include "string.h"

#include "ENC28J60.h"
#include "c_ctype.h"
#include "conv.h"
#include "Utility.h"

#define ENC28J60_HALFDUPLEX                0
#define ENC28J60_FULLDUPLEX                1

/************************************************************
 * ROM constant strings
 */
const unsigned char httpHeader[] = "HTTP/1.1 200 OK\nContent-type: ";          // HTTP header
const unsigned char httpMimeTypeHTML[] = "text/html\n\n";    // HTML MIME type
const unsigned char httpMimeTypeScript[] = "text/plain\n\n";    // TEXT MIME type
unsigned char httpMethod[] = "GET /";
/*
 * this HTML page calls the boards to get its status, and builds itself with javascript
 */
const char *indexPage = "<HTML><HEAD></HEAD><BODY>\
<h1> ARM& LPC214x </h1>\
<h2>  WEB SERVER  </h2>\
<a href=/>Reload</a>\
<script src=/s></script>\
<table><tr><td valign=top><table border=2 style=\"font-size:25px ;font-family: terminal ;\">\
<tr><th colspan=3>ADC</th></tr>\
<tr><td>AN0</td><td><script>document.write(AN0)</script></td></tr>\
<tr><td>AN1</td><td><script>document.write(AN1)</script></td></tr>\
</table></td><td><table border=1 style=\"font-size:15px ;font-family: terminal ;\">\
<tr><th colspan=3>P1[31..24]</th></tr>\
<script>\
var str,i;\
str=\"\";\
for(i=0;i<8;i++)\
{str+=\"<tr><td bgcolor=blue>BUTTON #\"+i+\"</td>\";\
if(PORT1_31_24&(1<<i)){str+=\"<td bgcolor=green>ON\";}\
else {str+=\"<td bgcolor=#cccccc>OFF\";}\
str+=\"</td></tr>\";}\
document.write(str) ;\
</script>\
</table></td><td>\
<table border=2 style=\"font-size:15px ;font-family: terminal ;\">\
<tr><th colspan=4>P1[23..16]</th></tr>\
<script>\
var str,i;\
str=\"\";\
for(i=0;i<8;i++)\
{str+=\"<tr><td bgcolor=orange>LED #\"+i+\"</td>\";\
if(PORT1_23_16&(1<<i)){str+=\"<td bgcolor=blue>ON\";}\
else {str+=\"<td bgcolor=#cccccc>OFF\";}\
str+=\"</td><td><a href=/t\"+i+\">Toggle</a></td></tr>\";}\
document.write(str) ;\
</script>\
</table></td></tr></table>\
This is HTTP request #<script>document.write(REQ)</script></BODY></HTML>\
";
/***********************************
 * RAM variables
 */
unsigned char myMacAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f}; // my MAC address
unsigned char myIpAddr[4] = {192, 168, 1, 60} ;// my IP address
unsigned char getRequest[15];                                                                                                // HTTP request buffer
unsigned char dyna[31];                                                                                                           // buffer for dynamic response
unsigned long httpCounter = 0;                                                                                               // counter of HTTP requests

/*******************************************
 * functions
 */
/*
 * put the constant string pointed to by s to the ENC transmit buffer
 */
unsigned long putConstString(const char *s)
{
    unsigned long ctr;      
    ctr = 0;
    while(*s)
    {
             ENC28J60_putByte(*s++);
             ctr++;
    }
    return(ctr);
}
       
/*
 * put the string pointed to by s to the ENC transmit buffer
 */
unsigned long putString(char *s)
{
    unsigned long ctr;
    ctr = 0;
    while(*s)
    {
             ENC28J60_putByte(*s++);
             ctr++;
    }
    return(ctr);
}

/*
 * this function is called by the library
 * the user accesses to the HTTP request by successive calls to ENC28J60_getByte()
 * the user puts data in the transmit buffer by successive calls to ENC28J60_putByte()
 * the function must return the length in bytes of the HTTP reply, or 0 if nothing to transmit
 *
 * if you don't need to reply to HTTP requests,
 * just define this function with a return(0) as single statement
 *
 */
unsigned long ENC28J60_userTCP(unsigned char *remoteHost, unsigned long remotePort, unsigned long localPort, unsigned long reqLength)
{
    unsigned long
             len,                                                   // my reply length
             i,                                                                 // general purpose integer
             bitMask;                                 // for bit mask

    // for parameters that are not used, skip compiler warnings "unreferenced parameter"
    i = (unsigned long) remoteHost;
    i = remotePort;
    i = reqLength;

    len = 0;
    bitMask = 0;

    if (localPort != 80)        // I listen only to web request on port 80
             return(0) ;
               
    // get 10 first bytes only of the request, the rest does not matter here
    for (i = 0; i < 10; i++)
             getRequest[i] = ENC28J60_getByte();
    getRequest[i] = 0;

    if (memcmp(getRequest, httpMethod, 5))                                                       // only GET method is supported here
             return(0);

    httpCounter++;                                                                                                            // one more request done

    if (getRequest[5] == 's')                                                                                      // if request path name starts with s, store dynamic data in transmit buffer
    {
             // the text string replied by this request can be interpreted as javascript statements by browsers
             len = putConstString(httpHeader);                                                          // HTTP header
             len += putConstString(httpMimeTypeScript);                     // with text MIME type

             // add AN0 value to reply
             IntToStr(0, dyna);
             len += putConstString("var AN0=");
             len += putString(dyna);
             len += putConstString(";");

             // add AN1 value to reply
             IntToStr(0, dyna);
             len += putConstString("var AN1=");
             len += putString(dyna);
             len += putConstString(";");

             // add PORT1[31..24] value (buttons) to reply
             len += putConstString("var PORT1_31_24=");
             IntToStr(((IOPIN1 >> 24) & 0xFF), dyna);
             len += putString(dyna);
             len += putConstString(";");
                       
             // add PORT1[23..16] value (LEDs) to reply
             len += putConstString("var PORT1_23_16=");
             IntToStr(((IOPIN1 >> 16) & 0xFF), dyna);
             len += putString(dyna);
             len += putConstString(";");

             // add HTTP requests counter to reply
             IntToStr (httpCounter, dyna);
             len += putConstString("var REQ=");
             len += putString(dyna);
             len += putConstString(";");
    }
    else if (getRequest[5] == 't')  // if request path name starts with t, toggle LED bit number that comes after
    {
             if (isdigit(getRequest[6])) // if 0 <= bit number <= 9, bits 8 & 9 does not exist but does not matter
             {
                       bitMask = getRequest[6] - '0';        // convert ASCII to integer
                       bitMask = 1 << (bitMask + 16);      // create bit mask
                       if ((IOPIN1 & bitMask) != 0)  // Toggled LED
                                IOCLR1 |= bitMask;
                       else
                                IOSET1 |= bitMask;
             }
    }

    if (len == 0)                                                                                                                             // what do to by default
    {
             len =  putConstString(httpHeader);// HTTP header
             len += putConstString(httpMimeTypeHTML); // with HTML MIME type
             len += putConstString(indexPage);                                                                   // HTML page     return (len);                                               // return to the library with the number of bytes to transmit
}
       
/*
 * this function is called by the library
 * the user accesses to the UDP request by successive calls to ENC28J60_getByte()
 * the user puts data in the transmit buffer by successive calls to ENC28J60_putByte()
 * the function must return the length in bytes of the UDP reply, or 0 if nothing to transmit
 *
 * if you don't need to reply to UDP requests,
 * just define this function with a return(0) as single statement
 *
 */
unsigned long ENC28J60_userUDP(unsigned char *remoteHost, unsigned long remotePort, unsigned long destPort, unsigned long reqLength)
{
    unsigned long
             len;                                                   // my reply length
    unsigned char
             *ptr;                                                 // pointer to the dynamic buffer

    // reply is made of the remote host IP address in human readable format
    ByteToStr(remoteHost[0], dyna);                               // first IP address byte
    dyna[3] = '.';
    ByteToStr(remoteHost[1], dyna + 4);               // second
    dyna[7] = '.';
    ByteToStr(remoteHost[2], dyna + 8);               // third
    dyna[11] = '.';
    ByteToStr(remoteHost[3], dyna + 12);   // fourth

    dyna[15] = ':';                                                                                                               // add separator

    // then remote host port number
    IntToStr(remotePort, dyna + 16);
    dyna[22] = '[';
    IntToStr(destPort, dyna + 23);
    dyna[29] = ']';
    dyna[30] = 0;

    // the total length of the request is the length of the dynamic string plus the text of the request
    len = 30 + reqLength;

    // puts the dynamic string into the transmit buffer
    ptr = dyna;
    while (*ptr)
             ENC28J60_putByte(*ptr++);

    // then puts the request string converted into upper char into the transmit buffer
    while (reqLength--)
             ENC28J60_putByte(toupper(ENC28J60_getByte()));

    return (len);                  // back to the library with the length of the UDP reply
}

/*
 * main entry
 */
int main (void)
{
    PINSEL0 = 0;
    PINSEL1 = 0;
    PINSEL2 &= 0x0000000C;
    delay_Nx10cyc(599999);                         // Delay 0,1s

    IODIR1 &= 0x00FFFFFF;                                     // Set P1[31..24] as inputs for buttons
    IODIR1 |= 0x00FF0000;                                     // Set P1[23..16] as outputs for LED
    IOCLR1 |= 0x00FF0000;                                    // Turn off LEDs
       
    // starts ENC28J60 with : RST bit on IOPIN0.13, CS bit on IOPIN0.12, my MAC & IP address, full duplex ENC28J60_Init(&IOPIN0, 13, &IOPIN0, 12, myMacAddr, myIpAddr, ENC28J60_FULLDUPLEX) ;

    while (1)
    {
             ENC28J60_doPacket();                   // process incoming Ethernet packets
             /*
             * add your stuff here if needed
             * ENC28J60_doPacket() must be called as often as possible
             * otherwise packets could be lost
             */
    }
}


 
Conclusion

A web server in the device provides access to the user interface functions for the device through a device web page. A web server can be embedded into any appliance and connected to the Internet so the appliance can be monitored and controlled from remote places through the browser in a desktop. We think this product have high potential for marketing in the future.

6 comments:

  1. I know this is one of the most meaningful information for me. And I'm animated reading your article. But should remark on some general things, the website style is perfect; the articles are great. Thanks for the ton of tangible and attainable help. Windows Hosting

    ReplyDelete
  2. Its really helpful for me, awaiting for more new post. Keep Blogging!hp printer support

    ReplyDelete
  3. I just got to this amazing site not long ago. I was actually captured with the piece of resources you have got here. Big thumbs up for making such wonderful blog page! google scholarship

    ReplyDelete
  4. Thanks for sharing this valuable information to our vision. You have posted a trust worthy blog keep sharing.
    hp envy 7800 driver
    hp envy 5052 driver
    hp envy 5055 printer setup

    ReplyDelete
  5. This is such a great resource that you are providing and you give it away for free. I love seeing blog that understand the value of providing a quality resource for free. trafficize software

    ReplyDelete