Thursday, August 9, 2018

TCP IP + ENC28, HTTP Web Server Demo Application

Recently there’s a growing use of IoT (Internet of Thing) application in engineering solution. In this post I’m trying to make one project that related to Ethernet and IoT application.

I’m going to use ENC28J60 chip from Microchip. ENC28 chip has integrated MAC + PHY, it’s a very popular chip to implement some small to mid-level TCP/IP application. Communication with ENC28 is done through SPI.

I’m going to use this cheap board:
This small-sized ENC28 board is so much available and can be searched easily at online electronics component store. The board quality is not the best, I got one that I could say it’s not that pretty, but fortunately it’s working fine, at least it help me cut the development time half.

ENC28 only implement MAC + PHY layer, to use it in application we need another TCP/IP implemented somewhere. And since it came from the same company, Microchip has TCP/IP Stack, it’s one of the largest stack available. The stack and some demo examples are included in Microchip Application Library (MAL), mine is TCPIP Stack v5.42.08 June 2013. I’m going to pair ENC28 chip with PIC24FJ256 microcontroller, the stack will be implemented in PIC24F firmware.

The project plan is to build a HTTP web page application. The web page application will perform some simple function to turn something ON/OFF and display the status. The first place I’m going to start is the “Demo App” example which can be found in MAL TCPIP folder. I modified the demo example sources to meet my application. We don’t need to include all the sources in “Demo App” to this project as it will be simpler.

The system (ENC28 + PIC24F + TCPIP Stack) will act as a web server. When connected to PC/laptop Ethernet port, we can access the webpage using a web browser (Firefox, Chrome, IE, etc). The system is connected to an AC lamp, the web page will serve as a simple interface, it shows the current status of the lamp and provides us the ability to turn it ON/OFF.

Block diagram of what will be build:

There will be several things need to be prepared for building the project, I’m going to summarized what to do step by step:

(1)    Create new project in MPLABX just like usual, choose device family, choose compiler. Copy linker file for PIC24F to the main project directory and add it in MPLABX project under Linker Files, I’m using the one from hid bootloader, with a little modification.

(2)   In the project main directory create new folder and name it “TCPIP Stack”, we’ll copy and dump all required TCP IP Stack sources here. (to avoid modifying the original stack in MAL installation directory).

Copy these sources from “Demo App” and paste it at the project main directory: BerkeleyTCPClientDemo.c, BerkeleyTCPServerDemo.c, BerkeleyUDPClientDemo.c, CustomHTTPApp.c, CustomSSLCert.c, GenericTCPClient.c, GenericTCPServer.c, HardwareProfile.h, HTTPPrint.h, MainDemo.c, MainDemo.h, PingDemo.c, SMTPDemo.c, TCPIPConfig.h. Also copy “GenericTypeDefs.h” and “Compiler.h” from MAL directory “Microchip/Include”.

Create another new folder and name it “Configs”. Configuration source files will be placed in here.

There’re a lot of file inclusion and preprocessor since the demo examples were created to support several Microchip demo board. I’m using my own PIC24F board and ENC28, so in that case the most suitable option is to pick “HWP EX16_ENC28 XC16.h” and “TCPIP ENC28.h” for configuration. Copy and place both files under directory “Configs” in the project.

The final look for project directory will be like this:
Now, go back to MPLABX and then on the project window right click “Source Files” and create two logical folders “TCPIP Stack” and “Configs”. Add all the sources.

Some important files inclusion summary:

- "TCPIP ENC28.h"
  (where all the macro “STACK_USE” are defined, e.g: STACK_USE_UART)
   File inclusion:
  "TCPIP ENC28.h" -> "TCPIPConfig.h" -> "TCPIP.h" -> "MainDemo.c"

- "HWP EX16_ENC28 XC16.h"
   (where the configuration setting, SPI SFR, TRIS, PORT, LAT, UART TRIS are defined)
  File inclusion:
  "HWP EX16_ENC28 XC16.h" -> "HardwareProfile.h” -> "TCPIP.h" -> "MainDemo.c"

(Note: To include “HWP EX16_ENC28 XC16.h” we need to define macro “CFG_INCLUDE_EX16_ENC28” in MPLABX project setting)
PIC24 and ENC28 communicate using SPI. Macro definitions for SPI CS pin and SPI register being used are defined in file "HWP EX16_ENC28 XC16.h". Remember if using PIC24, SPI pins need to be allocated before use. PPS (Peripheral Pin Select) for SPI pins allocation are done in function "InitializeBoard" in “MainDemo.c”.

Hardware I/O pin mapping (e.g. TRIS, LAT, PORT) is defined in "HWP EX16_ENC28 XC16.h".

There will be a lot of sources placed under TCPIP Stack folder, but we don’t need to include all of them to our project, I only included necessary files. Let the compiler guide us on what to include, if we missing some files then when we build the project on MPLABX an error will tell us what files we’re missing. (I’ve done compile and recompile ton of times) The .h header files for TCPIP Stack can be copied from MAL installation directory under “Microchip/Include/TCPIP Stack”, and the corresponding .c sources can be copied from “Microchip/TCPIP Stack”.

(3)   We need to prepare the HTML source for the web page. Once the HTML source is ready, we’ll use MPFS2 Utility to convert the web pages and generate MPFS2 image to store in the flash program memory of the microcontroller.
(Note: name the HTML source code “index.htm” not “index.html”)

The dynamic variables are the variables that being passed (communicated) between our HTML web page and the microcontroller. It’s the important key, it provide the ability to us the application designer to output HTML, control design, what is displayed, layout, graphical elements on the webpage.
Below is the simple HTML webpage layout that I created:
The HTML layout use table which consists of two rows and two columns (the 2nd column span two rows). The first row will display the status of the lamp. The second row has button to toggle the lamp ON/OFF (this button submit “Get Form” to the HTTP web server to process, it will append value “toggle lamp” to the URL). On the second column an image of a lamp is shown to make the page looked more interactive.

To create a dynamic variable, we enclose the name of variable inside a pair of tilde (~) character within the web page HTML source code. (ex: ~myVariable~) When we run the MPFS2 Utility to generate the web page, it will automatically index these variables in “HTTPPrint.h” (and also create HTTPPrint.idx). This index will instruct our application to invoke the function HTTPPrint_myVariable when this string is encountered.
In my HTML source, the dynamic variable (~lamp~) is used to update the status of the lamp. When this string encountered, the application will execute “HTTPPrint_lamp” function. This function is indexed in “HTTPPrint.h” and the function is defined in “CustomHTTPApp.c”:
The dynamic variable (~lampimg~) is used to control the display image of the lamp. It depend on the lamp status, if ON then a glowing lamp image is loaded and vice versa.
Form Processing:
In the HTML source there’s one form that must be processed, the button to toggle the lamp ON/OFF will submit a GET Method to the web server. The string “toggle lamp” will be appended at the end of the URL when the button is clicked. (i.e. http://index.htm?button=toggle+lamp) In TCP IP firmware, data sent via GET is automatically decoded and stored in curHTTP.data array. This data is limited to the size of curHTTP.data , which is by default 100 byte, that more than enough for this simple web page. A callback function “HTTPExecuteGet” will be called to process the GET request. This function is also defined in “CustomHTTPApp.c”, we need to modify this function a little:
The callback need to do several things. First it call “MPFSGetFilename” to get the filename, then verify it came from our HTML webpage “index.htm”. If so then we seek out the expected string submitted “toggle”, then the microcontroller will change the LAT value of the pin which connected to the relay controlling the lamp.

(more info can be found in TCP IP Stack Help inside the “Help” directory of MAL, also read webminar by Elliot Wood “TCP IP Networking Part 1: Web-Based Status Monitoring” and “TCP IP Networking Part 3: Advanced Web-Based Control”)

We set/select network configuration and addressing options in file “TCPIP ENC28.h”. There we select how TCP IP stack application works. Also in there we can set default Host Name, IP Address, Mac Address, subnet mask, gateway, and DNS. There’re 3 methods that we can use to set or obtain an IP address: static, DHCP, or AutoIP. I’ll be connecting the application directly to my PC Ethernet port.

Using static IP, TCP IP setting on device:


     disable auto ip, dhcp client, dhcp server 

     (comment “STACK_USE_AUTO_IP”, “STACK_USE_DHCP_CLIENT”, 
   “STACK_USE_DHCP_SERVER”)

       enable dns, dns server, netbios
     so that we can access the web page by DNS
   (“STACK_USE_DNS”, “STACK_USE_DNS_SERVER”, “STACK_USE_NBNS”)

 
     default ip addr = 192.168.1.100 

     default subnet mask = 255.255.255.0
     default gate way = 192.168.1.101 (PC ip address)
     default primary dns = 192.168.1.100 (this device ip address)
     default secondary dns = 0.0.0.0

To set the LAN adapter setting in “Windows 7” go to Control Panel -> Network and Sharing Center -> Change adapter setting -> Right Click Local Area Network -> Properties -> TCP/IPv4 -> Properties:

The webpage can be opened either by typing the default host name "http://mchpboard" or "169.254.1.100" in a browser and it will open “index.htm” which is the HTML webpage that have been added to the firmware.
(also test PING the device to see if it working and responded in command prompt, and check ipconfig too)

We can also set the application to use DHCP (Dynamic Host Configuration Protocol). With DHCP server enabled, the device can assign/give PC an IP Address, so we don’t need to set IP Address of PC manually in control panel (just set the adapter setting to obtain the IP address automatically). To enable DHCP uncomment macro “STACK_USE_DHCP_SERVER” in “TCPIP ENC28.h”.

How to connect AC lamp to relay (be careful don’t connect it wrongly with 220V the damage could be dangerous):

Typically AC equipment in house uses cable which contain two copper wires inside it. Cut the cable into two, so we got one cable hanging with the plug to AC outlet and the other one cable connected to the AC lamp. On each cable peel the outer isolator so we got two branch of wires inside, then peel the inside cable so the yellow copper now can be seen. Connect the cable using female terminal block (the terminal block in the relay board is the male one) to the relay board just like the figure above.

Before this post has become too long, let me end this now with this final video demonstration below to summarized everything:



No comments:

Post a Comment