Go Down

Topic: Simple arduino ethernet communication for beginner (Read 17 times) previous topic - next topic

bgree15

Hey guys.  This is my first arduino project and I'm having trouble figuring out where to start.  Basically, I'm using my arduino to simulate two buttons being pressed on a micro-controller that controls some LEDs for mood lighting.  All I need to do is send an integer to the arduino (which corresponds to the mood lighting mode on the controller), and have the arduino use that integer to click through each mode to get to the desired mode.  The issue I'm having is figuring out how to do this.  For example, what program (or should I use a web page somehow) do I use to allow the user to enter a number, and send that number to the arduino to use.  It seems pretty simple, and I've been reading and searching how to do it, but I'm just not really getting it.  I've taken two courses of C++, so I can understand the code for the most part. Would it be easier to use a program or use a web page to do this?  I guess preferably a web page would be cooler, but I don't have a clue where to start with that.  I hope this isn't too much to ask for, and I hope it won't be too difficult to explain. 

Also, the reason I'm not using the arduino to control the lights is because I'm talking about 216 LEDs.  I'm already able to get the arduino to simulate the buttons being pressed, and I already know how I will use the integer to click through modes.  I just need help sending the integer to the arduino.

Thanks

robtillaart

Quote
I just need help sending the integer to the arduino.

by means of ethernet?

start here - http://arduino.cc/en/Reference/Ethernet - and work through the examples, that is the best advice I can give you. If explicit problems with the sample code we can explain them.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

charalamposdoukas

Hello bgree15 and welcome to the world of the Arduino, home automation and IoT!

Allow me to suggest you chapter 7 of this book: http://www.buildinginternetofthings.com/table-of-contents/chapter-7. You can find great introductory content on how to program your Arduino and make it communicate with the Internet.

The source code for the projects described is free and accesible from here: http://www.buildinginternetofthings.com/wp-content/uploads/code/CH07_CODE.zip

More specifically to your question, you can either try to host a simple html page on your Arduino (following the default WebServer example included in your Arduino IDE using the Ethernet library) or use something more sophisticated like WebSockets and Pusher service, so that you can enter the integer online without worrying about firewalls, etc. Another solution would be to have your Arduino periodically check for that integer number on a remote page (using a sketch similar to the WebClient example). Not the best way (it introduces a lot of requests to the web server and delay into updating the value at the Arduino) but maybe the easiest in your case.

Hope this has helped a bit,

Best
Charalampos

bgree15

Thanks. I'll definitely take a look at that!

zoomkat

Some test code that uses a form with an input box to send data to the arduino. Open the serial monitor to see what the arduino is receiving when data is sent from the web page.

Code: [Select]

//zoomkat 3-25-12
//submit box code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84);; //server port

String readString;

//////////////////////

void setup(){

  pinMode(4, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();

  //enable serial data print
  Serial.begin(9600);
  Serial.println("servertest1"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString);

          //now output HTML data header

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>HTML form GET example</H1>");

          client.println("<FORM ACTION=\"http://192.168.1.102:84\" method=get >");

          client.println("Pin 4 \"on\" or \"off\": <INPUT TYPE=TEXT NAME=\"LED\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\"><BR>");

          client.println("<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"Change Pin 4!\">");

          client.println("</FORM>");

          client.println("<BR>");

          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();

          /////////////////////
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(4, HIGH);    // set pin 4 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

bgree15

zoomkat,

Thanks for the code! I've been searching on and off for WEEKS and I finally got it working!  You have no idea how much trouble I've spent trying to figure all this out haha. 

Aliende


It seems pretty simple, and I've been reading and searching how to do it, but I'm just not really getting it


Thank you very much for creating this thread :D, havent tested the solution yet, but I was on the same situation, every time I searched for "arduino receive data through ethernet" I found arduino hosting pages or accessing them, but never reading data from the request (POST and GET parameters).

Although, I found this very interesting library called RESTduino wich I am using on my project, it´s really awesome and works like a charm.


zoomkat

Quote
I searched for "arduino receive data through ethernet" I found arduino hosting pages or accessing them, but never reading data from the request (POST and GET parameters).


That would be an ethernet client function, which has has a good bit of code posted on the board. Below is some client test code.

Code: [Select]

//zoomkat 9-22-12
//simple client test
//for use with IDE 1.0.1
//with DNS, DHCP, and Host
//open serial monitor and send an e to test
//for use with W5100 based ethernet shields

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address

char serverName[] = "web.comporium.net"; // zoomkat's test web page server
EthernetClient client;

//////////////////////

void setup(){

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }

  Serial.begin(9600);
  Serial.println("Better client test 9/22/12"); // so I can keep track of what is loaded
  Serial.println("Send an e in serial monitor to test"); // what to do to test
}

void loop(){
  // check for serial input
  if (Serial.available() > 0) //if something in serial buffer
  {
    byte inChar; // sets inChar as a byte
    inChar = Serial.read(); //gets byte from buffer
    if(inChar == 'e') // checks to see byte is an e
    {
      sendGET(); // call sendGET function below when byte is an e
    }
  } 
}

//////////////////////////

void sendGET() //client function to send/receive GET request data.
{
  if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    Serial.println("connected");
    client.println("GET /~shb/arduino.txt HTTP/1.0"); //download text
    client.println("Host: web.comporium.net");
    client.println(); //end of get request
  }
  else {
    Serial.println("connection failed"); //error message if no client connect
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read(); //gets byte from ethernet buffer
    Serial.print(c); //prints byte to serial monitor
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop(); //stop client

}

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

alacosta

Hi All  also a new comer!  - trying to get my head round Arduino / Ethernet .
Need some help
I can use "get" to turn on / off led but need to be able to read an analogue  digital value to control the brightness / speed  of a light or motor.
I would  appreciate some sample code to read /convert the http value (string?)  to  control the arduino analogue pin. Keep searching but can seem to find what I am looking for so any help guidance would be appreciated.

zoomkat

Quote
I would  appreciate some sample code to read /convert the http value (string?)  to  control the arduino analogue pin. Keep searching but can seem to find what I am looking for so any help guidance would be appreciated.


Get your code working with the serial monitor first, then the ethernet part should be easy.
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

Aliende


Quote
I would  appreciate some sample code to read /convert the http value (string?)  to  control the arduino analogue pin. Keep searching but can seem to find what I am looking for so any help guidance would be appreciated.


Get your code working with the serial monitor first, then the ethernet part should be easy.


zoomkat, what about reading POSTed parameters, that´s what I need to do.


spatula

POST and GET belong to the HTTP protocol on top of TCP. The Ethernet library provides TCP. People usually write code to implement some minimal HTTP support, but this rarely gets beyond answering GET requests (which are of mime type text). POST requests have mime type multipart/form-data. They are more difficult to parse, and I doubt that the limited memory the Arduino can do a good job. But I can't see why one would want to send POST requests to the Arduino server, instead of using GET. You send a request:

Code: [Select]

GET /whatever/since/its/a/fake/webserver?param1=value1&param2=value2 HTTP1/0


Then it's up to your code to parse the string to extract the query string (the part beginning with ?), the parameters and their values. You should return some response to the client (e.g., "200 OK" followed by some text or HTML). There are many examples around, but they are always specific to a certain problem because you cannot implement the entire HTTP protocol. If you only want to set a PIN to HIGH or LOW you can even dispense with the query-string part and use "clean URLs" (sort-of):

Code: [Select]

GET /pin/1/LOW
GET /pin/2/HIGH


Then use your preferred method to locate a string within a string (strstr, strcmp, sscanf), apply the values, and you're done.

zoomkat

Quote
zoomkat, what about reading POSTed parameters, that´s what I need to do.


Server test code that will echo posted data to the serial monitor.

Code: [Select]

/*
A simple web server using an Arduino Wiznet Ethernet shield.
For Arduino IDE V1.0 only. Previous IDE versions require mods to this code.

Original code created 18 Dec 2009
by David A. Mellis
modified 4 Sep 2010
by Tom Igoe
modified 18 Jan 2012
by Tim Dicus
*/

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
//address will look like http://192.168.1.102:84 when submited
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip( 192,168,1,102 );
IPAddress gateway( 192,168,1,1 );
IPAddress subnet( 255,255,255,0 );
//IPAddress dns( 192,168,1,1 );

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(84);

void setup()
{
  Serial.begin(9600);

  // set SPI SS pins on w5100 and SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // start the SD interface here if you want.
  // Add the SD.h library above
  // SD.begin(4);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, dns, gateway, subnet);
  // disable w5100 SPI so SD SPI can work with it
  digitalWrite(10,HIGH);
  delay(2000);
  server.begin();

  Serial.println("setup finished");
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      while(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) {

// Here is where the POST data is. 
          while(client.available())
          {
             Serial.write(client.read());
          }
          Serial.println();

          Serial.println("Sending response");
          // send a standard http response header
          client.println("HTTP/1.0 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<HTML><BODY>TEST OK!");
         
         
//form added to send data from browser and view received data in serial monitor         
client.println("<FORM ACTION=\"http://192.168.1.102:84\" METHOD=\"post\">");
client.println("Name: <INPUT TYPE=\"TEXT\" NAME=\"Name\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\"><BR>");
client.println("Email: <INPUT TYPE=\"TEXT\" NAME=\"Email\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\"><BR>");
client.println("<INPUT TYPE=\"SUBMIT\" NAME=\"submit\" VALUE=\"Sign Me Up!\">");
client.println("</FORM>");
client.println("<BR>");
         
          client.stop();
        }
        else 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;
        }
      }
    }
    Serial.println("Disconnected");
  }
}

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

Aliende

Thanks a lot for your help spatula & zoomkat.


But I can't see why one would want to send POST requests to the Arduino server, instead of using GET.


The reason of this is that I need to send a large amount of data +20 parameters, I did not find nice to send that amount of data via GET request. Not saying that it is a bad thing to do.


Quote
zoomkat, what about reading POSTed parameters, that´s what I need to do.


Server test code that will echo posted data to the serial monitor.

Code: [Select]

/*
A simple web server using an Arduino Wiznet Ethernet shield.
For Arduino IDE V1.0 only. Previous IDE versions require mods to this code.

Original code created 18 Dec 2009
by David A. Mellis
modified 4 Sep 2010
by Tom Igoe
modified 18 Jan 2012
by Tim Dicus
*/

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
//address will look like http://192.168.1.102:84 when submited
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip( 192,168,1,102 );
IPAddress gateway( 192,168,1,1 );
IPAddress subnet( 255,255,255,0 );
//IPAddress dns( 192,168,1,1 );

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(84);

void setup()
{
  Serial.begin(9600);

  // set SPI SS pins on w5100 and SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // start the SD interface here if you want.
  // Add the SD.h library above
  // SD.begin(4);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, dns, gateway, subnet);
  // disable w5100 SPI so SD SPI can work with it
  digitalWrite(10,HIGH);
  delay(2000);
  server.begin();

  Serial.println("setup finished");
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      while(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) {

// Here is where the POST data is. 
          while(client.available())
          {
             Serial.write(client.read());
          }
          Serial.println();

          Serial.println("Sending response");
          // send a standard http response header
          client.println("HTTP/1.0 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<HTML><BODY>TEST OK!");
         
         
//form added to send data from browser and view received data in serial monitor         
client.println("<FORM ACTION=\"http://192.168.1.102:84\" METHOD=\"post\">");
client.println("Name: <INPUT TYPE=\"TEXT\" NAME=\"Name\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\"><BR>");
client.println("Email: <INPUT TYPE=\"TEXT\" NAME=\"Email\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\"><BR>");
client.println("<INPUT TYPE=\"SUBMIT\" NAME=\"submit\" VALUE=\"Sign Me Up!\">");
client.println("</FORM>");
client.println("<BR>");
         
          client.stop();
        }
        else 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;
        }
      }
    }
    Serial.println("Disconnected");
  }
}




That worked perfectly! Getting params as expected inside the request:
Name=test&Email=asd%40asd&submit=Sign+Me+Up%21

Go Up