Read more then 1 byte script in TCP

Hello

I have the following code

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

// Enter a MAC address, IP address and Portnumber for your Server below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress serverIP(192,168,1,45);
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(5190); //server port

// Initialize the Ethernet server library
// with the IP address and port you want to use
int led = 8;


void setup()
{
  pinMode(led, OUTPUT);

  // start the serial for debugging
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, serverIP, gateway, subnet);
  server.begin();
  Serial.println("Server started");//log
}

void loop()
{
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char ch = client.read();
// examine ch
        switch(ch)
        {
        case 'on':  // for example
         {
    digitalWrite(led, HIGH);
    client.println("The power is ON");
    break;
    delay(10);
    }
        case 'of':  // for example
    {
     digitalWrite(led, LOW);
     client.println("The power is OFF");
     break;
     delay(10);
    }    
        }             
      }
    }
  }
}

Right now it only reads 1 byte in when i send a tcp packet to it. but i would like it to read all the bytes and then see if it equal to the string it should do a command on
An example could be:
1234554321 = led turns on
5432112345 = led turns off
any other string = does nothing

i have been trying with the equal() but i can’t get it to work. so can anyone help me with this?
I would like to hold it in TCP raw.

Thanks in advance

You must store your characters in an array, then do a compare. Try something like this. It reads the first packet and compares the received string to “on” and “off”.

void loop()
{
  EthernetClient client = server.available();
  if (client) {
    char inBuffer[32];
    int inCount = 0;

    while (client.connected()) {
      while (client.available()) {
        char ch = client.read();
        if(inCount < 31) {
          inBuffer[inCount] = ch;
          inCount++;
          inBuffer[inCount] = 0;
        }
      }  
      if(inCount > 0) {
        // send response to client here if you wish
        client.println("Got it");

        client.stop();
        Serial.println(inBuffer);

        if(strcmp(inBuffer,"on") Serial.println("ON");
        else if(strcmp(inBuffer,"off") Serial.println("OFF");
    }
  }
}

This considers that the request comes in one packet and contains only “on” or “off”. I didn’t check this for errors. I will leave that part to you.

SurferTim:
You must store your characters in an array, then do a compare. Try something like this. It reads the first packet and compares the received string to “on” and “off”.

void loop()

{
  EthernetClient client = server.available();
  if (client) {
    char inBuffer[32];
    int inCount = 0;

while (client.connected()) {
      while (client.available()) {
        char ch = client.read();
        if(inCount < 31) {
          inBuffer[inCount] = ch;
          inCount++;
          inBuffer[inCount] = 0;
        }
      } 
      if(inCount > 0) {
        // send response to client here if you wish
        client.println(“Got it”);

client.stop();
        Serial.println(inBuffer);

if(strcmp(inBuffer,“on”) Serial.println(“ON”);
        else if(strcmp(inBuffer,“off”) Serial.println(“OFF”);
    }
  }
}



This considers that the request comes in one packet and contains only "on" or "off". I didn't check this for errors. I will leave that part to you.

Thank you for the answer… i tested the code and it doesnt work as intended. It still serial print “ON” no matter what i send to it as long as it ends with “n”…

My bad! It should have been like this.

        if(strcmp(inBuffer,"on") == 0) Serial.println("ON");
        else if(strcmp(inBuffer,"off") == 0) Serial.println("OFF");

SurferTim: My bad! It should have been like this.

        if(strcmp(inBuffer,"on") == 0) Serial.println("ON");
        else if(strcmp(inBuffer,"off") == 0) Serial.println("OFF");

I tested it. now it doesnt do the last Serial.println("ON") or Serial.println("OFF");

OK, try this. Maybe you are sending more characters than you think.

        if(strcmp(inBuffer,"on") == 0) Serial.println("ON");
        else if(strcmp(inBuffer,"off") == 0) Serial.println("OFF");
        else Serial.println("undefined");

        Serial.print("Length: ");
        Serial.println(strlen(inBuffer));

If you send "on", Length: 2 If you send "off", Length: 3 If not, you have additional characters being sent, like maybe a carriage return/line feed?

SurferTim: OK, try this. Maybe you are sending more characters than you think.

        if(strcmp(inBuffer,"on") == 0) Serial.println("ON");
        else if(strcmp(inBuffer,"off") == 0) Serial.println("OFF");
        else Serial.println("undefined");

        Serial.print("Length: ");         Serial.println(strlen(inBuffer));



If you send "on", Length: 2
If you send "off", Length: 3
If not, you have additional characters being sent, like maybe a carriage return/line feed?

you're right.. sorry i didnt think of that. when i send from my computer:

on

undefined
Length: 4
off

undefined
Length: 5

when i send from my mobile phone:

on

undefined
Length: 3
off

undefined
Length: 4

so this mean that i can never predict what its gonna send.. :(.. But can i then make a login or something like that? because i want it to be a bit secure so that you have to know something more then just my ip and which port there is open to control my arduino

so this mean that i can never predict what its gonna send..

You could, probably. Most likely, one is sending the text you type plus a carriage return AND line feed, while the other is sending the text that you type plus carriage return OR line feed.

If you make sure to NOT add the carriage return and to NOT add the line feed to the array then you will (most likely) always get the correct text in the array.

It appears one sends \r\n, and the other sends only \n. PaulS posted that while I was typing the new code.

Don’t save \r or \n in the buffer. Try something like this:

        if(inCount < 31 && ch != '\r' && ch != '\n') {
          inBuffer[inCount] = ch;
          inCount++;
          inBuffer[inCount] = 0;
        }

I have not tested that for correct logic, but it should be ok.

edit: I removed the extra closing parentheses.

Instead of doing a string comparison for an exact match, you could test whether the incoming string starts with "ON" or "OFF" - any trailing characters being ignored. The function strstr()can be used to do that.

when I use the following code

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

// Enter a MAC address, IP address and Portnumber for your Server below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress serverIP(192,168,1,45);
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(5190); //server port

// Initialize the Ethernet server library
// with the IP address and port you want to use
int led = 8;


void setup()
{
  pinMode(led, OUTPUT);

  // start the serial for debugging
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, serverIP, gateway, subnet);
  server.begin();
  Serial.println("Server started");//log
}

void loop()
{
  EthernetClient client = server.available();
  if (client) {
    char inBuffer[32];
    int inCount = 0;

    while (client.connected()) {
      while (client.available()) {
        char ch = client.read();
      if(inCount < 31) && ch != '\r' && ch != '\n') {
          inBuffer[inCount] = ch;
          inCount++;
          inBuffer[inCount] = 0;
        }
      }  
      if(inCount > 0) {
        // send response to client here if you wish
        client.println("Got it");

        client.stop();
        Serial.println(inBuffer);

 if(strcmp(inBuffer,"on") == 0) Serial.println("ON");
        else if(strcmp(inBuffer,"off") == 0) Serial.println("OFF");
        else Serial.println("undefined");

        Serial.print("Length: ");
        Serial.println(strlen(inBuffer));
    }
  }
}
}

then i get this warning:

sketch_apr06a.ino: In function 'void loop()':
sketch_apr06a:39: error: ISO C++ forbids comparison between pointer and integer
sketch_apr06a:39: error: expected `;' before ')' token
sketch_apr06a:39: error: label 'ch' used but not defined

is this possible to fix?

PeterH:
Instead of doing a string comparison for an exact match, you could test whether the incoming string starts with “ON” or “OFF” - any trailing characters being ignored. The function strstr()can be used to do that.

but i would like an exact match

I thought I had removed that extra parenthesis before you read it. This is the new code. Note no parenthesis after “inCount < 31”

       if(inCount < 31 && ch != '\r' && ch != '\n') {
          inBuffer[inCount] = ch;
          inCount++;
          inBuffer[inCount] = 0;
        }

SurferTim:
I thought I had removed that extra parenthesis before you read it. This is the new code. Note no parenthesis after “inCount < 31”

       if(inCount < 31 && ch != '\r' && ch != '\n') {

inBuffer[inCount] = ch;
          inCount++;
          inBuffer[inCount] = 0;
        }

ohh sorry my mistake… think im to tired to work with this anymore…

But thanks you very much for all the help :slight_smile:

the finale code:

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

// Enter a MAC address, IP address and Portnumber for your Server below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress serverIP(192,168,1,45);
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(5190); //server port

// Initialize the Ethernet server library
// with the IP address and port you want to use
int led = 8;


void setup()
{
  pinMode(led, OUTPUT);

  // start the serial for debugging
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, serverIP, gateway, subnet);
  server.begin();
  Serial.println("Server started");//log
}

void loop()
{
  EthernetClient client = server.available();
  if (client) {
    char inBuffer[32];
    int inCount = 0;

    while (client.connected()) {
      while (client.available()) {
        char ch = client.read();
       if(inCount < 31 && ch != '\r' && ch != '\n') {
          inBuffer[inCount] = ch;
          inCount++;
          inBuffer[inCount] = 0;
        }
        
      }  
      if(inCount > 0) {
        // send response to client here if you wish
        client.println("Got it");

        client.stop();
        Serial.println(inBuffer);

 if(strcmp(inBuffer,"on") == 0) digitalWrite(led, HIGH);
        else if(strcmp(inBuffer,"off") == 0) digitalWrite(led, LOW);
        else Serial.println("undefined");

        Serial.print("Length: ");
        Serial.println(strlen(inBuffer));
    }
  }
}
}