Send TCP message problem

Hello
I have conected ESP8266 with TCP server in an industrial smart camera. I can read the packages incoming by client.read command and it works fine. When i tried sending commands it does not work. I tried:
client.write("command")
client.print("command")
I have special commands that are accepted by the camera for example.
SCENE$0D informs us which scene is used now.
I tried to send packages by PC tcp client and it works fine ...
Please help !

#include <SPI.h>
#include <UIPEthernet.h>
//#include "packet.h"
String serial_data;
char incomingByte = 0;
char s = 0;
int choice = 0;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server(10, 5, 5, 10); // numeric IP for Google (no DNS)
IPAddress ip(10, 5, 5, 106);
EthernetClient client;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // start the Ethernet connection:
  Ethernet.begin(mac, ip);
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");
  // if you get a connection, report back via serial:
  if (client.connect(server, 9876)) {
    Serial.println("connected");
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  Serial.println("Wcisnij a aby odczytywac pakiety");
  Serial.println("Wcisnij b aby wysylac pakiety");
}


void loop() {
  Ethernet.maintain();
  // Read serial input:
  if (Serial.available() > 0)
  {
    incomingByte = Serial.read();
  }


  switch (incomingByte) {

    case 'a':
      //Serial.print("Logi");
      if (client.available())   {

        char c = client.read();

        Serial.print(c);
        Serial.print("");
      }
      if (!client.connected()) {
        client.connect(server, 9876);
      }
      break;

    case 'b':
      //Serial.print("Wpisz komendę");
      if (client.available()) {
        char c = client.read();
        Serial.print(c);
      }

      while (Serial.available() > 0) {
        char inChar = Serial.read();
        if (client.connected()) {
          client.print("SCENE$0D");
          client.write("SCENE$0D");
          char c = client.read();
          Serial.print(c);
        }
      }
      if (!client.connected()) {
        client.connect(server, 9876);
      }
      break;
  }
}

Does the client.print() need to be terminated in some way, perhaps with a Carriage Return or Linefeed, so that the camera knows that the message is complete ?

Hey I have no idea, using PC software (Hercules) I just connect to the server and send a message.

After your client.write you try a client.read, but you have not checked with client.available that there is anything to read yet. I have no idea how fast the camera responds, but it is very likely that you are attempting to read before the camera has responded. The client.available should give you an indication, if it returns false you can output on the serial display "client not avaiable" for example.
For testing purposes you could also add a delay after the client.write to give the camera time to respond and transmit the data. I would try something like delay (1000) as a starting point. If that allows the data from the camera to be read, you can look at a proper solution knowing that the two are talking.

Okay I guess that it is working but the message i got back from the Camera is in some format that is not read well.

case 'b':
      //Serial.print("Wpisz komendę");
      //if (client.available()) {
      //    char c = client.read();
      //    Serial.print(c);
      //  }

      if (client.available())   {
        Serial.print("Klient available");
      }
      //    char inChar = Serial.read();

      client.print("SCENE$0D");
      client.write("SCENE$0D");
      Serial.print("SENT");
      delay(2000);
      char c = client.read();
      Serial.print(c);
      Serial.print("READ BACK");


      if (!client.connected()) {
        client.connect(server, 9876);
      }
      break;
  }

Look at the Serial, between SENT and READ BACK there is a "?" and It seems that it is the message that is read from the server but maybe it needs conversion or something.

Also it looks liek the data is sent in ASCII so i guess just a serial.print should work...

Great that you are getting something back, obviously it is only the first character as that is al that is read at present. To work out what that character is I would use the itoa function. We know the value has to be less than 256, so 5 chars is sufficient.

const int rsLen = 5; 
char retString[rsLen];
itoa (c, reString, rsLen);
Serial.print("Returned char val: ");
Serial.printLn (retString);

After that I would change your line:

 if (client.available())   {
Serial.print("Klient available");

to:

int camretLen = client.available();
if (camretLen) {
Serial.print("Klient available - chars:");
Serial.printLn (camretLen);

This should give an indication of how many characters the camera is returning and whether that is what you expect.

I changed the code:

 case 'b':
      //Serial.print("Wpisz komendę");
      //if (client.available()) {
      //    char c = client.read();
      //    Serial.print(c);
      //  }

      //      if (client.available() > 0)   {
      //        Serial.print("Klient available");
      //      }
      //    char inChar = Serial.read();
      int camretLen = client.available();
      if (camretLen) {
        Serial.print("Klient available - chars:");
        Serial.println (camretLen);


        client.read();
        delay(100);
        client.flush();
        client.print("SCENE$0D");
        client.write("SCENE$0D");
        Serial.print("SENT");
        delay(2000);
        const int rsLen = 5;
        char retString[rsLen];
        char c = client.read();
        itoa (c, retString, rsLen);
        Serial.print("Returned char val: ");
        Serial.println (retString);
        Serial.print("READ BACK");
        client.flush();
        if (!client.connected()) {
          client.connect(server, 9876);
        }
        break;
      }
  }
}

and now nothing happens after I press the "b". literally nothing :smiley:
Moreover I changed the baud rate of Arduino to 115200 because i checked that the ethernet board is running on 115200 so It should be the same. To be honest i was sure that it was the main problem :smiley: but it was not

That is concerning and suggests to me that camretLen is not being set, perhaps putting
serial.printLn (camretLen); before the if(camretLen){ might tell us what value it has been set to.

It returns 0. I have no idea why because i could read the messages before so why now it is not available ? :smiley:

Well that explains why nothing happens, but I can't see why at present.
If you change if (camretLen) back to if (client.available()) does it work again?

Got it, my stupid mistake -sorry.

The lines:
`int camretLen = client.available();
serial.printLn(camretLen);

Need to come after the line
Delay(2000);
otherwise the camera has not had a chance to send anything.
This also explains why you never see "Klient available" because there is no data waiting at that point so it will always return 0.

client.available tells how much data the client has available, not whether the actual client is available!

  case 'b':
      //Serial.print("Wpisz komendę");
      //if (client.available()) {
      //    char c = client.read();
      //    Serial.print(c);
      //  }

      //      if (client.available() > 0)   {
      //        Serial.print("Klient available");
      //      }
      //    char inChar = Serial.read();
      client.read();
     

      if (client.available()) {
        Serial.print("Klient available - chars:");
      


        client.read();
        delay(100);
//        client.flush();
        client.print("SCENE$0D");
        client.write("SCENE$0D");
        Serial.print("SENT");
        delay(2000);
        int camretLen = client.available();
        Serial.println(camretLen);
        const int rsLen = 5;
        char retString[rsLen];
        char c = client.read();
        itoa (c, retString, rsLen);
        Serial.print("Returned char val: ");
        Serial.println (retString);
        Serial.print("READ BACK");
//        client.flush();
        if (!client.connected()) {
          client.connect(server, 9876);
        }
        break;
      }
  }
}

Nothing happens when i press "b".
When i press" a" id gives me the logs as usual. :confused:

If you look at your code from your posting #5 you have missed a } out (or at least moved it. Try putting it back as below:

Okay fixed it, that's the reply:


What does i mean ? :smiley:

I think it means we still have a slight problem :thinking:
I can't see how we can get 4044120 from a single byte which can hold 255 at most. I suspect I've got the datatypes mixed. itoa takes an int (not a char) so that is likely the problem - we read some other data in memory. I think we need to change

itoa (c, retstring, rsLen)

to:

int tmp;
tmp = int (c);
itoa (tmp, retString, rsLen);

I also think there is an error in itoa in that it has put more than 5 chars into retString so has likely written over some other memory :grimacing:

Changed it and the results are the same... :confused:

Maybe it should be

tmp = (int) c;

We might also want to intialise retString to be null terminated immediately after it is declared.
retString[0] = '\0';

Same situation: 4044120
I changed rsLen to:
10 - result : -1
8 - result : 177777
3 - result : 10022220020
1 - result : nothing
Maybe it will help you in some way to help me :smiley:

I'll admit I am a bit of a loss with this :confused:
This is the reference to itoa:
itoa - C++ Reference (cplusplus.com)

Ah - as soon as I pasted that in I can see the problem, the third argument is not the buffer length it is the base.

So we should just be using:
itoa (tmp, retString);

If the compiler requires 3 arguments, then the third one should be 10 (for base10).

Also if you put in retString[0] = ‘\0’ change it to retString[5] = '\0'; just in case.

  case 'b':
      //Serial.print("Wpisz komendę");
      //if (client.available()) {
      //    char c = client.read();
      //    Serial.print(c);
      //  }

      //      if (client.available() > 0)   {
      //        Serial.print("Klient available");
      //      }
      //    char inChar = Serial.read();



      if (client.available()) {

        Serial.print("Klient available - chars:");
      }




      delay(100);
      //        client.flush();
      client.print("SCENE$0D");
      client.write("SCENE$0D");
      Serial.print("SENT");
      delay(2000);
      //        int camretLen = client.available();
      //        Serial.println(camretLen);
      const int rsLen = 5;
      char retString[rsLen];
      //        retString[5] = '\0';
      char c = client.read();
      int tmp;
      tmp = (int) c;
      itoa (tmp, retString, 10);



      Serial.print("Returned char val: ");
      Serial.println (retString);
      Serial.print("READ BACK");
      //        client.flush();
      if (!client.connected()) {
        client.connect(server, 9876);
      }
      break;

  }
}

Now it returns "-1"

Anyway i tried to find something here :smiley: https://assets.omron.eu/downloads/manual/en/z338_fq2-s_ch_smart_camera_for_communication_settings_users_manual_en.pdf
But it just says that it returns in ASCII