John Errington's Experiments with an Arduino
Continuous monitoring of my connection to the web: Uses ESP32 Devkit, and 1.8 inch SPI display
Overview:
My internet connection has been unreliable in the past. I wanted a stand-alone unit that would give me a display showing the status in a simple form.
Trials with a NodeMCU gave unreliable results so I continued development with an ESP32 Devkit.
As the unit was intended to be viewed from some distance I needed to use text size 4, which allowed only 5 lines of text and a maximum of 11 characters to a line.
As you can see the display shows the following:
- program name and version (Weblog2.01) and L - indicating long averaging (or S - short)
- the up time of the connection since the last interruption
- the total down time since a reset
- the average time for a ping response to the test server, and
- a metric indicating the quality of the connection (more later)
The test server
Following an outage on the test server I first used, (a big multinational store's website) I looked for one with 100% uptime.
DNS Servers are usually chosen because the biggest have 100% reliability due to the URL being shared across multiple servers asround the world.
I used Traceroute to choose a DNS server that was a few hops away from my ISP. Google 8.8.8.8 is "traditional" but I found Quad9 at 9.9.9.9 to be a better option for my own situation.
The circuit of the internet connection monitor
The electrical circuit is very simple. The ESP32 is powered by a USB adaptor, and supplies the external circuit.
A switch selects the averaging - slow or fast. The 47nF capacitor is just for debouncing.
A button allows the data to be reset.
Inputs 25 and 26 are set up as INPUT_PULLUP so the switch and button only need a ground connection.
All connections to the display are made from the other side of the ESP32 Devkit to the display module using a ribbon cable soldered to headers.
( Schematic produced with TinyCAD )
The displayed values
The DEVKIT connects to my router via wifi and gets the time from an NTP server using the time library. So maintaining a record of uptime and down time is straightforward. The more interesting part was getting and processing ping data - what values should I usefully display?
I used this ESP32Ping library -https://github.com/marian-craciunescu/ESP32Pin
but it did not give me the ping metrics I wanted so I modified the ESP32Ping.cpp and .h files (get them here) to add more.
To use them you will need to copy the modified .cpp and .h files into the library folder.
At 6 second intervals the program sends two successive pings to a chosen target server, and returns the average time for the number sent.
The first step in calculation is to convert the time values to microseconds as this supports integer calculations with good precision.
Averaging
The switch selects an averaging parameter K for a simple digital filter algorithm; you can see here the effect; for K=6 it takes about 20 samples before the average reaches the current "new" value; at 6 sec intervals that is 20 * 6 seconds = 2 minutes.
I'm using K=1 or K=6 for the ping time averaging
averageValue = (latestValue + (K-1) * oldAverageValue) / K
so if K=1 averageValue = (latestValue + (0) * oldAverageValue) / 1
which just means no averaging.
The switch also changes the averaging for the quality metric.
Line quality
The metric for the line quality is based on the "ping jitter"; that is, the time difference between successive pings.
Our jitter measurement is a compromise because the value we are measuring is already an average. However we can still get a useful indication of line qualty from the average ping jitter.
I'm using K = 6 or K = 30 for the ping time averaging (QualFilter)
//calculate and average the jitter
diff = abs(pingTime - pingLast); //current jitter in microseconds
pingLast = pingTime;
pingJitter = ((2 * diff) + (qualFilterM1 * pingJitter)) / (qualFilter ); //add and average the jitter
if (pingJitter > 99999) { pingJitter = 99999; } //dont allow it to exceed 100
pingQual = 100 - (pingJitter / 1000) ; //express the line quality pingQual as a value between 100 & 0 "percentage"