Brick Wall - My ISP does NAT

My ISP does fixed Wireless ( Motorolla Canopy System) which connects to me, not with an external IP, but with an internal one that I have little control over. Because of this I seem to be unable to connect my arduino to the web. I see there are a lot of very knowledgeable people here. Can anyone suggest a possible workaround.

How does your computer connect to the Canopy system? Wireless (wifi) or wired (cat5 cable)?

Yahoo.... I know you can probably help me. Sorry my question was vague. Yes my computer is connected to dlink dir615 with (cat5 cable) , which connects to customer service module 3.5 ghz to an Access point that does NAT. I have the manual for the CSM but no access to it.

That is not a problem if you are planning on using a TCP client connection to servers. Do you have an ethernet shield? If so, which ethernet controller does it have? w5100 or enc28j60?

edit: With that router, you could use a wifi shield also.

The project is a basic home monitor (possibly control). I have several analog and digital inputs on a mega 2560 with w5100 ethernet shield. I also have a webspace with my ISP that has Apache ASP, SSI, PHP, CHI, Perl all available. In truth I'm really not sure just how I might put this all togetherand so am looking for a little direction.

Then you are ok. I recommend a client connection to your ISP's Apache server to start.
http://playground.arduino.cc/Code/WebClient

You should use dhcp to get an ip for your shield, so modify that GET code like this

  // Start ethernet
  Serial.println(F("Starting ethernet..."));
  //  Ethernet.begin(mac, ip, gateway, gateway, subnet);

  // If using dhcp, comment out the line above 
  // and uncomment the next 2 lines

  if(!Ethernet.begin(mac)) Serial.println(F("failed"));
  else Serial.println(F("ok"));
  digitalWrite(10,HIGH);

That should get you started.

edit: The ip for Google is no longer valid. Try this instead.

IPAddress server(74,125,227,145); // Google

Thank you. This will take me some time to understand but it's sure nice to have a compass in the bush.

Once you get that downloading the Google home page, change the server ip to your server ip and the serverName to your domain to download your home page.

char serverName[] = "www.yourdomain.com";

Everything worked great until I tried to get my home page.. Then This
starting ethernet...
ok
192.168.xxx.xxx
Ready
connecting...connected
220 ProFTPD 1.2.10 Server (ProFTPD) [142.xxx.xxx.xxx]
500 GET not understood
500 HOST: not understood
500 CONNECTION: not understood

Timeout

disconnecting.

That is a FTP server response, not a web (http) server. Are you using port 80 in the connection request? If you are, something has gone wrong on the server end.

edit Insure you still have this setting in your global declarations.

// change to your server's port
int serverPort = 80;

FTP is supposed to be port 21.

Oops. Yes Now changed to port 80 and this…
connecting…connected
HTTP/1.1 400 Bad Request
Date: Mon, 10 Feb 2014 08:04:32 GMT
Server: Apache/2.0.52 (Red Hat)
Content-Length: 329
Connection: close
Content-Type: text/html; charset=iso-8859-1

400 Bad Request

Bad Request

Your browser sent a request that this server could not understand.


Apache/2.0.52 (Red Hat) Server at www.users.xplornet.com/~gordswebpage Port 80

Not quite what I expected but it’s a start.

An "Error 400 Bad Request" message normally means there is a format error in the request header. That is this part of the request:

    sprintf(outBuf,"GET %s HTTP/1.1",page);
    client.println(outBuf);
    sprintf(outBuf,"Host: %s",serverName);
    client.println(outBuf);
    client.println(F("Connection: close\r\n"));

Try displaying the request send on the serial monitor, then if it is not apparent, post that here.

    sprintf(outBuf,"GET %s HTTP/1.1",page);
    Serial.println(outBuf);
    client.println(outBuf);
    sprintf(outBuf,"Host: %s",serverName);
    Serial.println(outBuf);
    client.println(outBuf);
    client.println(F("Connection: close\r\n"));

The problem has to be the domain entry I think because if I change it back to www.google.com then the page loads.

// change to your server
IPAddress server(142.166.86.99); // Gords Primary Host

//Change to your domain name for virtual servers
char serverName = "Gords House";
// If no domain name, use the ip address above
// char serverName = "74.125.227.16";

I found the IPAddress server by looking up serverName and translating it. I bet this is wrong.

This should be your serverName

char serverName[] = "users.xplornet.com";

This should be your page

sprintf(pageAdd,"/~gordswebpage/",totalCount);

That did the trick. You have probably saved me a great deal of time floundering around. I’ll have to have a closer look at this code as there are several lines that I want to understand better, but I am now communicating. I’m guessing my next step is to develop some php script to use on the server.

This is probably the most confusing part of my code. It is a timeout in case the connection fails. If the server does not send a packet for 10 seconds, this code considers the connection as broken, and closes the connection from the client end. Otherwise, the code will lock up in the "while(client.connected())" loop.

  // connectLoop controls the hardware fail timeout
  int connectLoop = 0;

  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      // set connectLoop to zero if a packet arrives
      connectLoop = 0;
    }

    connectLoop++;

    // if more than 10000 milliseconds since the last packet
    if(connectLoop > 10000)
    {
      // then close the connection from this end.
      Serial.println();
      Serial.println(F("Timeout"));
      client.stop();
    }
    // this is a delay for the connectLoop timing
    delay(1);
  }

  Serial.println();

  Serial.println(F("disconnecting."));
  // close client end
  client.stop();

OK. I see how that works. I'm just trying to work my way through this

sprintf(outBuf,"GET %s HTTP/1.1",page);
    client.println(outBuf);
    sprintf(outBuf,"Host: %s",serverName);
    client.println(outBuf);
    client.println(F("Connection: close\r\n"));
  }

That is the request send. The important part of that happens in the loop() function. This is how you should pass parameters to your php page. This requests the page arduino.php page sending the parameter “test” with a value determined by the variable totalCount. Note I commented out the original sprintf and used the alternate version.

    // Modify next line to load different page
    // or pass values to server
    // sprintf(pageAdd,"/",totalCount);
   
    sprintf(pageAdd,"/~gordswebpage/arduino.php?test=%u",totalCount);

If the variable totalCount is set to 2, then it is the same as this request in a web browser
http://users.xplornet.com/~gordswebpage/arduino.php?test=2

OK. I not sure I have this.

sprintf(pageAdd,"/arduino.php?test=%u",totalCount);

Will this line create a file on the server and add 'test=2' to it

Edit: I have found a thread from last summer where you cover some of this. I need to go through it.

http://forum.arduino.cc/index.php?topic=171983.0

Pizzanova:
OK. I not sure I have this.

sprintf(pageAdd,"/arduino.php?test=%u",totalCount);

Will this line create a file on the server and add 'test=2' to it

It will if you have a file named arduino.php on your server and use the correct php script in that file. I use MySQL as a database for storing data on my Apache server.