ethercard library, help separating out url

Hi guys,

I’m in need of a bit of help especially since C/variants arnt really my 1st language. I’m using the ethercard library and enc28j60 module as a sever to show a form which is populated with some setting which seems to be working fine, the bit i am a bit stuck with is when I submit the form and get a URL returned similar to:

http://192.168.1.200/?s1h=7&s1m=0&s3h=21&s2m=56&z1=1&z2=1&z3=1

how would I go about setting individual variables with the returned values. so from the above URL i would want to get the equivalent of in the arduino code if that makes sense.

s1h =7;
s1m=0;
z1=1;
z2=2;

Here is the code I am using in the Arduino (with a few bits trimmed off as irrelevant to this problem i think):

#include <EtherCard.h> //for ethernet
#include <Time.h>  //for time functions
#include <Wire.h>  //for I2C comms with the RTC
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
#include <EEPROM.h>    //for EEPROM storage functions

//IP and Gateway address for ethernet connection
static byte myip[] = { 192,168,1,200 }; //IP address for the Arduino
static byte gwip[] = { 192,168,1,1 };  //Gateway IP address to connect to

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[900]; // tcp/ip send and receive buffer
BufferFiller bfill;






//Vars we will need for times, pins etc
int z1=4; //pins for sprinkler control solenoids
int z2=5;
int z3=6;

int z1time=0; //time for sprinkler running time in minutes
int z2time=0;
int z3time=0;

long z1seconds=0; //time for sprinkler running time in seconds (derives from z1time * 60)
long z2seconds=0;
long z3seconds=0;


void setup()  {
  
  //setup pin mode and turn off outputs
  
  pinMode(z1, OUTPUT);
  pinMode(z2, OUTPUT);
  pinMode(z3, OUTPUT);
  
  
  digitalWrite (z1, LOW);
  digitalWrite (z2, LOW);
  digitalWrite (z3, LOW);

  //load default values into EEPROM for debugging purposes, normally comment next line out
  DefaultValues();
  delay(1000);

EEPROMread();
  //start debugging and set Arduino time from the RTC
  Serial.begin(9600);
  while (!Serial) ; // wait until Arduino Serial Monitor opens
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet) 
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");   
     Serial.print("Trigger times loaded from EEPROM are: ");
     Serial.print(trigger1h);   
     Serial.print(":"); 
     Serial.print(trigger1m);
     Serial.print(" and ");
     Serial.print(trigger2h);
     Serial.print(":");
     Serial.print(trigger2m);
     Serial.println();

    //ethernet setup
    if (ether.begin(sizeof Ethernet::buffer, mymac, 8) == 0)
    Serial.println( "Failed to access Ethernet controller");
    
    //setup static IP address
    ether.staticSetup(myip, gwip);
  
}

void loop()
{
  if (timeStatus() == timeSet) {
    digitalClockDisplay();
  } else {
    Serial.println("The time has not been set.  Please run the Time");
    Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
    Serial.println();
    delay(4000);
  }
  delay(1000);

//ethernet code

  // check if anything has come in via ethernet
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if (pos) { // check if valid tcp data is received
    // data received from ethernet

       char* data = (char *) Ethernet::buffer + pos;


       // "on" command received     
       if (strncmp("GET /on",data,7) == 0) {
         digitalWrite(z1, HIGH);   // set the LED on
       #if DEBUG
         Serial.println("option1 received");
       #endif
       }

       // "off" command received     
       if (strncmp("GET /off",data,8) == 0) {
         digitalWrite(z1, LOW);   // set the LED off
       #if DEBUG
         Serial.println("option2 received");
       #endif
       }

       ether.httpServerReply(homePage()); // send web page data
   }
  

//end ethernet code

  
  
  CalcSeconds(); //load the vars with the running times in seconds
  
  if((((minute() == trigger1m) and (hour() == trigger1h)) or ((minute() == trigger2m) and (hour() == trigger2h))) and inCycle == false)
  {
  //calculate the EPOCH finishing times for each zone
   EPOCHz1 = (z1time * 60) + now();
   EPOCHz2 = ((z1time * 60) + (z2time * 60)) + now();
   EPOCHz3 = ((z1time * 60) + (z2time * 60) + (z3time * 60)) + now();
   
  inCycle = true; //set this so we cant trigger another cycle until this one has completed
  }
  
if (inCycle == true  )
  {
   
    if (now() < EPOCHz1)
    {
    digitalWrite (z1, HIGH);
    }else{
    digitalWrite (z1, LOW);
    } 
    
    if ((now() < EPOCHz2) and (now() >= EPOCHz1))
    {
     digitalWrite (z2, HIGH);
    }else{
     digitalWrite (z2, LOW); 
    }
    
    if ((now() < EPOCHz3) and (now() >= EPOCHz2))
    {
    digitalWrite (z3, HIGH);
    }else{
    digitalWrite (z3, LOW); 
    }
    
    if (now() > EPOCHz3)
    {
     inCycle = false; 
    }
  }
}



static word homePage() {
int a=trigger1h;
int b=trigger1m;
int c=trigger2h;
int e=trigger2m;
int f=z1time;
int g=z2time;
int h=z3time;
  
bfill = ether.tcpOffset();
bfill.emit_p(PSTR(
"<html>"
"<head><title>"
"Tom's Irrigation Controller"
"</title></head>"
"<body>"
"<h1>Tom's Irrigation Controller</h1>"
"<form method='GET'>"
"<table width='400px' cellpadding='5' cellspacing='5' border='0'>"
"<tr><td colspan='4'>Times</td></tr>"
"<tr><td colspan='2'>Time 1</td><td colspan='2'>Time 2</td></tr>"
"<tr><td><input type='text' name='s1h' value='$D'></td><td><input type='text' name='s1m' value='$D'></td><td><input type='text' name='s3h' value='$D' ></td><td><input type='text' name='s2m' value='$D'></td></tr>"
"<tr><td colspan='4'>Watering Duration</td></tr>"
"<tr><td>Zone 1</td><td>Zone 2</td><td>Zone 3</td><td></td></tr>"
"<tr><td><input type='text' name='z1' value='$D'></td><td><input type='text' name='z2' value='$D'></td><td><input type='text' name='z3' value='$D' ></td><td></td></tr>"
"</table>"
"<input type='submit' value='Submit'>"
"</form>"
"</body>"//
"</html>"),
a,b,c,e,f,g,h);
return bfill.position();
}

I’ve edited a few bits out that is stuff for timing /RTC etc that wasnt really relevant to the problem I’m having. As you can see I’ve used some example code I found to get the ethernet side working but just not sure how to modify it to achieve what I’m after.

Thanks

Tom

I forgot to mention, that the returned URL all the returned values are integers with values between 0 and 99 incase that would be relevant as I'd expect the solution to this would somehow involve splitting the string and stripping characters.

Thanks

Tom

Use strtok?

Or a state machine:

http://www.gammon.com.au/statemachine

Just edited this post, thanks for your earlier advice Nick regarding Strtok, picked through a few C examples and think if somewhat got my head around it. Started a new sketch just to test how this would work rather than messing around with my other code that works.

Now I’m getting the values from the URL separated out and putting them into an array, however still having a few little issues, the last array element is getting an incorrect value (223 instead of 1) and I cant seem to work out why.

Here is my test code (little messy but will clean it up once I get it working how i want):

int returnArray[7];



void setup() {
  
Serial.begin(9600);
Serial.println("Setup Finished");

}

void loop() {
  // put your main code here, to run repeatedly: 

char* str = "http://192.168.1.200/?s1h=7&s1m=0&s3h=21&s2m=56&z1=1&z2=1&z3=1";
char* pch;
char* splitstring;
int num;  
  Serial.print("splitting string ");
  Serial.print(str);
  Serial.print(" into tokens");
  Serial.println();
  delay(3000);
 
int i=1;
  
  //split the string up
  pch = strtok (str,"?&=");
  while (pch != NULL)
  {
    splitstring = ("%s\n",pch);
    
    Serial.println(splitstring);
   
   

    num = atoi( splitstring );
 
    if ((num == 0) && (splitstring[0] != '0')){
      //do nothing, value is not numeric or contains non numeric chars
    }else{
     //contains numeric chars only
  
       returnArray[i] = num;
      i++;
    
    }
    pch = strtok (NULL, "?&=");
  }
 
 Serial.println("returnArray contains:");
int x=1;
 for (int x = 1; x < 8; x++){
   Serial.print("Array element ");
   Serial.print(x);
   Serial.print(" contains ");
   Serial.println(returnArray[x]);
 }
 
}

Serial monitor gives me:

splitting string http://192.168.1.200/?s1h=7&s1m=0&s3h=21&s2m=56&z1=1&z2=1&z3=1 into tokens
http://192.168.1.200/
s1h
7
s1m
0
s3h
21
s2m
56
z1
1
z2
1
z3
1
returnArray contains:
Array element 1 contains 7
Array element 2 contains 0
Array element 3 contains 21
Array element 4 contains 56
Array element 5 contains 1
Array element 6 contains 1
Array element 7 contains 223

so looks like I’m heading the right way, only thing now is I dont understand why the last array element is getting a value of 223 instead of the expected value of 1. can someone point me in the right direction please

Thanks

Tom

int returnArray[7];
...

 for (int x = 1; x < 8; x++){
   Serial.print("Array element ");
   Serial.print(x);
   Serial.print(" contains ");
   Serial.println(returnArray[x]);
 }

http://www.gammon.com.au/forum/?id=12153#trap11

Thanks Nick, will try correcting the mistake tomorrow and see if that solves it all :)