Data Parsing - WiShield - Wireless Temp. & Switch

Hi all!

So here is my project: I am working on a multi-sensor device which is also intended to control solid state relays.
As it stands, I am using TMP102 temperature sensors which report over the I2C protocol to an Arduino Due. w/ WiShield 1.0
The temperature data for two sensors is being sent via POST method to a PHP script on a colocated server.
The remote PHP script stores the incoming data in an SQL database which I then analyze using JpGraph & PHP.
This part is working just fine - I have been collecting temperature data for ~6mo now.

What I am struggling with is the following:

Getting control data from the remote server to control a solid state relay.

What I would like to do is use my SQL database to control the switch states (Boolean function, really).
I have written a PHP script that polls my database and returns the only following:

, (eg. |1,0)

I am using pipe ( | ) as a sort of index to parse the incoming GET request so that my code knows where to start looking for the actual control data.
I would like to make this scalable so that I could have say, 4 switches, all having their states returned with a single query of the SQL/PHP server.
So I need to somehow include the ability to intelligently parse multiple switch data.

Ie: sw1,1 .. sw2,0 .. sw3,1 .. etc

As it stands, if I make a text file (switch.php) with |1,0 in it, the switch get set to off, similarly if the text file contains only |1,1 the switch is turned on.
When I test my swtich.php using the SQL data, my web browser reports only: |1,0 or |1,1 but the Arduino does not control the switch accordingly.

I was hoping that an experienced coder could have a look at my source (below) and make suggestions / help me along my way.

void printData2(char* data, int len) {   // how the headers returned from getData routine are handled
  if (len > 0){
    memset(dataIn, ' ', sizeof(dataIn)); // clear dataIn and initialize cleanly for length of data packet
    for (int cntChar=0; cntChar < len; cntChar++) {
      char chrIn = data[cntChar];    // gather data from data variable 1 char at a time
      if (chrIn == '|') {                    // more advanced: if ((chrIn == '|') || (indexFound != 1))
        dataIn[ptr] = chrIn;             // set the first dataIn[0] to the current chrIn, post-increment ptr
        ptr++;
        indexFound = 1;
      } // end of if (chrIn == '|')
      if (indexFound == 1) {
        sscanf(dataIn, "%[^,], %d", sw1); // ignore the switch name for now, just get the state (and hope it works)
        Serial.println(onoff);
      } // end of (indexFound == 1)
    } // end of for (int cntChar=0; cntChar < len; cntChar++)
  } // end of (len > 0)
//  uip_close();  // disconnect from server - this causes data packet loss for some reason, ie. does not finish GET request
}

Here is the source code of the PHP script that the Arduino is told to GET data from:

    <?php
    include ("db.php");

    $sw = $_GET['sw'];

    $today = date("Y-m-d");

    if ($dbtable == "") $dbtable = "switches";

    mysql_connect($host,$login,$passwd);
    @mysql_select_db($dbname) or die( "Unable to connect to database");

    $query = "      SELECT *
                    FROM switches
            ";

    $result = mysql_query($query);

    $cnt = 0;
    $cnt2 = 0;

    while($row = mysql_fetch_row($result))
    {
            $switchIn[$cnt] = $row[0];
            $stateIn[$cnt] = $row[1];
            $dateIn[$cnt] = $row[2];
            $cnt++;
    }

    mysql_free_result($result);

    while($cnt2 < $cnt)
    {
            $dateInConv[$cnt2] = date("Y-m-d H:i:s",$dateIn[$cnt2]);
            $cnt2++;
    }

    $cnt3=0;
    while($cnt3 < $cnt)
    {
            echo "|";
            echo $switchIn[$cnt3];
            echo ",";
            echo $stateIn[$cnt3];
            $cnt3++;
    } // example, outputs:   |1,1

    ?>

If you fetch switch.php with a browser what does it display?

The code of printData2 is quite unclear for me what it does, e.g. the var ptr is never initialized?
When the separator is found you store it into dataIn[ptr]. Why? I understood you only need the digits.

Adding an end-token to the handshake makes parsing easier. e.g. <1,0> as you know when you have enough data for a new 'command'

Fetching switch.php will give |1,0 (for example)

The purpose of printData2 is to handle data that comes back from the WiShield.

ptr is initialized globally

Here is a link to the entire code for more background: http://asynclabs.com/forums/viewtopic.php?f=19&t=539

I suppose making the data string a little more like XML might be a good way to ensure the correct command is passed.

Still looking for a hand here :slight_smile:

Below is some parsing test code I've used that might be of interest if you are sending commands in a GET request. This is for the 0018 IDE. Should be fairly easy to modify for the current IDE.

//zoomkat 5-24-10

#include <WString.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
Server server(84); //server port

String readString = String(100); //string for fetching data from address

///////////////////////
 String teststring = String(100);
 String finalstring = String(100);
 String flag = String(2);
 int ind1 = 0;
 int ind2 = 0;
 int pos = 0;
 //////////////////////

void setup(){

//start Ethernet
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();

//enable serial data print 
Serial.begin(9600); }

void loop(){
// Create a client connection
Client 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.append(c); 
} 

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

///////////////
//Serial.println(readString);
//readString looks like "GET /?-0p1555-1p500t1000 HTTP/1.1"

  if(readString.contains("-")) { //test for servo control sring
  readString.replace('-', '#');
  pos = readString.length(); //capture string length
  //find start of servo command string (#)
  ind1 = readString.indexOf('#');
  //capture front part of command string
  teststring = readString.substring(ind1, pos);
  //locate the end of the command string
  ind2 = teststring.indexOf(' ');
  //capturing the servo command string from readString
  finalstring = readString.substring(ind1, ind2+ind1);
  //print "finalstring" to com port;
  Serial.println(finalstring); //print string with CR
    }
  ////////////////////////
  //GET /?Slidervalue0=1800&Submit=Sub+0 HTTP/1.1
  if(readString.contains("Slidervalue")) {
  ind1 = readString.indexOf('u');
  ind2 = readString.indexOf('&');
  finalstring = readString.substring(ind1+1, ind2);
  finalstring.replace('e', '#');
  finalstring.replace('=', 'p');
  Serial.println(finalstring);
  }
  ///////////////////
  
  //now output HTML data header
  client.println("HTTP/1.1 204 Zoomkat");
  client.println();
  client.println();
  delay(1);
  //stopping client
client.stop();

/////////////////////
//clearing string for next read
readString="";
teststring="";
finalstring="";
  
}}}}}