arduino visual ICMP ping server monitor (ICMP echo request)

Today I had a little issue with my server – it stopped responding for no apparent reason and with no warning.

When it finally became responsive I asked myself “how can I know when my server is down quickly?”

The idea for this post was born – use my arduino to ping the server and show the status using LEDs.

After a little google search for arduino ping I found lots of references to the ping))) sensor, but that is not the type of ping I meant. Well done whoever came up with the name – you broke the internet.

Anyway, I digress. Back to the real issue.

I found a library for ICMP ping at Blake’s site – http://www.blake-foster.com/project.php?p=44
The link to the library itself is at http://www.blake-foster.com/projects/ICMPPing.zip

Install the library in the appropriate directory for your system (~/arduino/libraries in my case, your location will vary) and start the arduino software.

The following code will ping my server and alert me to the status via serial output and LED output.

Initially all three pins go high to signify ethernet attempting to connect.
Pin 2 will pulse when the arduino is pinging the server.
Pin 3 goes high when the server responds (it is up).
Pin 4 goes high when the server fails to respond (it – or your internet – is down).

The source for this script is available here
/*

* This code is the property of and remains the copyright of
* Gregory Fenton, http://labby.co.uk/2012/08/arduino-visual-icmp-ping-server-monitor-icmp-echo-request
* The code may be freely distributed and reused as long as this header is not altered or removed
* For commercial use of this code a fee of not less than $10 per hardware device the software runs on is payable for the usage rights
* Please contact Gregory Fenton at the above site should you wish to use this software in a commercial manner

Repeatedly ping a server and output the response to serial and pins 2,3,4

pin 2: ping request sent
pin 3: ping response received
pin 4: ping response not received

This software requires the ICMPPing library, available at

http://www.blake-foster.com/projects/ICMPPing.zip

Portions of this code were derived from code available at

http://www.blake-foster.com/project.php?p=44

My thanks go to Blake for his hard work.

If you do not wish to output to the serial port, comment out the line
#define serialOut 1
If you do not wish to output to the LEDs, comment out the line
#define ledOut 1

The lines
byte ip[] = {192,168,0,177}; // ip address for ethernet shield
byte pingAddr[] = {91,121,5,142}; // ip address to ping
need to be changed to suit your own needs. If your network has DHCP the arduino
will automatically grab an IP address for itself.
*/

#include <SPI.h>
#include <Ethernet.h>
#include <ICMPPing.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // mac address for ethernet shield
byte ip[] = {192,168,0,177}; // ip address for ethernet shield
byte pingAddr[] = {91,121,5,142}; // ip address to ping

SOCKET pingSocket = 0;

char buffer [256];

int delayMS = 60 * 1000; // delay between successive pings (60 * 1000 = 60 seconds)

#define serialOut 1
#define ledOut 1

#ifdef ledOut
#define ledPing 2
#define ledOk 3
#define ledFail 4

void startPing()
{
digitalWrite(ledPing, HIGH);
}

void endPing()
{
digitalWrite(ledPing, LOW);
}

void pingSuccess()
{
digitalWrite(ledFail, LOW);
digitalWrite(ledOk, HIGH);
}

void pingFail()
{
digitalWrite(ledFail, HIGH);
digitalWrite(ledOk, LOW);
}
#endif

void setup()
{
#ifdef ledOut
pinMode(ledPing, OUTPUT);
pinMode(ledOk, OUTPUT);
pinMode(ledFail, OUTPUT);

// initialising, turn all LEDs on
digitalWrite(ledFail, HIGH);
digitalWrite(ledOk, HIGH);
digitalWrite(ledPing, HIGH);
#endif

#ifdef serialOut
// start serial port:
Serial.begin(9600);
Serial.println("Starting ethernet connection");
#endif
// start Ethernet
if (Ethernet.begin(mac) == 0) {
#ifdef serialOut
Serial.println("Failed to configure Ethernet using DHCP");
#endif
// DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
}

void loop()
{
bool pingRet; // pingRet stores the ping() success (true/false)

#ifdef ledOut
startPing();
#endif
ICMPPing ping(pingSocket);
pingRet = ping(4, pingAddr, buffer);
#ifdef ledOut
delay(250);
endPing();
#endif

#ifdef serialOut
Serial.println(buffer);
#endif
#ifdef ledOut
if(pingRet) // Failure
pingSuccess();
else
pingFail();
#endif
delay(delayMS);
}

9 thoughts on “arduino visual ICMP ping server monitor (ICMP echo request)”

  1. Good Article. Congratulations!

    Is there any way to give a Serial.println in pingAddr []?

    Suppose pingAddr [] = {192.168, 1, 5}

    I wish the outcome would be something like this:
    The ping ip is: 192,168,1,5

    How could I do this?

    Google Chrome 21.0.1180.60 Windows 7
    Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
    1. Hello Leandro

      The buffer[256] variable is populated by a typical ping output line which would be one of the following:
      sendEchoRequest failed.
      Reply[%d] from: %d.%d.%d.%d: bytes=%d time=%ldms TTL=%d
      Request Timed Out

      The second line above, Reply[%d] from: %d.%d.%d.%d: bytes=%d time=%ldms TTL=%d would appear on Serial as
      Reply[1] from: 192.168.1.5: bytes=32 time=12ms TTL=128

      The actual output from my arduino as I type is:
      Reply[1] from: 91.121.5.142: bytes=32 time=23ms TTL=128

      Per your specific question I would not change the actual pingAddr library, I would simply add an extra Serial.println into the code above:
      #ifdef serialOut
      Serial.println(buffer);
      #endif

      #ifdef serialOut
      Serial.println(buffer);
      // Below two lines are modifications for Leandro Lalini,
      // http://labby.co.uk/2012/08/arduino-visual-icmp-ping-server-monitor-icmp-echo-request/#comment-1692
      sprintf(buffer, "The ping IP is: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
      Serial.println(buffer);
      #endif

      I hope this answers your question

      Google Chrome 21.0.1180.57 GNU/Linux 64 bits
      Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.57 Safari/537.1
      1. That was exactly what I needed.

        I have another question:

        I want to monitor 10 different ip address, but only I can monitor a maximum of 4. If I put the fifth, they stop working.

        I doing as follows:

        example:

        byte pingAddr[] = {187,19,16,1};
        byte pingAddr2[] = {187,19,16,210};
        byte pingAddr3[] = {187,19,16,211};
        byte pingAddr4[] = {187,19,16,226};
        byte pingAddr5[] = {187,19,16,221};

        SOCKET pingSocket = 2;
        char buffer [256];
        char buffer2 [256];
        char buffer3 [256];
        char buffer4 [256];
        char buffer5 [256];

        ICMPPing ping(pingSocket);

        ///

        ping(10, pingAddr, buffer);
        if( strcmp (buffer, “Request Timed Out”) == 0) {
        digitalWrite(2, LOW);
        Serial.println(buffer);
        delay (5000);
        digitalWrite(2, HIGH);
        }
        delay(1000);
        ping(10, pingAddr2, buffer2);
        if( strcmp (buffer2, “Request Timed Out”) == 0) {
        digitalWrite(3, LOW);
        Serial.println(buffer2);
        delay (5000);
        digitalWrite(3, HIGH);
        }
        delay(1000);
        ping(10, pingAddr3, buffer3);
        if( strcmp (buffer3, “Request Timed Out”) == 0) {
        digitalWrite(5, LOW);
        Serial.println(buffer3);
        delay (5000);
        digitalWrite(5, HIGH);
        }
        delay(1000);
        ping(10, pingAddr4, buffer4);
        if( strcmp (buffer4, “Request Timed Out”) == 0) {
        digitalWrite(6, LOW);
        Serial.println(buffer4);
        delay (5000);
        digitalWrite(6, HIGH);
        }
        delay(1000);
        ping(10, pingAddr5, buffer5);
        if( strcmp (buffer5, “Request Timed Out”) == 0) {
        digitalWrite(7, LOW);
        Serial.println(buffer5);
        delay (5000);
        digitalWrite(7, HIGH);
        }
        delay(1000);

        Would be able to monitor more than four pings or am I doing this wrong?

        Google Chrome 21.0.1180.60 Windows 7
        Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
  2. Hi again Leandro

    There is only a limited number of connections available to the arduino (4 maximum open connections at any one time).

    Should you wish to do any more than 4 you would need to wait for one to close to reuse the socket. I will look into how forthwith.

    Google Chrome 21.0.1180.57 GNU/Linux 64 bits
    Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.57 Safari/537.1
  3. Hi Greg,

    Thank you very much.

    Now just what is needed to get my project done. Need to monitor 10 IP addresses. If it does not I’ll have to find a way to be able to choose which of the 10 will be monitored.

    Thanks again.

    Google Chrome 21.0.1180.60 Windows 7
    Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
  4. Hi ! I’m new to atmega328 and arduino. What I need is A way to trigger an output for 30 secondes if unsucces of ping attempt to any website let say after 2 minutes. And It will wait 10 minutes before retest ping … if still unsucess it will trigger the output for 30 secondes again…… and start over after all of these

    Thanks for your help and time

    Internet Explorer 9.0 Windows 7
    Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; MALC)
    1. No problem. The way the code is set up you can just put a delay() in the pingFail() routine as long as you

      #define ledOut
      void pingFail()
      {
        digitalWrite(ledFail, HIGH);
        digitalWrite(ledOk, LOW);
        delay(30 * 1000);
      }

      My code has several places you could hook into, you just need to check the pingRet value (0 is failure) and act on that.

      Google Chrome 22.0.1229.79 GNU/Linux 64 bits
      Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

CommentLuv badge