Commands sent to a TCP server only runs about 3 times

So I’m working on a project where I can turn a smart light on and off with the photon. I can connect to the server just fine. I can tell it to turn on just fine. I can tell it to turn off just fine. But if I try turning it on and off every 10 seconds (or even 60 seconds), it’ll turn on, off, on, but then won’t change again. Here is the code:

TCPClient client;
byte lightOn[] = "<all;light;pwr;on>";
byte lightOff[] = "<all;light;pwr;off>";

    void setup()
    {
        pinMode(D7, OUTPUT);
        client.connect(IP, port);
        if(client.connected())
            digitalWrite(D7, HIGH);
        client.write(lightOff, strlen((const char *)lightOff));
        delay(2000);
    }
    
    void loop()
    {
            Particle.process();
            client.write(lightOn, strlen((const char *)lightOn));
            delay(3000);
            Particle.process();
            client.write(lightOff, strlen((const char *)lightOff));
            delay(3000);
    }

@sammcc117, can you give a few more details? For example, lightOn and lightOff seem to be blank. I highly recommend running with SYSTEM_THREAD(ENABLED); at the top of the file, before setup(). You can then remove the Particle.process() calls since the user and system threads will now run separately.

I noticed that you do if(client.connected()) but you proceed with the client.write() even it the connection failed! You should also check at the start of loop() if you are still connected as well. Your server may be dropping the socket and the code doesn’t check! I suggest you add code to check if you are connected and turn off the D7 LED. At the same time, you could try to reconnect, looping (with a suitble delay) until the connection is re-established. :smiley:

Ahh! I forgot to re-add the command code! Light up is “all;light;pwr;on”, light off is “all;light;pwr;off”. As for the loop suggestion, I’ve tried that before and it didn’t work :broken_heart:

@sammcc117, did you add SYSTEM_THREAD(ENABLED);? You should add Serial.print() debug statements to trace where things are failing.

When I do that the photon won’t connect to the light’s server at all. I also checked to see if it was getting disconnected from the socket and it’s not

@sammcc117, did you place the ‘SYSTEM_THREAD(ENABLED);’ before setup()? With that in place, you will need to wait for the client connection since the user app will start before wifi comes online. You can add in setup():

waitUntil(WiFi.ready);  // wait until wifi is ready

or

waitFor(WiFi.ready, 15000);   // waif for wifi to be ready for a max of 15 seconds

Then you can do the client.connect(), etc. What version of system firmware do you have on the Photon? Did you add Serial.print() debug statements?

1 Like

@peekay123 I got it to work, but now I can’t seem to get client.read() to work properly…

@sammcc117, can you post your code?

@peekay123

TCPClient client;
byte IP[] = {192, 168, 11, 341};
int PORT = 31415;
String readHum = "<ALL;SNSRHUM;LEVEL;GET;CURR>";

void setup()
{
  Serial.begin(9600);
  Serial.println("beginning");
}

void loop()
{
  command(readEnvHum);
  delay(5000);
}

void command(String command)
{
  if(client.connect(IP, PORT))
  {
    client.write(command);
    Serial.println((String)command + ": executed");
    Serial.println((String)client.read());
  }
  else
    Serial.println((String)command + ": error");
  client.stop();
} 

I’m expecting a result like:
ALL;SNSRENVHUM;LEVEL;GET;CURR: executed
(ALL;SNSRENVHUM;LEVEL;GET;CURR;333)

But instead I’m getting:
<ALL;SNSRENVHUM;LEVEL;GET;CURR>: executed
-1

@sammcc117, you are calling command() with “readEnvHum” but you only define “readHum”. Also, client.read() reads a single character. You may want to first check that there is a return from the server with client.available() and then read while client.available() is true. Check out the documentation for TCPClient. :grinning:

Ahh yeah sorry, I have it defined, I was just trying to cut out some of the excessive code to make it easier for you to read. When I call client.available(), it returns 0, which makes no sense. I KNOW that the humidity sensor should return something. It works perfect in PuTTy, and returns in the “(ALL;SNSRHUM;LEVEL;GET;CURR;XXX)” format like it should

This is so frustrating, but thank you so much for helping

You can only expect that if your code was correct, but your code does this

String readHum = "<ALL;SNSRHUM;LEVEL;GET;CURR>";
...
void loop()
{
  command(readEnvHum);
  delay(5000);
}

and since we only can find readHum but no readEnvHum there is no reason to believe that your expectations would be satisfied by this code above.
If you want help with that, you’d need to provide actually working code, but this wouldn’t even build - that is frustrating.

And even if you sent the correct command, you shouldn’t expect your client.read() to be able to read the data instantaneous. The communication takes time which you are not allowing for in your code (as @peekay123 has already pointed out with his reference to client.available()).