I have this web client example that gets an IP address via DHCP. It connects to my router at IP address 192.168.0.1 successfully, but then it fails to send a GET HTTP to google.com. Essentially, I cannot allow the traffic from Arduino to go out into the Internet.
I have a Linksys/Cisco E2000 router connected to the Arduino.
My code is below.
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetDHCP.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x78, 0x0B};
byte ip[] = {192, 168, 0, 125};
byte gateway[] = {192, 168, 0, 1};
byte subnet[] = {255,255,255,0};
byte serverLocal[] = { 192,168,0,1 }; // Google
byte serverExternal[] = { 173,194,33,104 }; // Google
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
Client clientLocal(serverLocal, 80);
Client clientExternal(serverExternal, 80);
const char* ip_to_str(const uint8_t*);
void setup() {
Serial.begin(9600);
Serial.println("Attempting to obtain a DHCP lease...");
// Initiate a DHCP session. The argument is the MAC (hardware) address that
// you want your Ethernet shield to use. This call will block until a DHCP
// lease has been obtained. The request will be periodically resent until
// a lease is granted, but if there is no DHCP server on the network or if
// the server fails to respond, this call will block forever.
// Thus, you can alternatively use polling mode to check whether a DHCP
// lease has been obtained, so that you can react if the server does not
// respond (see the PollingDHCP example).
EthernetDHCP.begin(mac);
// Since we're here, it means that we now have a DHCP lease, so we print
// out some information.
const byte* ipAddr = EthernetDHCP.ipAddress();
const byte* gatewayAddr = EthernetDHCP.gatewayIpAddress();
const byte* dnsAddr = EthernetDHCP.dnsIpAddress();
Serial.println("A DHCP lease has been obtained.");
Serial.print("My IP address is ");
Serial.println(ip_to_str(ipAddr));
Serial.print("Gateway IP address is ");
Serial.println(ip_to_str(gatewayAddr));
Serial.print("DNS IP address is ");
Serial.println(ip_to_str(dnsAddr));
// if you get a connection, report back via serial:
if (clientLocal.connect()) {
Serial.println("connected internally");
// Make a HTTP request:
clientLocal.println("GET /index.html HTTP/1.0");
clientLocal.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed internally");
}
// if you get a connection, report back via serial:
if (clientExternal.connect()) {
Serial.println("connected externally");
// Make a HTTP request:
clientExternal.println("GET /search?q=arduino HTTP/1.0");
clientExternal.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed externally");
}
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (clientLocal.available()) {
char c = clientLocal.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!clientLocal.connected()) {
Serial.println();
Serial.println("disconnecting.");
clientLocal.stop();
}
// if there are incoming bytes available
// from the server, read them and print them:
if (clientLocal.available()) {
char c = clientLocal.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!clientExternal.connected()) {
Serial.println();
Serial.println("disconnecting.");
clientExternal.stop();
// do nothing forevermore:
for(;;)
;
}
}
// Just a utility function to nicely format an IP address.
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;
}
Here's an example of working code (maybe you used this as a source?). The only differences I could see are the lines:
Serial.begin(9600);
delay(1000);
just before the line:
if (clientLocal.connect()) {
I doubt the additional Serial.begin() has any effect but the delay() may be required (although it's a long shot...)
Related
Hi I am absolute newbee using ENC28J60, I want to upload some data to my seerver (in php) :
I take a php hosting from 0fees and now I can send the data to my server using : http://ashutest123.0fees.us/dataupload1.php?data=somedata and check the uploaded list of data in the table as http://ashutest123.0fees.us/showdata.php ——— u can take a view yourself.
I wrote an arduino code (using Aruino Uno and ENC28J60 module from ebay.in) using UIPEthernet lib
#include <UIPEthernet.h> // Used for Ethernet
// **** ETHERNET SETTING ****
// Arduino Uno pins: 10 = CS, 11 = MOSI, 12 = MISO, 13 = SCK
// Ethernet MAC address - must be unique on your network - MAC Reads T4A001 in hex (unique in your network)
byte mac[] = { 0x54, 0x34, 0x41, 0x30, 0x30, 0x31 };
// For the rest we use DHCP (IP address and such)
EthernetClient client;
char server[] = "ashutest123.0fees.us"; // IP Adres (or name) of server to dump data to
int interval = 5000; // Wait between dumps
void setup() {
Serial.begin(9600);
Ethernet.begin(mac);
Serial.println("Tweaking4All.com - Temperature Drone - v2.0");
Serial.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
Serial.print("IP Address : ");
Serial.println(Ethernet.localIP());
Serial.print("Subnet Mask : ");
Serial.println(Ethernet.subnetMask());
Serial.print("Default Gateway IP: ");
Serial.println(Ethernet.gatewayIP());
Serial.print("DNS Server IP : ");
Serial.println(Ethernet.dnsServerIP());
}
void loop() {
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("-> Connected");
// Make a HTTP request:
client.print( "GET /dataupload1.php?");
client.print("data=");
client.print( "somedata" );
client.println( " HTTP/1.1");
client.print( "Host: " );
client.println(server)
client.println( "Connection: close" );
client.println();
client.println();
client.stop();
}
else {
// you didn't get a connection to the server:
Serial.println("--> connection failed/n");
}
delay(interval);
}
when I run it in serial monitor it shows all ip, dns, gateway etc addresses as 0.0.0.0 ---- seems no dhcp abtained
then shows "connected"
no data goes to my server
Please help me I am in a need of it
Thanks in advance
You might want to try this example code, it might help you alot to understand your problem and where it come from.
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
// this check is only needed on the Leonardo:
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for (;;)
;
}
// print your local IP address:
printIPAddress();
}
void loop() {
switch (Ethernet.maintain())
{
case 1:
//renewed fail
Serial.println("Error: renewed fail");
break;
case 2:
//renewed success
Serial.println("Renewed success");
//print your local IP address:
printIPAddress();
break;
case 3:
//rebind fail
Serial.println("Error: rebind fail");
break;
case 4:
//rebind success
Serial.println("Rebind success");
//print your local IP address:
printIPAddress();
break;
default:
//nothing happened
break;
}
}
void printIPAddress()
{
Serial.print("My IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
}
Then I let you edit your code with your custom functions to get all informations you might need.
Note that if you set an hard-coded IP address even in a DHCP range it will be working.
V.
I've recently bought an Arduino ethernet shield but couldn't get it work.
I've tried to use the example's code but it did not work. I have even tried to get a static IP without DHCP and it's always the same problem .
I've used this code :
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xE1, 0xBF };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS)
char server[] = "www.google.com"; // name address for Google (using DNS)
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,10);
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected");
// Make a HTTP request:
client.println("GET /search?q=arduino HTTP/1.1");
client.println("Host: www.google.com");
client.println("Connection: close");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
}
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
while(true);
}
}
and I got this answer:
Failed to configure Ethernet using DHCP
connecting...
connected
disconnecting.
How can I be sure that my ethernet shield is working correctly and how can I resolve this problem?
With a failed DHCP you don't have DNS address to resolve "www.google.com".
Modify your code like this and try again :
IPAddress server(74,125,232,128);
//char server[] = "www.google.com";
I'm testing the Ethernet shield with an Arduino Uno, and I'm getting a DHCP error just using the example sketch.
#include <SPI.h>
#include <Ethernet.h>
byte MACaddress[] = { 0x90, 0xAD, 0xDA, 0x0D, 0x96, 0xFE };
EthernetClient client;
void setup() {
Serial.begin(9600);
while (!Serial) {
;
}
// Start the Ethernet connection:
if (Ethernet.begin(MACaddress) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
for(;;)
;
}
Serial.print("My IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
}
void loop() {
}
I've opened the router administration page, and I can see it gave the Arduino an IP address, associated with the MAC address. I've also tried a static IP address in the code (Ethernet.begin(MACaddress, IPaddress)), but it won't work either.
I can't ping the shield IP address that shows in the router administrator page.
What is wrong with just this simple code?
Everything is out of the box, the Arduino and the shield. I haven't done anything with them, just connected the shield to the Arduino and sent the code. It seems everything is working fine, the LEDs are blinking for both boards.
These loops are useless.. Could you try something like:
#if defined(ARDUINO) && ARDUINO > 18
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDHCP.h>
// MAC Address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
const char* ip_to_str(const uint8_t*);
// Initialize the Ethernet server library
Server server(8080);
void setup()
{
Serial.begin(9600);
Serial.println("Attempting to obtain a DHCP lease...");
// Initiate a DHCP session. The argument is the MAC (hardware) address that
// you want your Ethernet shield to use. This call will block until a DHCP
// lease has been obtained. The request will be periodically resent until
// a lease is granted, but if there is no DHCP server on the network or if
// the server fails to respond, this call will block forever.
// Thus, you can alternatively use polling mode to check whether a DHCP
// lease has been obtained, so that you can react if the server does not
// respond (see the PollingDHCP example).
EthernetDHCP.begin(mac);
// Since we're here, it means that we now have a DHCP lease, so we print
// out some information.
const byte* ipAddr = EthernetDHCP.ipAddress();
const byte* gatewayAddr = EthernetDHCP.gatewayIpAddress();
const byte* dnsAddr = EthernetDHCP.dnsIpAddress();
Serial.println("A DHCP lease has been obtained.");
Serial.print("My IP address is ");
Serial.println(ip_to_str(ipAddr));
Serial.print("Gateway IP address is ");
Serial.println(ip_to_str(gatewayAddr));
Serial.print("DNS IP address is ");
Serial.println(ip_to_str(dnsAddr));
// Start the server
server.begin();
}
void loop()
{
// You should periodically call this method in your loop(): It will allow
// the DHCP library to maintain your DHCP lease, which means that it will
// periodically renew the lease and rebind if the lease cannot be renewed.
// Thus, unless you call this somewhere in your loop, your DHCP lease might
// expire, which you probably do not want :-)
EthernetDHCP.maintain();
// listen for incoming clients
Client client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = 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
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// Some misc. HTML
client.println("<title>Arduino Control Panel</title>");
client.println("<center><h1>Control Panel</h1></center>");
client.println("<p></p>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
client.print("Analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(analogRead(analogChannel));
client.println("<br />");
}
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
// Just a utility function to nicely format an IP address.
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;
}
I'm not sure what you mean by "I've also tried a static IP address in the code". If you simply replaced
if (Ethernet.begin(MACaddress) == 0) {
with
if (Ethernet.begin(MACaddress, myIP) == 0) {
the result may be unpredictable, because there is no return value.
Read
EthernetBegin
Returns
The DHCP version of this function, Ethernet.begin(mac), returns an int: 1 on a successful DHCP connection, 0 on failure. The other versions don't return anything.
have you tried one of the examples with fixed IP's?
I have an Arduino Uno with Ethernet Shield as server, and I make requests on the Arduino through the Internet. I use two libraries to do it (Ethernet.h and SPI.h).
I want to check the client IP address, so I accept only HTTP requests from a known IP address (for example, 50.50.50.50) which is the static IP address in my office. How can I get the the client IP address on the Arduino?
have a look at the following, this works for TCP:
http://forum.arduino.cc/index.php?PHPSESSID=jh6t8omt7vrb8nget5c9j5dbk4&/topic,82416.0.html
The following is a quote from the author's post, I am just copying the excellent work:
To make it work, I did the following:
I added the following lines to the end of the EthernetClient.cpp file:
uint8_t *EthernetClient::getRemoteIP(uint8_t remoteIP[])
{
W5100.readSnDIPR(_sock, remoteIP);
return remoteIP;
}
I then added the following line (under the virtual void stop(); line)to the EthernetClient.h file:
uint8_t *getRemoteIP(uint8_t RemoteIP[]);//adds remote ip address
Finally I used the following code in my sketch to access the remote IP:
client.getRemoteIP(rip); // where rip is defined as byte rip[] = {0,0,0,0 };
to display the IP in the serial monitor, I used:
for (int bcount= 0; bcount < 4; bcount++)
{
Serial.print(rip[bcount], DEC);
if (bcount<3) Serial.print(".");
}
I've done this using UDP, hopefully this will help you.
Get UDP.h from Google here: UDP.h
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
// ***** ETHERNET VARS *****
// MAC address and IP for arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,98};
unsigned int localPort = 8888; // local port to listen on
// SenderIP and SenderPort are set when message is received
byte SenderIP[IP_LENGTH]; // holds received packet's originating IP
unsigned int SenderPort; // holds received packet's originating port
// buffer for receiving data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet
int packetSize = 0;
void setup()
{
Ethernet.begin(mac,ip); //start Ethernet
Udp.begin(localPort); //start UDP
}
void loop()
{
if(NewPortMessage())
{
// Do stuff, SenderIP is the IP where the UDP message was received from
}
}
boolean NewPortMessage()
{
packetSize = Udp.available();
if(packetSize > 0)
{
packetSize -= 8; //subtract UDP 8-byte header
// read the packet into packetBufffer and get the senders IP addr and port number
Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, SenderIP, SenderPort);
return true;
}
clearPacketBuffer();
return false;
}
void clearPacketBuffer()
{
for(int i=0; i < packetSize; i++)
packetBuffer[i] = 0;
}
what about changing the approach? you could use SOA and you could make your arduino a web client instead of a web server.......then you could handle all of this restrictions in the web server that host your web service, this web service will be the core of your app, and this way you could call it from any mobile device you want :D
just an idea arduino web servers are not very useful, with this approach you could use the internet instead of using LAN only
good luck with your project
I have a brand new Ethernet shield on Arduino Uno and have worked through many (non-Ethernet) examples without any issues, until I tried to use the Ethernet shield.
Using the provided EthernetClient example, I get a connection failed. The return code is -5 (and I could only find answers for -4 through 1).
/*
Web client
This sketch connects to a website (http://www.google.com)
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
Created 18 Dec 2009
Modified 9 Apr 2012
by David A. Mellis
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x4E, 0x71 };;
char server[] = "google.com"; // Google
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// Start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for(;;)
;
}
// Give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
Serial.println("Obtaining local IP address");
IPAddress myIPAddress = Ethernet.localIP();
Serial.println(myIPAddress);
// if you get a connection, report back via serial:
int ret = client.connect(server, 80);
if (ret == 1) {
Serial.println("connected");
// Make a HTTP request:
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("Connection failed");
Serial.println(ret);
Serial.println(client.status());
}
}
void loop()
{
// If there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// If the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("Disconnecting.");
client.stop();
// Do nothing forevermore:
for(;;)
;
}
}
The results are always:
Connecting...
Obtaining local IP address
192.168.0.7
Connection failed
-5
0
disconnecting.
Not sure why this helped, but adding a delay after the Serial is intialized, before beginning Ethernet, and also increasing the delay before using Ethernet seemed to work.
/*
Web client
This sketch connects to a website (http://www.google.com)
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
created 18 Dec 2009
modified 9 Apr 2012
by David A. Mellis
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x4E, 0x71 };;
char server[] = "google.com"; // Google
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
delay(5000);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for(;;)
;
}
// give the Ethernet shield a second to initialize:
delay(5000);
Serial.println("connecting...");
Serial.println("Obtaining local IP");
IPAddress myIPAddress = Ethernet.localIP();
Serial.println(myIPAddress);
// if you get a connection, report back via serial:
int ret = client.connect(server, 80);
if (ret == 1) {
Serial.println("connected");
// Make a HTTP request:
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
Serial.println(ret);
Serial.println(client.status());
}
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
for(;;)
;
}
}
That Google IP address (173.194.33.104) is not valid now. Try to use 74.125.226.242 instead:
IPAddress server(74,125,226,242); // Google
And before your try it on Arduino, ensure your can open this IP address in your browser:
http://74.125.226.242
Try defining the server IP address as it is shown on the Arduino Reference Page:
byte server[] = { 64, 233, 187, 99 }; // Google
Try a couple different example programs. There have been some revisions with the move to IDE 1.0 that could affect compatibility.