Arduino library to handle ping messages for ESP8266 platform


Introduction

The ESP8266 is a system on a chip embedding a 8-bit microcontroller and a Wi-Fi transceiver, made by Espressif Systems.

The high number of ESP8266-based development boards providing GPIO access and USB connectivity make such SoC very interesting for fast deploying IoT applications.

In a large network of small Wi-Fi systems can be convenient to check periodically the connection state of same nodes. This library makes it possible to handle ping requests ans responses, allowing the user to specify callbacks to run when icmp echo packets are received.

Installation using Library manager

  1. Open Arduino IDE
  2. Select Sketch -> Include Library -> Manage Libraries… Arduino library manager
  3. Type "ESP8266-ping" in search bar, and install it

Manual installation

  1. Download latest release zip file
  2. Rename downloaded zipfile to ESP8266-ping.zip
  3. Open Arduino IDE
  4. Go to Sketch -> Include library -> Add .ZIP library…
  5. Select just downloaded file
  6. Library is installed.

Usage example

/*****************************************************************************
Arduino library handling ping messages for the esp8266 platform
MIT License
Copyright (c) 2018 Alessio Leoncini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*****************************************************************************/

#include <Pinger.h>
#include <ESP8266WiFi.h>
extern "C"
{
  #include <lwip/icmp.h> // needed for icmp packet definitions
}

// Set global to avoid object removing after setup() routine
Pinger pinger;

void setup()
{  
  // Begin serial connection at 9600 baud
  Serial.begin(9600);
  
  // Connect to WiFi access point
  bool stationConnected = WiFi.begin(
  "wifissid",
  "wifipassword");

  // Check if connection errors
  if(!stationConnected)
  {
    Serial.println("Error, unable to connect specified WiFi network.");
  }
  
  // Wait connection completed
  Serial.print("Connecting to AP...");
  while(WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.print("Ok\n");
  
  pinger.OnReceive([](const PingerResponse& response)
  {
    if (response.ReceivedResponse)
    {
      Serial.printf(
        "Reply from %s: bytes=%d time=%lums TTL=%d\n",
        response.DestIPAddress.toString().c_str(),
        response.EchoMessageSize - sizeof(struct icmp_echo_hdr),
        response.ResponseTime,
        response.TimeToLive);
    }
    else
    {
      Serial.printf("Request timed out.\n");
    }

    // Return true to continue the ping sequence.
    // If current event returns false, the ping sequence is interrupted.
    return true;
  });
  
  pinger.OnEnd([](const PingerResponse& response)
  {
    // Evaluate lost packet percentage
    float loss = 100;
    if(response.TotalReceivedResponses > 0)
    {
      loss = (response.TotalSentRequests - response.TotalReceivedResponses) * 100 / response.TotalSentRequests;
    }
    
    // Print packet trip data
    Serial.printf(
      "Ping statistics for %s:\n",
      response.DestIPAddress.toString().c_str());
    Serial.printf(
      "    Packets: Sent = %lu, Received = %lu, Lost = %lu (%.2f%% loss),\n",
      response.TotalSentRequests,
      response.TotalReceivedResponses,
      response.TotalSentRequests - response.TotalReceivedResponses,
      loss);

    // 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);
    }
    
    // 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());
    }

    return true;
  });
  
  // Ping default gateway
  Serial.printf(
    "\n\nPinging default gateway with IP %s\n",
    WiFi.gatewayIP().toString().c_str());
  if(pinger.Ping(WiFi.gatewayIP()) == false)
  {
    Serial.println("Error during last ping command.");
  }
  
  delay(10000);
  
  // Ping technologytourist.com
  Serial.printf("\n\nPinging technologytourist.com\n");
  if(pinger.Ping("technologytourist.com") == false)
  {
    Serial.println("Error during ping command.");
  }

  delay(10000);

  // Ping undefinedname
  Serial.printf("\n\nPinging undefinedname\n");
  if(pinger.Ping("undefinedname") == false)
  {
    Serial.println("Error during ping command.");
  }

  delay(10000);

  // Ping invalid ip
  Serial.printf("\n\nPinging invalid ip 1.2.3.4\n");
  if(pinger.Ping(IPAddress(1,2,3,4)) == false)
  {
    Serial.println("Error during ping command.");
  }
}

void loop()
{
}

Version 2.0.1

Send ping requests to a remote host, providing the response time and other statistics.

Library includes simple examples showing how to issue ping requests to remote hosts defined by IP address or DNS name.

Changelog:

  • Fix in library properties for Arduino IDE

Version 2.0.0

Send ping requests to a remote host, providing the response time and other statistics.

Library includes simple examples showing how to issue ping requests to remote hosts defined by IP address or DNS name.

Changelog:

  • Redesigned to exploit low level LWIP functions
  • Allows execution of user-defined callbacks
  • Allows slight packet customization

Version 1.1.0

Send ping requests to a remote host, providing the response time and other statistics.

Library includes simple examples showing how to issue ping requests to remote hosts defined by IP address or DNS name.

Changelog:

  • Fixed exceptions throwing
  • Fixed wrong behavior if host unreachable
  • Added detailed info when ping successful

Version 1.0.0

First release of ESP8266-ping. Present code allows to send ping requests to a remote host, providing the response time.

Present library includes simple examples showing how to issue ping requests to remote hosts defined by IP address or DNS name.


Comments