Go Down

Topic: about connecting to Arduino Server with Ethernet through Processing (Read 1 time) previous topic - next topic

MikeLuo

hi Guy:
I am currently working on a project that control the motor and sensor through the Ethernet. I got a Ethernet Shield with Mega. I would like to make the Arduino Mega as server, and user local computer as client by Processing.
My questions are what kind of server I should user for Arduino, web server? chat server or other kinds of server?
If I want to use Processing to build a client GUI. What should I do to make it work with my Arduino?
Is there any information to help me start with?

pYro_65

If you are using the mega as a server, why not have it as aweb server and provide a config page to a browser, rather than trying to connect to processing.

Javascript and ajax will allow you to talk to the Arduino from the web page.

As a web page you can even use your phone to control the Arduino.

MikeLuo

I am connect my computer to a robot, and the Processing is a better software to design my User Interface.

pYro_65

I personally think  a web page is a far better medium for remote control, web technologies are very flexible and powerful these days. I haven't used processing so I'm not much help, however I did find this: http://processing.org/reference/libraries/net/

MattS-UK

#4
Nov 21, 2013, 09:20 am Last Edit: Nov 21, 2013, 11:34 am by MattS-UK Reason: 1
You are entitled to your opinion but I personally think HTTP is a rubbish protocol to use for swapping a few bytes with a micro-controller.    As demonstration of my point.  We have other threads on this forum, running over a dozen pages, attempting to achieve robust HTTP implementations for MCUs and not yet managing it.  Give me a PC with a few MB of RAM and a couple 100Mhz and I could give you robust HTTP in a couple hours!

HTTP was designed to be ubiquitous.   Ubiquity is the USP for HTTP but you have to pay a high cost, in complexity and resources, to achieve it.  

As soon as you lose the requirement for ubiquity, you can lose the need for the verbosity and vagueness of HTTP.  You can design your own 'lean' application protocol (Layer 7) and choose whether to use TCP or UDP to transport it (Layer 3).

For the application layer, you probably want to design a Device Control Block (DCB) - A C structure to hold the device status, with a couple of fields to pass commands.  Serialise the DCB into a single packet and pass it to your choice of transport layer.

For the transport layer, you need to think about what your communication requirements are.

UDP is very lightweight and very easy to implement within the local area.  UDP is very suited to sending real time device status, which does not need acknowledgement.

TCP provides the integrity of session based communication but comes with higher processing overheads.  TCP is much easier to transport onto the wide area, across routers and the internet.  TCP is probably a better choice for sending device commands which require realtime feedback confirmation.

The Ethernet shield has 4 sockets, so you could use UDP for status updates and TCP for command and control.

Robots are typically more about command and control, rather than continual status updates.  So I guess TCP would fit the bill.

The chat server uses  TCP, so is probably the example to start with.  More commonly, the 'chat server' protocol would be referred to as Telnet.   More precisely, the 'chat server' is a simple demonstration of using a TCP socket.

MikeLuo

Thank you Matt. That what I am currently using right now(I was using HTTP :p ). Yesterday, I was using UDP to get communication with the Arduino Ethernet. I realized that the speed (response speed) is very slow. Do you have any idea to fix this problem?

zoomkat

Quote
I was using UDP to get communication with the Arduino Ethernet. I realized that the speed (response speed) is very slow.


What do you consider "slow"? Even http can be fairly quick. If you gave the standard w5100 Ethernet shield, you can try the below code to see the http traffic can be fairly fast for some applications.

Code: [Select]

// zoomkat's meta refresh data frame test page 5/25/13
// use http://192.168.1.102:84 in your brouser for main page
// http://192.168.1.102:84/data static data page
// http://192.168.1.102:84/datastart meta refresh data page
// for use with W5100 based ethernet shields
// set the refresh rate to 0 for fastest update
// use STOP for single data updates

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

const int analogInPin0 = A0;
const int analogInPin1 = A1;
const int analogInPin2 = A2;
const int analogInPin3 = A3;
const int analogInPin4 = A4;
const int analogInPin5 = A5;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // arduino 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
unsigned long int x=0; //set refresh counter to 0
String readString;

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

void setup(){
  Serial.begin(9600);
    // disable SD SPI if memory card in the uSD slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();
  Serial.println("meta refresh data frame test 5/25/13"); // so I can keep track of what is loaded
}

void loop(){
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
         if (readString.length() < 100) {
          readString += c;
         }
        //check if HTTP request has ended
        if (c == '\n') {

          //check get atring received
          Serial.println(readString);

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

          //generate data page
          if(readString.indexOf("data") >0) {  //checks for "data" page
            x=x+1; //page upload counter
            client.print("<HTML><HEAD>");
            //meta-refresh page every 1 seconds if "datastart" page
            if(readString.indexOf("datastart") >0) client.print("<meta http-equiv='refresh' content='1'>");
            //meta-refresh 0 for fast data
            if(readString.indexOf("datafast") >0) client.print("<meta http-equiv='refresh' content='0'>");
            client.print("<title>Zoomkat's meta-refresh test</title></head><BODY><br>");
            client.print("page refresh number: ");
            client.print(x); //current refresh count
            client.print("<br><br>");
           
              //output the value of each analog input pin
            client.print("analog input0 is: ");
            client.print(analogRead(analogInPin0));
           
            client.print("<br>analog input1 is: ");
            client.print(analogRead(analogInPin1));
                       
            client.print("<br>analog input2 is: ");
            client.print(analogRead(analogInPin2));
           
            client.print("<br>analog input3 is: ");
            client.print(analogRead(analogInPin3));
                                   
            client.print("<br>analog input4 is: ");
            client.print(analogRead(analogInPin4));
           
            client.print("<br>analog input5 is: ");
            client.print(analogRead(analogInPin5));
            client.println("<br></BODY></HTML>");
           }
          //generate main page with iframe
          else
          {
            client.print("<HTML><HEAD><TITLE>Zoomkat's frame refresh test</TITLE></HEAD>");
            client.print("Zoomkat's Arduino frame meta refresh test 5/25/13");
            client.print("<BR><BR>Arduino analog input data frame:<BR>");
            client.print("&nbsp;&nbsp;<a href='http://192.168.1.102:84/datastart' target='DataBox' title=''yy''>META-REFRESH</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='http://192.168.1.102:84/data' target='DataBox' title=''xx''>SINGLE-STOP</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='http://192.168.1.102:84/datafast' target='DataBox' title=''zz''>FAST-DATA</a><BR>");
            client.print("<iframe src='http://192.168.1.102:84/data' width='350' height='250' name='DataBox'>");
            client.print("</iframe><BR></HTML>");
          }
          delay(1);
          //stopping client
          client.stop();
          //clearing string for next read
          readString="";
        }
      }
    }
  }
}

Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

MattS-UK

The bottleneck on the Ethernet Shield is the SPI bus.  There is a 255 byte limit on the amount of data the Arduino can write to a UDP packet but you can blat packets out just as fast as your Arduino can go.  I did a rough throughput test yesterday and UDP output is roughly the same as TCP, ~500 to ~800Kbps.

For comparison purposes, I very quickly wrote a UDP equivalent of zoomkat's example.
As you can see, a lot less code and it is a lot less complicated.  Fair enough, you need to write the GUI to run on the PC, but you have much more RAM and CPU, and a choice of sophisticated IDEs at your disposal, to do it with.

Code: [Select]

#include <Streaming.h>

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

byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
IPAddress ip(192, 168, 20, 30);        // <-- ip of your PC

EthernetUDP udp;
uint16_t srcPort = 2000;
uint16_t dstPort = 2000;

void setup()
{
Serial.begin(9600);
Ethernet.begin(mac);
}

typedef struct DCB {
uint32_t timeStamp;
int pinA0;
int pinA1;
int pinA2;
int pinA3;
int pinA4;
int pinA5;
char stringData[32];
byte endData;
} DCB;

uint16_t packetCount = 0;
void loop() {
DCB* dcbData = (DCB*) malloc(sizeof(DCB));
dcbData->timeStamp = millis();
dcbData->pinA0 = analogRead(A0);
dcbData->pinA1 = analogRead(A1);
dcbData->pinA2 = analogRead(A2);
dcbData->pinA3 = analogRead(A3);
dcbData->pinA4 = analogRead(A4);
dcbData->pinA5 = analogRead(A5);
strcpy(dcbData->stringData, "my device\r\n\0");
dcbData->endData = 0;

udp.begin(srcPort);
udp.beginPacket(ip, dstPort);
udp.write( (byte*) dcbData, sizeof(DCB) );
udp.endPacket();
udp.stop();

                free(dcbData);

Serial << "packetCount" << ++packetCount << "\r\n";

delay(1000);   // <--- I don't want to flood my network :D
}


MikeLuo

WOW that's really impressive. I also have another question. I am using processing as client. I use the code that was provided by Arduino's Example but the problem is, no message was sent back from Arduino. I don't know what's going on?

MattS-UK

Unfortunately I am going to be away from my PC until after the weekend.

Can you post the code that you have?


zoomkat

Code: [Select]
delay(1000);   // <--- I don't want to flood my network :D

Not sure why you use a delay if you want speed. My code runs ~16x faster with out a delay and has run for days.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

MikeLuo

I am pretty sure that I don't have any delay() in my code.

MattS-UK


Code: [Select]
delay(1000);   // <--- I don't want to flood my network :D

Not sure why you use a delay if you want speed. My code runs ~16x faster with out a delay and has run for days.


I am not sure whether you read my post!  Perhaps you only glanced at it.

The code I posted was a demonstration of using UDP to transmit a DCB.  The delay is a bandwidth throttle, which I would think makes it plain the code is not intended to be a speed test.  Removing the throttle from the code,   a packet is transmitted every 1.6 ms; far faster than you would ever need to update a GUI.

Quote
My code runs ~16x faster with out a delay and has run for days.


You are comparing apples to oranges.  A fine career in marketing awaits you ;)

TCP has more failure modes then UDP, is an immutable fact.  Even so, I would not say that UDP is better than TCP.  An appropriate choice, very much depends on the usage case and application requirements.  By attempting to squeeze HTTP into every usage case and meet every requirement with TCP, you guarantee at least some  of your choices would be inappropriate.

zoomkat

Quote
I am not sure whether you read my post!  Perhaps you only glanced at it.


I read your ramble, which in the final end only appears to state what most already know concerning TCP and UDP.  ;)  Not sure why you seem prefer UDP over TCP for a GUI interface.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

MattS-UK

Quote from: zoomkat
I read your ramble,  


My apologies for being schooled before the Twitter generation.  
+ I was taught to read and write in paragraphs.  
+ I had to prove I could spot a straw man, before being let near a keyboard to write code.

Quote

Not sure why you seem prefer UDP over TCP for a GUI interface.


Which bit of,  "I would not say one is better than the other."  Did you not understand?

Go Up