This post is a version of my previous post with the option of multiple IP addresses to be pinged.
It was requested by one of the people that commented on my blog, Leandro.
I hope it is useful.
/*
Repeatedly ping a number of servers 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[8][4] = { {91,121,5,142}, {91,121,5,143}, {91,121,5,144}, {91,121,5,145}, {91,121,5,146}, {91,121,5,147}, {91,121,5,148}, {91,121,5,149} }; // 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[8][4] = { {91,121,5,142}, {91,121,5,143}, {91,121,5,144}, {91,121,5,145}, {91,121,5,146}, {91,121,5,147}, {91,121,5,148}, {91,121,5,149} }; // ip address to ping
int numAddresses = sizeof(pingAddr[0]);
SOCKET pingSocket = 0;
char buffer [256];
int delayMS = 1 * 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);
}
}
int i = 0;
void loop()
{
bool pingRet; // pingRet stores the ping() success (true/false)
#ifdef ledOut
startPing();
#endif
ICMPPing ping(pingSocket);
byte pingAddr2[] = { pingAddr[i][0], pingAddr[i][1], pingAddr[i][2], pingAddr[i][3] };
pingRet = ping(4, pingAddr2, buffer);
#ifdef ledOut
delay(250);
endPing();
#endif
#ifdef serialOut
Serial.print("i:");
Serial.print(i);
Serial.print(" ");
Serial.println(buffer);
#endif
#ifdef ledOut
if(pingRet) // Failure
pingSuccess();
else
pingFail();
#endif
i++;
if(i >= numAddresses)
i = 0;
delay(delayMS);
}


Excellent! Congratulations!
Enlighten me a thing.
When I put this:
ping (10, pingAddr1, buffer);
if (strcmp (buffer, “Request Timed Out”) == 0) {
In the first line, which becomes the number 10? The number of ping fired?
In the second line, the “== 0″ means only those who lose just one of 10 he will perform what is below? What happens if I put == 1?
Thanks!!
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
ping(10, signifies how many times to retry.
If it receives a reply the first time it returns immediately.
If you check my code I now catch the return value from ping() and check that rather than strcmp.
strcmp returns 0 if the strings match, otherwise it returns 1 or -1.
I hope this helps.
Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19
Hi Greg,
I love your project ….. but
I think this multi IP code does not work as described.
The loop count is determined by “int numAddresses = sizeof(pingAddr[0]);”
Which gives the answer “4″ – the size of the number of bytes in the first IP address – not the number of IP addresses to test. One needs “int numAddresses = sizeof(pingAddr)/4;” to achieve that.
Thus the sample code tests the first 4 addresses OK – but that was not the intention as 4 connections was found to work OK.
If you change that count to 8 I get unreliable results.
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0
Pingback: arduino visual ICMP ping multiple server monitor (ICMP echo request) | labby.co.uk | Arduino Geeks | Scoop.it
We congratulate you Greg,
I attended several forums and nobody could explain to me properly.
I think now I can finish my project.
Thank navamente. I’ll be following your blog.
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1
Leandro
Please keep me informed on how your project goes.
I love challenges like this :)
If you are interested, I am redesigning the code to allow a 2×16 LCD to give a visual indication of which server is being pinged, which are up and which are down.
I will upload the code once I go through and tidy it.
To whet your appetite and keep you coming back here is a youtube video of the current version in operation (sorry it is a little dark):
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.57 Safari/537.1
It’ll be very cool.
Maybe I can use in my project.
I’ll keep you informed yes.
Tonight I speed up my project, and I’ll send for you.
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
Hello Greg,
I made a video of my project.
Do you have any email I can send you my conf to you?
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
Hi Leandro
Great video, I followed it without understanding a word of the voiceover apart from arduino, patch panel, and a few others.
The panel looks very professional.
My domain has catchall email, just use your name as the first part and I will receive it.
I am looking forward to seeing how I helped with this project :)
Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19
Hello Greg,
I sent the files of my project. Maybe you have some idea to improve it.
I want to make an application to communicate with it the same way that php via socket. Would you recommend any specific language?
I was thinking in java.
Actually I have never programmed, do not even know where to start. I put my face as I did with the arduino.
Can you tell me if java is possible to make this connection via socket?
Thanks
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
Greg
I’m abusing you, but it has a little something I’d really like to help me.
In my project I change the ips via php. How do I save in EEPROM the ips that are received by php. To read them in the boot too.
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
Leandro
I am happy to help, I will review the code you sent me.
In the meantime, here is some sample code to write data to the arduino eeprom.
Please be aware that the arduino eeprom memory area has a very limited number of writes (100,000) before it becomes susceptible to failure.
That being said, to write to the eeprom area is actually very straightforward:
#include <EEPROM.h>unsigned char ipAddresses[8][4] =
{
{ 192,168,0,10 },
{ 192,168,0,11 },
{ 192,168,0,12 },
{ 192,168,0,13 },
{ 192,168,0,14 },
{ 192,168,0,15 },
{ 192,168,0,16 },
{ 192,168,0,17 }
};
void setup()
{
/*
Store the initial IP addresses in eeprom memory.
The code below will only write to the eeprom if the
cell is different to the data needed to be stored.
Doing it this way will dramatically increase the
life expectancy of the eeprom.
*/
Serial.begin(9600);
Serial.println("Preparing to write to EEPROM");
int i, j;
unsigned char dot;
for(i = 0; i < 8; i++)
{
Serial.print("Port: ");
Serial.print(i);
Serial.print(" ");
for(j = 0; j < 4; j++)
{
Serial.print("dot: ");
Serial.print(j);
Serial.print(" ");
dot = EEPROM.read((i * 4) + j);
if(dot != ipAddresses[i][j])
{
Serial.print("has changed from ");
Serial.print((int)dot);
Serial.print(" to ");
Serial.print(ipAddresses[i][j], DEC);
Serial.print(" - updating EEPROM cell ");
Serial.println((i * 4) + j);
EEPROM.write((i * 4) + j, ipAddresses[i][j]);
}
else
Serial.println("is unchanged");
}
}
}
void loop()
{
int i , j;
unsigned char dot;
for(i = 0; i < 8; i++)
{
Serial.print("Port: ");
Serial.print(i);
Serial.print(" IP: ");
for(j = 0; j < 4; j++)
{
dot = EEPROM.read((i * 4) + j);
Serial.print(dot);
if(j < 3)
Serial.print(".");
else
Serial.println();
/*
The next line updates the IP addresses with the contents of the eeprom
You would do this in your setup() function to populate the ipAddresses[]
rather than with this sample code doing it in loop()
*/
ipAddresses[i][j] = dot;
}
}
Serial.println();
}
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.57 Safari/537.1
I’m a little lost to adapt to my code.
I colcar here two “case” where I get the ip ..
EX:
case ‘A’:
{
char *token = strtok(msg, “,”);
{
int addNum = atoi(token);
token = strtok(NULL, “,”);
int bytePos = 0;
byte byteVals[4];
while(token)
{
byteVals[bytePos++] = atoi(token);
token = strtok(NULL, “,A#”); // Get next token delimited by comma or pound sign
}
for(byte i=0; i<4; i++)
{
pingAddr[0][i] = byteVals[i];
}
}
}
break;
case 'B':
{
char *token = strtok(msg, ",");
{
int addNum = atoi(token);
token = strtok(NULL, ",");
int bytePos = 0;
byte byteVals[4];
while(token)
{
byteVals[bytePos++] = atoi(token);
token = strtok(NULL, ",B#"); // Get next token delimited by comma or pound sign
}
for(byte i=0; i<4; i++)
{
pingAddr[1][i] = byteVals[i];
}
}
}
break;
/////////////////////
Correct me if I'm wrong.
In "case'A '"
for(byte i=0; i<4; i++)
{
pingAddr[0][i] = byteVals[i];
EEPROM.write((0 * 4) + i, byteVals[i]);
}
and "case'B '"
for(byte i=0; i<4; i++)
{
pingAddr[1][i] = byteVals[i];
EEPROM.write((1 * 4) + i, byteVals[i]);
}
Was that it?
And then to read on startup?
I paste in setup ()
for(byte i=0; i<4; i++)
{
ipAddresses[0][i] = EEPROM.read((0 * 4) + i);
ipAddresses[1][i] = EEPROM.read((1 * 4) + i);
}
?
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
Almost correct.
You still need to check each byte and compare it with the byte stored in the eeprom. If it differs write the new byte to the eeprom.
We really could do with collaborating in something like Google docs on this so we can code in realtime.
I never did ask but this does look quite professional. Is it a project for yourself or work?
Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19
Hi Greg,
I am Brazilian, and work in the area of internet service provider. Here in Brazil, most providers are Internet radio.
A long time we need something like this. For here worked very hard with many towers which are placed Ubiquiti and Mikrotik RouterBoard devices that are powered via POE.
So if we can make this project work well, maybe I can even get a partnership with a manufacturer patchpanel poe, there are few here and also in the market are high.
What do you think?
ps. I have little experience with programming. My area is linux servers and networks and mikrotiks.
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1
Continuing …
My idea of what is missing to make him more professional is:
Place a button to reset configuration. Where pressed for 5 seconds all IPs back to default.
type:
IP = 192.168.100.2
Mask = 255.255.255.0
GW = 192.168.100.1
IP tracking of each door, 192,168,100,101, 102, 103 …
The difficulty now is to get the user a way to change the ip, mask, gw, because in php the way it is, every time he change the ip of the equipment, he would have to switch from php also and it is not practical. So I’m thinking of an app to manage it. (ideas are very welcome)
Done this, the basic version is ready.
Then, thinking further ahead.
Place a display equal to his, and also a meter correte on each port to monitor the consumption of the equipments.
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1
Hi Leandro
I would love to collaborate on this with you, but realistically I cannot as I do not have the ubiquiti or microtic hardware making debugging all but impossible for me.
I have rewritten casa3.php for you to make it easier to modify and read.
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.57 Safari/537.1
Just answer me one thing Greg.
There is a possibility to do the same thing this page in php in html inside the arduino? With an SD card I could store the images?
Thanks again.
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1
Yes, this would be quite simple and is exactly what I was thinking of with the email I just sent you.
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.75 Safari/537.1
Hi Greg,
Great work! is it possible to return a MAC address from the ip?
I am working on a project that will let me know who is on my network, the plan is to allow 10 DHCP users on my wifi network, then i will ping those 10 ip’s, if I can get a return MAC address I can build a database of who the users are and give them names. This can be used to show who is home and when and can also be used to integrate to the home automation. Open front door etc. Thanks in advance for your help.
Regards
Doug
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Doug, as it is wifi maybe the router will already have the info – open the router’s info page (http://192.168.0.1 at a guess)and parse the results is one possible method. How you would do that I will leave to you as there is not much chance that my router is the same as yours :)
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.81 Safari/537.1
I am also looking into ARP (Address Routing Protocol) for you.
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.81 Safari/537.1
Hi Greg,
Thanks for the response.
I am using DD-WRT firmware on a linksys wrt54 router.
With this firmware i can allocate a static lease on an ip address to a given mac address. This means if i know the devices mac that will be connecting to my network they will always be given the same ip, so I can use your sketch to ping those devices.
It would still be nice to be able to get the mac address returned for a new device if possible.
While pinging the ip works great in my system, there is one issue. If I arrive home and the phone is in 3g mode it does not switch to wifi while in standby. pressing any button wakes the phone and switches to wifi within seconds. Does anyone know how this could be changed so it happens even in standbye/sleep mode.
Its the same on the Iphone and Galaxy s2 tested.
Regards
Doug
Mozilla/5.0 (Windows NT 6.0; rv:13.0) Gecko/20100101 Firefox/13.0.1
Thanks for the great post!
I want to only ping one address.
But when I change the ip addesses to:
byte pingAddr[1][4] = { {172,16,0,112}}
I still get this:
i:0 Reply[1] from: 172.16.0.112: bytes=32 time=47ms TTL=128
i:1 Request Timed Out
i:2 Request Timed Out
i:3 Request Timed Out
Can someone tell me what I do wrong?
Thanks!
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11
int numAddresses = 1;
Make that change and retry
Mozilla/5.0 (Linux; Android 4.2.1; Galaxy Nexus Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19
Hey Greg! How u doing?
First of all, thank you so much for this!
So… i modify your code to make a watchdog for my “crazy” router…
It keeps pinging on a server online who is always ON, the ip is (200.154.56.80) , and if it don’t got the response the arduino turn off my router and them turn on again.
I have done that because sometimes my router just gets crazy sometimes and just shut down the connection with the internet, and only comes back if i turn him off and on again…
But i’m having a issue, because when my router gets crazy the arduino keeps pinging, not to the ip of the server on the internet but on my router’s ip which is (192.168.1.1). But that’s the thing, because if the arduino keeps pinging it will never make the process of turning off and on again the router. I try to make a “if” comparing the ip’s but with no sucess. Do you have an idea that might help me?
Thanks!!
Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.15