Abstract: This project enhances the projects Track_Train_ESP_Class and WiFi_123 to develop a WiFi access point that reads the status of a model train and generates a HTML page that can display the train status on a Smartphone.
Possible Audience: Model railway enthusiasts who wish to track the position of a model train using in track sensors and WiFi
Keywords: C++ header files, C++ lambda function, WiFi, HTML displays, Placeholders, tagging, processor( ) method.
Required Hardware: The project will use the hardware of the project Track_Train_ESP_Class plus a Smartphone etc for monitoring the WiFi
Required Software: Track_Train_ESP_Class and WiFi_123 Libraries. The project will be developed using the Arduino IDE
----------------------------------------------
This project is concerned with developing a WiFi access point that will read the status of a model train over 4 sensors and generating a HTML page to display the train status on a Smartphone. There will be 4 states corresponding to a train over a sensor, 3 additional states for a train between the sensors plus an 8th state when there are no trains present.
This project known as Track_Train_ESP_WiFI will merge/build on two previous projects: Track_Train_ESP_Class and WiFi_123
------------------------
The project will inherit the Track_Train_ESP_Class that in turn inherits
1. LDR_Serial_Sensor_Class that read the status of 8 track sensors (This project will only use the results from 4)
2.Signals3_Serial_Class that will control 4 sets of 3 aspect signals (RED, AMBER, GREEN)
The basic application/test/client code to use Track_Train_ESP_Class is
This code will be used as the starting point. The steps are to insert the HTML-WiFi operations into the code and to give different messages depending upon the enum variable train_loc (ie state of train). The given states are:
**The design allows for trains coming in either direction - hence coming0, coming1 etc
-----------------------------------------------
The WiFi section of the project will build on program 2 from the WiFi_123 project:
The HTML code is contained in a separate file index.h.**
const char WiFi_Mess [] PROGMEM = R"(<!DOCTYPE html><HTML><HEAD><TITLE>WiFi_Mess_page</TITLE><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="data:,"></HEAD><BODY><CENTER><H2>WiFi Message</H2></CENTER></BODY></HTML>)";**The directive PROGMEM has been added to the character string WiFi_Mess. Normally the compiler will make an image of all variables to be loaded into RAM (dynamic or data memory) at run time. PROGRAM tells the compiler not to make an image of WiFi_Mess (basically all of the index.h). The program will then use the original in program memory or flash rather than a copy in RAM..
-----------------------------
Combining the *.ino files obtain**:
//Track_Train_ESP_Class.ino#include <Track_Train_ESP_Class.h>Compiling and running should give WiFi_Mess as an available network:
When requested enter the pass word 12345678.
In a browser select address 192.168.4.1++ The following message should be obtained
** The only change was to modify the quotes to brackets around the header file Track_Train_ESP_Class.h. That is #include <Track_Train_ESP_Class.h> the < > giving that the header file is now part of the Arduino Library.
++ 192.168.4.1 is the default address
-------------------------------
One part of this project will be concerned with changing the HTML appearance. Metadata is not directly visible to the end user but adds functionality to the web page. It is inserted between the <HEAD> and </HEAD> tags. The <TITLE></TITLE> tags give the message that shows up in the web browser’s title bar.
To allow browsing on a range of devices the meta tag
<meta name="viewport" content="width=device-width, initial-scale=1">
that will automatically adjust for different screen sizes and viewports is included..
To change the style the following metadata directive could be added:
With the text_align: center directive will centre the display so the tags <CENTER>...</CENTER> then become redundant.
Once the program was verified the opportunity was taken to change the project to "Where's Thomas?" This required three changes:
const char* ssid = "WheresThomas";
<TITLE>Where's Thomas</TITLE>
<H2>Where's Thomas</H2>
---------------------
Placeholders allow the HTML to be changed. A common example is a physical parameter such as temperature where the value changes.
In the long term I will use this project to display the location of a model train or as implied in the previous section the location of Thomas the Tank Engine. The display might be "Thomas approaching" or "Thomas departing".
A placeholder is added to the body portion of the HTML code (the index.h) file.
The placeholder is surrounded by the percentage symbols and in this example it is given the label PLACEHOLDER. For more complex examples PLACEHOLDER_1 etc might be used.
The main program now needs to replace %PLACEHOLDER% with the desired message. This is done with the processor method.
------------------------------
The processor method will have the placeholder label as a parameter and return the replacement string. That is String processor(const String& var).
The full code will be:
In the above code if there is no test for the given placeholder there is a default message.
To execute the above code it must be called from the request->send function.
--------------------------------
A request from the client browser is handled with the server.on method.
The server.on method specifies or configures the route where server will be listening for incoming. In this example it is looking for the "/" hello route and type. The second parameter is the message to be sent, effectively the index.h file. The third argument is the handling function that will be executed when the request is received**.
The request method will respond with
i.The HTTP response code: 200 is the HTTP response code for “OK”.
ii.The content type: “text/html for a HTML message.
iii.The actual content. In this example the constant WiFi_Mess
iv. The replacement string (ie the method processor)
Note with the extra argument the send is replaced with send_P.
The resultant display is shown below where "Nowhere to be seen!" replaces the placeholder.^^
** To keep the syntax compact the handling function uses a C++ lambda function. ie [captures](params){body}
^^ The actual display is for a later section where the message is tagged. (Shown underlined)
----------------------
The project requirements are to display the status, That is one of 8 states that is defined by the variable train_loc. The code will be:
----------------------------------------------
As given the code will only execute once. In a practical situation it will be desirable to have the capability to update the display when required. This may be done using the href tag. The HTML code will be of the form:
<a href="update">Click here to update.</a>
After this message is seen a few times it becomes redundant. A possible technique is to place the tag around the message. That is:
<a href="update">%PLACEHOLDER%</a>
This results in the previous display.
There is now another option that must be implemented in the program code.
Clicking on the message "Nowhere to be Seen!" the browser will send the request 192.168.4.1/update and in this example the display will be refreshed.**
** In a practical situation the display will be updated depending upon the application. For a temperature display the actual temperature will change. In the monitor a model train example the train will have moved so the response will be a different message.
---------------------------------
This design was tested on a small layout where exactly where Thomas the Tank Engine was could be readily seen so the WiFi only added a "whow!" factor. However ever if Thomas moved relatively slowly through the monitored section of track by the time one requested an update and the response was received and displayed Thomas had moved on. In practice a solution that updated the display everytime the train entered a new state was required. This is another project.
Alternatively the dispaly could be updated every 3 seconds via the meta instruction between the <HEAD> </HEAD> tags in the index,h file.
<meta http-equiv="refresh" content="3">
-----------------------