TCP Client problem, Spark Core reconnects to cloud every time when it does a TCP request

I read that lot of people are having problem with TCP Client lib in Spark Core and with this same problem related too but I can’t find a clear solution for this.

I used Thinker Android App to communicate with my Spark Core and when it receives a command by cloud my Spark Core should send a message via TCP to a remote machine and after it receives the data, this machine send back the same data. I developed a TCP Server in C# that receives a message and returns the same data received to the source.

Spark Core is able to send the correct data to the remote machine but when it will get the data, it doesn’t receive connections anymore (from Thinker App), begins blinks green and it reconnect to the cloud. In the middle of this process, I’m not able to send commands to the board and after that the board become unstable and I don’t receive the data.

Here is my code:

int tinkerDigitalWrite(String command);

    TCPClient client;
    IPAddress ip = { 192, 168, 25, 13};
    
    volatile bool isToWrite = false;
    
    void setup()
    {    
        Spark.function("digitalwrite", tinkerDigitalWrite);
    
        // Make sure your Serial Terminal app is closed before powering your Core
        Serial.begin(9600);
    	
        //Now open your Serial Terminal, and hit any key to continue!
        while(!Serial.available()) SPARK_WLAN_Loop();
    
        client.connect(ip, 3001);
    }
    
    void loop()
    {
    
      if (isToWrite)
      {
        byte message[3];
        message[0] = 11;
        message[1] = 12;
        message[2] = 13;
    
        client.write(message, 3);
        
        Serial.print("Message received: ");
        while (client.available()) {
          char c = client.read();          
          Serial.print(c);
          Serial.print(" ");
        }
    
        Serial.println();
    
        isToWrite = false;
      }
    }
    
    int tinkerDigitalWrite(String command){
        bool value = 0;
        int pinNumber = command.charAt(1) - '0';
        if (pinNumber< 0 || pinNumber >7) return -1;
        if(command.substring(3,7) == "HIGH") value = 1;
        else if(command.substring(3,6) == "LOW") value = 0;
        else return -2;
        if(command.startsWith("D")){
    
            isToWrite = true;
    
            return 1;}
        else if(command.startsWith("A")){
            pinMode(pinNumber+10, OUTPUT);
            digitalWrite(pinNumber+10, value);
            return 1;}
        else return -3;}

I wrote a TCP Client in C# and it works fine with my server.

Someone can help me with this two-way connection ?

Thanks

@vdef you are using Serial.print© to print your return data which will have values of ascii 11, 12 and 13 which correspond to VT (vertical tab), FF (form feed) and CR (carriage return). I am not sure what print() does with these but it does not sound good!. What you may want to do is use Serial.print(c, DEC) or Serial.print(c,HEX) to view decimal or hexadecimal value of the data.

Despite not seeing any evidence or reason for it in your code, could it be that your while (client.available()) { ... } never leaves or prevents the cloud keeping?

Try to add SPARK_WLAN_Loop() inside the while() and put a visual Serial.println("Got out of while!") after it to confirm it’s actually working.

2 Likes

You also never check client.connected() to see if you are really connected.

I think it is not a good idea to depends on client.connect() just in setup. Your code is very fragile against any kind of error. A better approach is to do your work in loop(), calling connect() if you need to retry.

3 Likes

Sorry about my delay to answer it but I solved that situation reading one byte per interation of the main loop, Its not possible to read all data inside TCPClient into one loop interaction. That was my main problem.

About the considerations of how my code was, I know that it could be better but I just wrote it for tests.

Reading one byte per interation solved my problem.