It is a pretty commonly uttered question (sometimes loudly) around the home or office; "Is the internet up?" As the go to IT Support Manager around the house this can get a little tiresome. Most of the time the internet is up and it's a user or personal device problem that can be solved with a re-boot, re-load, re-etc. Rarely is the internet really down requiring a router and cable modem reboot or a call to the ISP. Wouldn't a simple visual check that anyone could quickly understand be helpful?
-----
I recently found my father's old Simpson 260 meter. He let me borrow it anytime I wanted with the warning of "DON'T COOK IT!". My memory recalls only using it for continuity and batteries which is good because I did not have a clue as to what would "cook it". I decided to put this heirloom to use as an internet monitor. This project is amazingly useful and simple to duplicate.
-----
The rig uses an ESP8266 to ping different servers. The ping time (in mS) is displayed on the Simpson 260 and 'percent of full scale'. In other words a ping of 73mS would be 73% of full scale on the Simpson 260. We set the source code (see below) to cycle through ten servers and show the ping result every 15 seconds.
-----
If the LAN is down or a ping error is detected the meter "wags" back and forth 5 times and tries another server. The message to the house is, "If the needle ain't wagging back and forth then your problem ain't with the internet connection!"
Upload the Arduino IDE based source code below to the ESP8266. Connection to the Simpson 260 is easy.
-----
/*
* A vintage Simpson 260 meter to shows network PING times
* and if there is a connection to the internet.
*
* Deflect the Simpson meter from 0-100% of the 2.5V full scall
* based on ping times of servers.
*
* 10mS = 10% of full scale.
* 45mS = 55% of full scale.
* 73mS = 73% if full scale.
* XXmS = XX% of full scale, etc....
* Anything over 100ms is consider terrible and just maxes to 100%
*
* A bad ping (site not found, network down, etc) will 'wag' the meter
* back and forth from 0% to 100% five times then try next ping site.
*
* ESP8266 NodeMCU Board BAUD 115200
* HiLetgo 1PC ESP8266 NodeMCU CP2102 ESP-12E Development Board from Amazon
*
* Full documetation at:
* WhiskyTangoHotel.Com
*
* FEB2022
*
*/
#include <ESP8266WiFi.h>
#include <Pinger.h>
const char* ssid = "Virus-2.4"; // These vars are your private WIFI
const char* password = "zenakelsocats"; // connection information
// Define some 'ping friendly' sites. ARRAY starts a 0
String PingSite[] = {
"whiskeytangohotel.com",
"google.com",
"yahoo.com",
"bing.com",
"abc.com",
"cbs.com",
"cnn.com",
"apple.com",
"pingler.com",
"mailinator.com"
}; // end ping array define
int Number_of_Ping_Sites = 10; // counted from the list above
int Secs_Between_Pings = 15;
float Min_Ping_Result = 999;
const int PINGOUT = 2; // Drives the S260. Blue onboard LED and ~D4
Pinger pinger;
void setup() {
analogWrite(PINGOUT, 0);
delay(50);
Serial.begin(115200);
delay(100);
// Connect to the WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// For the ping dot h features https://github.com/bluemurder/esp8266-ping
pinger.OnEnd([](const PingerResponse& response)
{
// Print time information
if(response.TotalReceivedResponses > 0)
{
Serial.printf("Approximate round trip times in milli-seconds:\n");
Serial.printf(
" Minimum = %lums, Maximum = %lums, Average = %.2fms\n",
response.MinResponseTime,
response.MaxResponseTime,
response.AvgResponseTime);
Min_Ping_Result = response.MinResponseTime;
}
// Print host data
Serial.printf("Destination host data:\n");
Serial.printf(
" IP address: %s\n",
response.DestIPAddress.toString().c_str());
if(response.DestMacAddress != nullptr)
{
Serial.printf(
" MAC address: " MACSTR "\n",
MAC2STR(response.DestMacAddress->addr));
}
if(response.DestHostname != "")
{
Serial.printf(
" DNS name: %s\n",
response.DestHostname.c_str());
Serial.println("Minimum ping was: " + String(Min_Ping_Result) + "mS." + " Meter to " + String(int(Min_Ping_Result)) + "% of full scale.");
Serial.println("Delay to next ping is " + String(Secs_Between_Pings) + " seconds...");
Serial.println("---------------------");
}
return true;
}); // end ping features
//Self Test the meter by moving the meter full scale
// Increase meter value and on board LED brightness
for(int dutyCycle = 0; dutyCycle < 200; dutyCycle++){
// changing the LED brightness with PWM;
analogWrite(PINGOUT, dutyCycle);
Serial.println(String(dutyCycle) + " increasing meter self test...");
//analogWrite(PINGOUT, testval);
delay(10);
} // end meter increase
// Decrease meter value and on board LED brightness
for(int dutyCycle = 200; dutyCycle > 0; dutyCycle--){
// changing the LED brightness with PWM
analogWrite(PINGOUT, dutyCycle);
Serial.println(String(dutyCycle) + " decreasing meter self test...");
//analogWrite(PINGOUT, testval);
delay(10);
} // end meter decrease
Serial.println("Self test complete!!!");
Serial.println("---------------------");
} // end void setup
// dutytCycle/2 = ~ the % of 2.5V scale on S260
// 0 dutytCycle =
// 50 dutytCycle = 28%
// 100 dutytCycle = 53%
// 150 dutytCycle = 77%
// 200 dutytCycle = 100%
// Set S260 to +DC. The + lead to D4. Neg lead to GND
void loop() { // loop until the Cowboys win a Super Bowl
for (int i = 0; i <= (Number_of_Ping_Sites - 1); i++) { // don't always use the same PingSite; cycle them.
Serial.println("PingSite[" + String(i) + "]: " + PingSite[i]);
if(pinger.Ping(PingSite[i]) == false)
{
Serial.println("Error during ping command. Walk the meter 5 times.");
// Walk the meter back and forth to symbol 'ping error' or network down
for (int walk = 0; walk<=4; walk++) {
// Increase meter value and on board LED brightness
for(int dutyCycle = 0; dutyCycle < 200; dutyCycle++){
// changing the LED brightness with PWM;
analogWrite(PINGOUT, dutyCycle);
Serial.println(String(dutyCycle) + " Showing FAIL increasing for: " + PingSite[i]);
delay(10);
} // end fail meter increase
// Decrease meter value and on board LED brightness
for(int dutyCycle = 200; dutyCycle > 0; dutyCycle--){
// changing the LED brightness with PWM
analogWrite(PINGOUT, dutyCycle);
Serial.println(String(dutyCycle) + " Showing FAIL decreasing for: " + PingSite[i]);
delay(10);
} // end fail meter decrease
} // end for fail meter back forth walk
} // end if pinger.Ping
// Write Ping value to the meter. Low is better.
// We basically make percent of full scale equal the ping in mS, ie; 45mS = 45%...
// Anything over a 100mS is a crappy ping so we make 100mS (100% of scale)
if (Min_Ping_Result > 100) { Min_Ping_Result = 100; }
analogWrite(PINGOUT, Min_Ping_Result * 2); // move to meter to display the ping value
delay(Secs_Between_Pings * 1000); // delay for next ping
} // end for/next to cycle the PingSites
} // end loop until the Cowboys win the Super Bowl
-----