Communicating with arduino/ethernet shield through the interweb

Greetings everybody!
Long time creeper on the forum, first time poster. Anyway I was hoping you fine folk of the internet machine may be able to point me in the right direction. Currently I have setup my arduino+ethernet shield. I have this then connected to a group of LEDs (for testing purposes). I have written a program that allows me to communicate with my arduino via my LAN (local access network) by opening any browser on any device (provided it is connected to the network, wired or wirelessly) and going to the ip address of my arduino. This then brings up a html page, that I wrote in my sketch, containing buttons that when pressed turn the LED on/off. This is beautiful.

HOWEVER!

I would like to be able to communicate with my arduino/ethernet shield from anywhere in the world. I am aware that in order to do this I must have a static IP address. My ISP do not provide me with one so I set up one with no-ip. I then forwarded an appropriate port from my router (example port 81) and edited my sketch to accommodate for this. I can now access my arduino from anywhere via the interweb. For example I type the host name (http://genericexamplehere.no-ip.org) into my browser from a remote location, i.e. from outside my LAN. This then brings me to my html page that allows me to turn LEDs on/off. But whenever I click on one of the html links i.e. on/off buttons the webpage doesn't relay the information back to my arduino and thus the LEDs are not switched. I have searched for an answer to this but have not been able to find an appropriate solution. If anybody would be so kind as to point me in the right direction or offer any information on steps I must complete in order to get this working I would be very much obliged.
Thank you in advance fantastic members of this community!

I then forwarded an appropriate port from my router (example port 81) and edited my sketch to accommodate for this. I can now access my arduino from anywhere via the interweb. For example I type the host name (http://genericexamplehere.no-ip.org) into my browser from a remote location, i.e. from outside my LAN.

Typically, when you forward a port other than 80, that needs to be part of your URL:
http://genericexamplehere.no-ip.org:81

What does the served up page look like? Is it redirecting to the proper port?

Im actually using port 80 as the forwarded port. When I go to example.no-ip(dot)org:80 it serves up the same webpage as is served when i type the ip of the arduino into my browser from my LAN. When I click a html button to toggle the Led it just replies with a "cannot find webpage" etc... Thanks for your reply mate, great people on here.

Sounds like the button url link on your web page is not correct.

Thanks for the replies lads, I'm gonna post some of my code here and if anybody can see any reasons why I can get this to work in my LAN but not through the internet please let me know. I could really do with the help!

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

// Enter MAC address and IP that is assigned to microcontroller
//In this case I used 192.168.1.4

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 4 }; // ip in lan 
byte gateway[] = { 192, 168, 1, 1 }; // internal ip of my router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask

EthernetServer server(80);

//Declare pins to be used as fixed integers;
int pin2 = 2;

String s = String(30); //string for fetching data from address
String cmd = "/X" ; //X is any variable of the command that will come after the ethernet address in the GET...

void setup() 
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.println(Ethernet.localIP());
  Serial.println("Home Lighting Automation V1.0");
  Serial.println("Ethernet Ready");
  Serial.println("Server Ready");
  
  //Set Arduino pins as outputs
  
  pinMode(pin2, OUTPUT);
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("INCOMING REQUEST FROM CLIENT");
    // an http request ends with a blank line
    
    boolean currentLineIsBlank = true;
    boolean DoPage=true;
    
    while (client.connected()) {
        if (client.available()) {
               char c = client.read();
               // if you've gotten to the end of the line (received a newline
              // character) and the line is blank, the http request has ended,
             // so you can send a reply
               
           // Serial.write(c);     // Remove (//) for debug! (prints incoming client, get, host, connection
                                  //accept, user and all encoding)
                                                     
               if (s.length() < 7) { s.concat(c); }   // build up a short string to parse
               if(s.substring(0,3) == "GET" & DoPage){    // check for the GET from the web page
                    
                     cmd=s.substring(4,6);        // get the 2 letters in the string out and call this the CMD,  /A, or /B or /H etc, these come in after the GET
                     // Serial.println("CMD=");  // Remove (//) for debug!
                     //Serial.println(cmd);     // Remove (//) for debug!
                     
          
                     // Recieved a GET command from client, 
                     //compare the received command to the specific command and then execute
                     
                     if (cmd == "/A" && DoPage) {
                                Serial.println(F("Relay 1 Activated"));  
                                digitalWrite(pin2, HIGH);    
                               DoPage = false;
                     } 
}
        
        
              // if you've gotten to the end of the line (received a newline
              // character) and the line is blank, the http request has ended,
              // so you can send a reply
              if (c == '\n' && currentLineIsBlank) {
              // send a standard http response header
                      client.println(F("HTTP/1.1 200 OK"));
                      client.println(F("Content-Type: text/html"));
                      client.println(F("Connnection: close"));
                      client.println();
                      client.println(F("<!DOCTYPE HTML>"));
                      client.println(F("<html>"));
                      client.println(F("<head>"));
                      client.println(F("<meta content='text/html; charset=ISO-8859-1'http-equiv='content-type'>"));
                      client.println(F("<title>Home Lighting Automation"));
                      client.println(F("</title>"));
                      client.println("<font color='black'><h1 align=center>Home Automation V1.2</font></h1>");
                      client.println(F("</head>"));
                      // the next line sets the background color to something nice like blue
                      client.println(F("<body style='background-color:#58ACFA'>"));
                      //  load in a background .jpg for the web page.
                      client.println(F("<BODY BACKGROUND='#CEECF5' style='width: 481px; height: 690px;'></span>
"));
                      //  set up some HTML that has buttons with specific actions that link back to the arduino at the 
                      address of the arduino and have a specific string 
                      client.println(F("<FORM METHOD='LINK' ACTION='http://192.168.1.4/A\r'><INPUT TYPE='submit' VALUE='Light 1 On'></FORM>  "));  
                      client.println("</html>");
                      client.println("
");
                      client.println("<font color='black' size='3'>Copyright&#169; 2012 Cathal Cavanagh, All Rights Reserved.</h1>");
                      client.println("
");
                      // Clear out the received string
                      s="";
                      break;
                }
                if (c == '\n') {
                      currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                      currentLineIsBlank = false;
                }
          }
    }
    client.stop();
    Serial.println("Client finished sending request");
    
  }
  
}  // end

This line of code will work from your local network, but not from outside because 192.168 addresses can't be seen outside their gateway:

       client.println(F("<FORM METHOD='LINK' ACTION='http://192.168.1.4/A\r'><INPUT TYPE='submit' VALUE='Light 1 On'></FORM>  "));

Replace the 192.168.1.4 with your external domain name and see if that helps when you click.

-br

Billroy, cannot begin to thank you enough. Your a saint! If I were to replace that external ip with http://myhostname.no-ip(dot)com would it still work?

Yes, that is what I meant by "replace the fixed IP with your external domain name".

-br

Thanks again billroy, I've been pulling my hair out trying to figure this one. Can't thank you enough!

hey i know that this post is over a year old, but i really need this help. im working on a very similar project where i must control an led over the internet from outside of my LAN, however i am using the WIFI SHIELD instead of the Ethernet, would i only have to change the library in the beginning of this code and my specific network settings to get this to work?? any help will be greatly appreciated.