Data stream over Ethernet another problem..

Hi,
I'm trying to have simple protocol to command Arduino over enc28j60 from pc to adjust servo position, read sensor, etc.

I use a lib from here now:

First please have a look in my code:

...
String strSrvCmdArr = ""; //initialized
...
void loop()
{
  analogWrite(5, 0);
  char* params;
  if (params = e.serviceRequest())
  {
    e.print("<H1>Hello there!</H1>");
   
    for(int i=1;params[i];i++)
    {
      strSrvCmdArr += params[i];
    }
    
    Serial.println(strSrvCmdArr);
    strSrvCmdArr = "";

    e.respond();
  }
}

Based on info of the web site I got the ENC28J60 lib from, "params = e.serviceRequest()" will load params either with incoming request including '?' char or params will be null.

Next, this is my guess that if I request like:
http://arduino-ip/?someCmd=smth
then param will have first character as '?', then there will be these characters: someCmd=something, and finally a '\n' (or '\0'?). But trying like:

for(int i=1;params[i]!='\n';i++)

returned the string correct, but continued with many strange characters (including squares that serial window didn't recognized as characters).

Next and the main problem:
when I changed to:

for(int i=1;params[i];i++)

I started to get this output:

someCmd=smth
someCmd=smthavicon.ico

where the avicon.ico is not mine! I ordered as: http://arduino-ip/?someCmd=smth, in my browser! I guess that is favicon.ico, but these questions:

  1. why I got 2 times the request?
  2. how favicon.ico jumped into string?
  3. what is the best practice? may be better to make request like:
    http://arduino-ip/?someCmd=smth&endOfCmd
    and just extract between ? and endOfCmd, to hit right service request parameters?
  4. how to protect one command to not to be sent for 2 times, this way? In browser I hit enter key only once, but my params got loaded 2 times, what to do?
  5. why this didn't work:
for(int i=1;params[i]!='\n';i++)

Please help so I get a clear mind to go on..

The string returned by e.serviceRequest() should be NULL terminated, not carriage return terminated. You can get the length of the string, if it is important (I don't think it is) using strlen().

Thanks, any hint on double times receiving of request, with second time mixed with favicon.ico?

Thanks, any hint on double times receiving of request, with second time mixed with favicon.ico?

I haven't seen any code of yours that properly prints the data received, so commenting on what you think you see based on incorrect code would be futile.

I suppose that if request is received only once, then params is loaded only once, and this:

Serial.println(strSrvCmdArr);

does the print 2 times, with second time concatenating it with favicon.ico file name. Do you know why this happens?

I don't think that I have ever, in 36 years of coding, ever printed just a value. I had one program that I was working on that printed 400 million lines of debug. There was no way in hell I would have ever figured out what that program was doing without printing SOMETHING in front of each and every value.

There is no way I would have asked someone to help me debug that program by showing them one or two or a dozen lines of code.

Change each and every one of your print statements to do two things. Print something (anything!) before the value, and, in the case of strings, something after the value.

Serial.print("params = [");
Serial.print(params);\
Serial.println("]");

Now, you or I, or anyone else, can look at the output and KNOW what was being printed, and, because is is a string, know EXACTLY how long the string is.

Then, post ALL of your code.

Paul thanks I respect all the 36 and will further print debug info!

Next, this is the complete sketch code:

#include "etherShield.h"
#include "ETHER_28J60.h"

static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24};   
static uint8_t ip[4] = {192,168,0,7};                    

static uint16_t port = 80;                                     
ETHER_28J60 e;


String strSrvCmdArr = "";

void setup()
{ 
  e.setup(mac, ip, port);
  Serial.begin(9600);

}



void loop()
{
  analogWrite(5, 0);
  char* params;
  if (params = e.serviceRequest())
  {
     e.print("<H1>Hello !</H1>");
    
    for(int i=1;params[i];i++)
    {
      strSrvCmdArr += params[i];
    }
    
    Serial.println(strSrvCmdArr);
    strSrvCmdArr = "";
   params = null; //new, 
    e.respond();
  }
}

now it is 3:30 morning here, I'll do as you said right after some sleeping..

I read documents on 'c string functions' that found on google and learned those you kindly pointed to, in previous post, but the problem now is that I'm not sure I'm getting the string at all, right, before starting parsing and tokenizing.

Bowsers typically send two requests for a page; one for favicon and one for the actual page.

If you install wireshark on you PC your can trace all the packets sent to your arduino and what the arduino sends back. Wireshark will decode the contents of the packets so you easily work out what is going on.

Thank for the link, really need that software,

Yes I just published debug info as Paul kindly suggested and I see that I received 2 request, but...

Now the question is:
What is the best practice here, so that to protect 1 request to be processed only one time, if user by mistake sends 1 req. 2 times?

What is the best practice here, so that to protect 1 request to be processed only one time, if user by mistake sends 1 req. 2 times?

It isn't clear what the Arduino is going to be doing in response to client requests. Typically, though, the server is able to do the same thing multiple times, with no ill affects.

Keep in mind that your Arduino should be able to process requests from multiple clients, and that it has no way of distinguishing one client from another, so it can't tell that "the same request" is from the same client.

Thanks Paul, I finally realized messaging desktop -> google cloud -> android -> arduino,

I can say mostly helped that "36 years coding experience" you mentioned to suggest heavy debugging! I everywhere used Log.d(string,string) on android and without that job couldn't get done!

Now android does the cmd analysis job and sends safe commands to arduino, via an ethernet socket with it.

Growing my arduino up to cloud and even over :smiley:

Thanks again!