/* Hi guys, I have been searching for 2 days trying to figure out how to update DynDNS using an arduino. I finally cracked it by searching all over the place and combining code from different sources. so i though i would share the completed and tested working code with the community. This was updated using IDE 1.8.1 An original arduino UNO and Ethernet shield with the standard library's were used, nothing special. The reason for this is i have a BT modem which does not have a static ip address or allow the functionality of auto update of a DDNS account. Web client to detect WAN IP address of the arduino and update DynDNS Dyn offers a free web IP detection tool: https://help.dyn.com/remote-access-api/checkip-tool/ Arduino check IP here: http://checkip.dyndns.com:8245/ Answer received: Current IP CheckCurrent IP Address: 93.91.152.138 Circuit: * Arduino UNO * Ethernet shield attached created 18 Jan 2016 by Petr Hubacek, RobotPlace Updated 13 Mar 2017 John Smith - Easy2pc Ltd Tested on Arduino IDE 1.8.1 */ #include #include //****** TO MODIFY **************/ byte mac[] = { 0x00, 0x2B, 0xBE, 0xAE, 0xFE, 0x1D }; String robotName = "Web client get WAN IP from checkip.dyndns.org"; String sourceCode = ""; String robotOwner = ""; //***** TO MODIFY ***************/ //--------- New Variables -----------/ String ip_address = ""; //newly read ip address from _ip String ip_address_old = ""; // old ip address used for comparison char match_fail = 0; // match failure = true int delay_value = 30000; // 7200000 = 2 hours //frequency to check ext IP byte domaindydns[]= { 204, 13, 248, 112 }; // members.dyndns.org char hostname[ ] = "**********.dyndns.org"; // put your hostname here char userpwdb64[ ] = "*****************"; //http://www.functions-online.com/base64_encode.html use-> username:password // the above bit caught me out you have to put your username:password in the box and encode the whole lot. //-----------------------------------/ // use DNS or the numeric IP for the server: // answer {"ip":"93.91.152.138"}"; IPAddress server(216, 146, 43, 70); // numeric IP for checkip.dyndns.org (no DNS) // char server[] = "http://checkip.dyndns.org"; // name address for checkip.dyndns.org (using DNS) // Initialize the Ethernet client library EthernetClient client; EthernetClient clientdyn; String readBuffer = ""; void setup() { Serial.begin(57600); Serial.println(F("----- SETUP START ------")); //Serial.print(F("robotName = ")); //Serial.println(robotName); //Serial.print(F("codebender source = ")); //Serial.println(sourceCode); Serial.print(F("MAC: ")); for(int i = 0; i < 6 ; i++) { Serial.print(mac[i], HEX); if(i < 5) Serial.print(F(".")); } Serial.println(); Serial.print(F("DHCP: ")); // --------------- start the Ethernet connection using DHCP: ----------------- if (Ethernet.begin(mac) == 0) { Serial.println(F("DHCP Failed")); Serial.println(F("Board stops")); // no point in carrying on, so do nothing forevermore: for(;;) ; } // --------------- give the Ethernet shield a second to initialize: ------------------- delay(1000); Serial.print(F("LAN IP: ")); for(int i = 0; i < 4 ; i++) { Serial.print(Ethernet.localIP()[i]); if(i < 3) Serial.print('.'); } Serial.println(); } //----------------- Main Loop ----------------------------------------------- void loop() { Serial.println("-------------- get_wan_ip --------------"); get_wan_ip(); Serial.print("String ip_address: "); Serial.println(ip_address); Serial.print("String ip_address_old: "); Serial.println(ip_address_old); Serial.println("-------------- check_for_difference --------------"); check_for_difference(); //delay (60000); delay(delay_value); } //---------------------------------------------------------------- void get_wan_ip() // Get Public WAN ip address { Serial.print(F("connecting...")); // if you get a connection, report back via serial: if(client.connect(server, 8245)) // you can use port 80, but this works faster { Serial.println(F("Connected OK")); client.println("GET / HTTP/1.0"); // Make a HTTP request: client.println("Host: checkip.dyndns.org"); client.println("Connection: close"); client.println(); //******************************** String _ip = "0"; //wait until a client is available while ( _ip == "0" || millis() < 10000 ) { if (client.available()) // read incoming bytes available from the server { delay(10); //give time to receive whole message to the buffer while (client.available()) { char c = client.read(); readBuffer += c; Serial.print(c); if (readBuffer.length() > 100) { readBuffer = readBuffer.substring(70, readBuffer.length()); } } int pos_start = readBuffer.indexOf("IP Address") + 12; // add 10 for "IP Address" and 2 for ":" + "space" int pos_end = readBuffer.indexOf("", pos_start); // add nothing _ip = readBuffer.substring(pos_start, pos_end); Serial.print(F("WAN IP: ")); Serial.println(_ip); ip_address=_ip; // put the read ip address into the variable ip_address readBuffer = ""; client.stop(); } } } else { Serial.println("failed"); // no connection to the server: } Serial.println(F("SETUP end")); } //----------------------------------------------------------------------------------------- void check_for_difference() { Serial.println(); { if (ip_address != ip_address_old) // compare the new and old readings { match_fail = 1; }//end if else match_fail = 0; if (match_fail == 1) { Serial.println("DOES NOT MATCH"); update_dyndns(); // Call the update void update_dyndns() ip_address_old = ip_address; } else { Serial.println("MATHCHES"); Serial.println(" No Update Required "); } Serial.println(); } } //----------------------------------------------------------------------------------------- void update_dyndns() { int timeout=0; Serial.println("----------- UPDATING DYN DNS -------------"); Serial.print("connecting to "); Serial.println(ip_to_str(domaindydns)); Serial.print("IP to push to DynDns: "); Serial.println(ip_address); if (clientdyn.connect(domaindydns, 80)) { Serial.println("connected"); clientdyn.print("GET /nic/update?hostname="); clientdyn.print(hostname); clientdyn.print("&myip="); clientdyn.print(ip_address); clientdyn.println(" HTTP/1.0 "); clientdyn.print("Host: "); //clientdyn.println("Host: members.dyndns.org "); clientdyn.println(ip_to_str(domaindydns)); clientdyn.print("Authorization: Basic "); clientdyn.println(userpwdb64); clientdyn.println("User-Agent: futura - arduinodydns - 1.1"); clientdyn.println(); } else { Serial.println("connection failed"); } delay(1000); while (!clientdyn.available() && timeout<50) { timeout++; Serial.print("Time out "); Serial.println(timeout); delay(100); } while (clientdyn.available()) { if (clientdyn.available()) { char c = clientdyn.read(); Serial.print(c); } } if (!clientdyn.connected()) { Serial.println(); Serial.println("disconnecting."); clientdyn.stop(); } } // This is just a little utility function to format an IP address as a string. const char* ip_to_str(const uint8_t* ipAddr) { static char buf[16]; sprintf(buf, "%d.%d.%d.%d\0", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]); return buf; }