This project enhances the WiFi_Mess project to send multiple messages to WiFi. In this example the end application will be a model train layout where the position of the train and hence message to send uses light detecting resistors (LDRs).
Abstract: This project will layer WiFi capability on to the Track_Train_ESP_Class. The Track_Train_ESP_Class project tracked the position of a train along a section of track.
Possible Audience: Model railway enthusiasts who are interested in adding WiFi capability to layouts
Keywords: C++ class/library, ESP8266, Arduino IDE Program Manager, LDR Light Detecting Resistors, enum type, WiFi
Components Required: ESP8266 Microcontroller. Design was tested with 74HC165 and 4 LDR plus resistors.
Required Software: Arduino IDE with ESP8266 Add on. Libraries from previous projects: Track_Train_ESP_Class, Signals3_Serial_Class and LDR_Serial_Sensor_Class
-------------------------------
This project will enhance the previous project Track_Train_ESP_Class, that monitored the status of a model train, by layering on top the WiFi capability of the project WiFi_Mess. For background the model train layout consisted of a section/block of track:
As shown there are 8 states or 15 if you allow for trains coming in both directions. These states are defined in the public type enum where_is_train {waiting, coming0, approaching0, arriving0, station0, departing0, leaving0, going0, coming1, approaching1, arriving1, station1, departing1, leaving1, going1} The Track_Train_ESP_Class has a public method monitor_train( ) that returns the state of the train (ie one of these states)..
The actual circuit is**:
With the circuit shown the Track_Train_ESP_Class constructor will specify how the circuit is wired. In the design given above the constructor will be: Track_Train_ESP_Class (D0,D5,D6,D2,D1) where the arguments are the pins for Ser_In, Load, In_Clk, Ser_Out, Out_Clk.
Track_Train_ESP_Class has a public methods
1. begin(1,1,4) where begin(ext,pol,sets) gives the configuration of the external circuitry where ext: external gate used for AMBER, pol: polarity of signals, sets: number of signals^^.
2. monitor_train( ) that returns the train state: where_ is_ train. where_is_train is an enum type with members{waiting, coming0, approaching0, arriving0, station0, departing0, leaving0, going0, coming1, approaching1, arriving1, station1, departing1, leaving1, going1};
After Track_Train_ESP_Class is initialised the public method monitor_train( ) will monitor the LDRs and control the signals. Controlling the signals is completely independent of this project. However monitor_train( ) will return the current state of the train- it is this state that will be used to select the WiFi messages.
**For this project controlling the signals (LEDs) occurs in the background so there is no requirement to have the 74HC164 and LEDs
^^begin( ) will default to begin(1,1,4). External NOR gate, positive signals and 4 sets of signals as shown in the circuit above. If the test set up is not going the include the signals (LEDs) use begin( ).
The project uses the Arduino IDE with the ESP8266 add on. If the add-on is not already included see appendix 1. Adding the Required Libraries.
If readers have implemented earlier projects they will have the library Track_Train_ESP_Class which in turn inherits the libraries Signals3_Serial_Class and LDR_Serial_Sensor_Class. If not, it is recommended that readers complete these projects and generate the libraries. See Appendix 2.
The ultimate product will consist of 4 LDRs located in the tracks of a model railway. These will be wired back to screw terminals on parallel to serial converted, 74HC165 that is in turn wired to a central micro-controller the ESP8266. For testing LDRs will be physically placed at the terminals (photo shows one only).
The Track_Train_ESP_Class recomends the following starting code:
To this code to add WiFi capability the code from WiFi_Mess needs to be integrated**:
The new WiFI_Train_State code becomes:
The program as given performs two independent operations:
i. The LDRs (train sensors) control the LEDs (Train Signals), and
ii. An unrelated WiFi message is displayed.
The task of this project is to combine the two. That is the WiFi messages to give the train state.
** I chose to re-load the WiFi_Mess project and save as WiFi_Train_State and then copy/paste the Track_Train_ESP_Class code.
Following reset there will be no trains detected so a message "No train present" should be added to the processor method/routine
The message "No train present" will be displayed by the smartphone.
Shading one of the LDRs corresponding to "coming" the Track_Train_ESP_Class will move to the coming and then approaching states. At this point there is no message for these states so Unknown State will be displayed**.
**"Unknown State" will continue to be displayed^^ until all the LDRs representing the train moving through the arriving, departing and going states are activated in the correct order.
^^ The Track_Train_ESP_Class contains a watch dog timer which will re-trigger the design if there is no activity for a period.
The code was modified to account for every state:
String processor(const String& var){if(var == "PLACEHOLDER"){if (train_loc == waiting) return String("No train present");if (train_loc == coming0) return String("Train coming from North");if (train_loc == coming1) return String("Train coming from South");if (train_loc == approaching0) return String("Train approaching from North");if (train_loc == approaching1) return String("Train approaching from South");if (train_loc == arriving0) return String("Train arriving from North");if (train_loc == arriving1) return String("Train arriving from South");if (train_loc == station0) return String("Train from North at Station");if (train_loc == station1) return String("Train from South at Station");if (train_loc == departing0) return String("Train departing to South");if (train_loc == departing1) return String("Train departing to North");if (train_loc == leaving0) return String("Train leaving to South");if (train_loc == leaving1) return String("Train leaving to North");if (train_loc == going0) return String("Train going to South");if (train_loc == going1) return String("Train going to North");return String("Unknown state");}return String("Placeholder Error");}Testing verified the operation**
** Testing was a bit difficult trying to place some shade over the LDRs and pressing the touch screen of a smart phone at the same time. Using switches may have been a better solution.
From an earlier project Train_State_ESP_Class the external activity was captured on a mixed signal oscilloscope (MSO):
The top three channels are capturing the LDR sensor state while the next two are the signals to drive the LEDs. The LEDs are only activated every 100mS implying this bust is every 100mS.
In the bottom channel the signal is set highy at the start of the program loop and then reset low at the end. The high portion represents the time the Arduino is executing "our" code while the low represents Arduino background routines.
Adding the WiFi capability, this project results in the following changes:
In this trace the MSO has been set to trigger on the lower channel being low for greater than 20uSec. Most of the time the signal was only low for ~7.5uSec so this is an exception. It is assumed** to occur when the ESP8266 is interrupted to perform in the background WiFi activities. That is the response to a request: request->send_P(200, "text/html", WiFi_Mess, processor);
In a second example the MSO was set to trigger if the pulse was high for longer than 200uS.
In this case it appears that the WiFi asynchronous/interrupt activity started half way through an output transfer and was taken up again in the background as per the previous trace.
As can be seen the WiFi does not appear to have a significant performance overhead.
** These are my best explanation as to what is happening - they may not hold up in a court of law.
A major limitation of the design was that an update had to be requested. A better solution will be to have the ESP8266 AP send the message when there is an update in status. This is the topic of a further project.
-----------------------------------------------
This project will use the Arduino IDE with the ESP8266 Add-ons.
This will allow the Arduino IDE editor to be used but the results are then compiled for the ESP8266. The advantage is that applications can be developed for the ESP8266 without the developer having to learn more complex and/or different tools. The disadvantage is that some of the features/attributes of theESP8266 may be hidden in the simplification. It may also lead to the impression that the ESP8266 is similar to the ATMega828 in the Arduino when it is not.
If required Install the drivers: (I was using a WiFi Mini product code XC3802 from Jaycar) and found my PC recognized the XC3802 I was using so this step was not necessary)
If the library is not found the WiFi Mini uses a CH340G USB-Serial IC. The drivers for this can be downloaded from the IC manufacturer’s website: http://www.wch.cn/download/CH341SER_ZIP.html
To add board support for the ESP8266 it is recommended to use Arduino IDE version 1.6.4 or later so that the Boards Manager can handle the installation.
1. To install board support for ESP8266, in File>Preferences>Additional Board Manager URLS add: http://arduino.esp8266.com/stable/package_esp8266com_index.json separating from existing entries with a comma.
2: Go to Tools>Boards>Boards Manager and type 'esp' in the search box
3. Install ESP8266 by ESP8266 Community. (Button on lower right) This is about 150MB download and can take a while.
4. Select the desired ESP6266 board. My board was identical to the 'WeMos D1 Mini Lite’
The Arduino IDE will now start creating, compiling and running programs with the ESP8266.
If readers have implemented earlier projects they will have the library Track_Train_ESP_Class which in turn inherits the libraries Signals3_Serial_Class and LDR_Serial_Sensor_Class. If not, it is recommended that readers complete these projects and generate the libraries**.
Briefly:
1. Open the Arduino IDE and create a new file LDR_Serial_Sensor_Class. The IDE will give it the extension *.ino
2. Use the inverted triangle to the upper right of the IDE monitor and create a New Tab and give it the label LDR_Serial_Sensor_Class.cpp. Note the extension.
3. Repeat and create a file with label LDR_Serial_Sensor_Class.h
4. Copy and paste the three files from the LDR_Serial_Sensor_Class_code into the Arduino IDE.
5. Compile the code - it may be necessary to remove any embedded formatting characters from the source code.
6, Using a program such as Windows Explorer make a *.zip file of the *.cpp and *.h files. It will have a label LDR_Serial_Sensor_Class
7. In the Arduino IDE use Sketch-->Include Library --> Add *.zip library and select the zip file just created LDR_Serial_Sensor_Class.zip
Repeat for Signals3_Serial_Class and Track_Train_ESP_Class.
** The new libraries will be in a folder "libraries" in the work folder. (See file-->preferences). It is possible to copy the required files to the libraries directly but it was considered safer to re generate the code.