Reading stream data from a TCP source

Hello people,

I’m new here and have been playing around with Arduino for a few months now. I am using the freetronics etherTen based on the Uno board and Wiznet W1500 chip, Here’s the link to the board.

I am connecting to a TCP server and exchanging messages in a Line Based ASCII protocol. The format of the messages is Qs436=0;0;0;0 with a CR and LF The messages can come in at any time. Maximum message length is 60 bytes but the average is about 12.

The first part of the message is a variable coming from the server, 436 in the example above but this could be Qh58, This is followed by a selection of fields separated by ‘;’, in the case Qs436=0;0;0;0 I need to put these 4 values into an array and do some calculations on later to drive hardware connected to the Arduino.

To parse the incoming message lines, I should inspect the first character (Q). A Q always means that there will be a category (h, i, or s) and an equals sign (=) followed by a value. The value is always an integer when the category is h or i, and a string otherwise.

I need some advice on how to implement this. My code so far does not include the array, I am unsure

  1. how to get the stream to match my if statements
  2. then put the data into an array in the right data types

Thanks in advance

Here is my code

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

byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,0,160 );
IPAddress subnet(255, 255, 255, 0); 
IPAddress server(192, 168, 0, 10); 

EthernetClient client;
  const int led =  3;      // the number of the LED pin  
  int t1psx;
  int t2psx;
  int t3psx;
  int t4psx;

void setup() {
  pinMode(led, OUTPUT);  
  Ethernet.begin(mac, ip);

  Serial.begin(9600);

  do { client.connect(server, 10748);
  } 
  while (!client.connected());

  delay(100);

  Serial.println("connecting...");

  if (client.connected()) {

    Serial.println("connected");
    client.println("name=Audrino THQ");
  } 
  else {
    Serial.println("connection failed");
 }
}

// the loop routine runs over and over again forever:
void loop(){

 if (client){
   while(client.connected()){
     if (client.available()){
      char c = client.read();  
          Serial.print(c);
           
        if (c == 'Qh58'){
          if (client.find ("=")){         
            int ATenabled = client.parseInt();

              if (ATenabled == 1){
                digitalWrite(led, HIGH);
                Serial.println("AT = 1");
                }
              if (ATenabled == 0){
                digitalWrite(led, LOW);
                Serial.println("AT = 0");
                }
          } 
        }
         if (c == 'Qs436'){

          if (client.find("=")){
            t1psx = client.parseInt();
            Serial.print("Qs436=");
            Serial.println(t1psx);
          }
        }
   }
 }

        delay(10); 
        }
}

You want to parse a protocol then you need to provide us the COMPLETE protocol.

List all the possible characters coming after Q and what each character will convey, in terms of number of values that follow (always 4 values or strings or depending on this char?), and their data types.

Also include even some cases that you currently consider unlikely, say maybe the server will send Qx blah blah at a one out of a million chance that you will "never encounter", but list it here as well.

Plus, get rid of ALL ethernet stuff. Start a new sketch and only read and process strings from Serial. Both Serial and Ethernet are Stream devices. It makes no difference to use either one in the code but a huge difference if you develop code and have to test on a server. Too many variables and unknowns even if you are sitting next to the server, so don't.

Develop the parser code and hand type a server response in Serial monitor (check "Both NL and CR" to the left of the baud rate selector in serial monitor) to test just the parser code. Throw at it all possible situations and see if it breaks. Servers can't do that, but you can and should.