TCPClient stopped working

I’ve had some mixed results while trying to figure out my Modbus interface.

My application essentially does this:

TCPClient ysi;
byte server[] = {192,168,0,21};

if (ysi.connect(IPAddress(192,168,0,21),1502)) {
Serial.println("Connected!!!");
ysi.write(readSensor,12);
delay(99);
int i = 1;
while (ysi.available()) {
  char c = ysi.read();
  Serial.println(i);
  i++;
  Serial.println(c,HEX);
}
if (!ysi.connected()) {
  Serial.println();
  Serial.println("disconnecting.");
  ysi.stop();
  //for(;;);
}
  }
  else {
    Serial.println("Connection failed.  Damn it!");
  }

I’m planning on putting most of the above (starting with the first “if”) in a loop and running it every minute to pull data and then push it to my cloud service.

The above worked many times and then seemed to stop. Powering down/up the Photon does not help. I am checking my Modbus simulator to see if it’s working OK, but thought I’d post a question to see if I’m doing anything wrong fundamentally (with regard to managing my TCP connection) with the above code.

Thanks for any feedback!

I’ve encountered errors when using TCPClient in conjunction with any of the Particle Cloud functions like functions and variables. Anything that starts with Particle.xxx(). Don’t combine the two in a single program. Without seeing the rest of your code I don’t know if you’re doing that.

@bheliker, I hate to differ but there are a large number of examples throughout the forum that contradict your assertion. I have several examples of TCP/UDP running alongside cloud functions without ANY interference.

@ctmorrison, your code doesn’t indicate what system mode it is running in and whether or not system threading is enabled.

[quote=“ctmorrison, post:1, topic:20716”]
The above worked many times and then seemed to stop
[/quote]When you ran this “many times” did the code repeat the ysi.connect() call? If so, each time you did, it opened a new socket and eventually ran out of available sockets! Giving a few more details on your testing conditions would help greatly. :wink:

So, by “many times”, I mean the program ran one time during which the TCPClient was called once and then the program ended. I then reset the program to run it again (or recompiled the program and re-flashed it with a slight modification) or powered the Photon down and back up (cold restart). It seems I simply can no longer make the connection to the target simulator.

Does it matter at all that the above code is in a function that’s called by setup()?

My plan is to have this call in a ~1 minute loop, reading the registers in an analyzer. I had thought of making 12 different calls to read the 12 sets of 8 registers in each loop as opposed to one call that would return 96 32 bit registers (nearly 400 bytes).

This test program is really simple–just trying to understand the requests and responses to/from the analyzer.

My assumption is that the ysi.stop() tears down the connection completely. I’m a bit concerned the connection is not being closed properly (due to some feedback from the Modbus simulator developer). However, this is just conjecture at this point–I’ve had insufficient time to analyze completely.

I hope the above clears things up.

Here’s the complete program:

byte readSensor [12] = {0x00,0x00,0x00,0x00,0x00,0x06,0x01,0x04,0x00,0x01,0x00,0x08};

TCPClient ysi;
//byte server[] = {192,168,0,21};

void setup() {
  Serial.begin(9600);
  while(!Serial.available()) Particle.process();

  readYSI();
}

void loop() {

}

void readYSI () {
  Serial.println("Connecting to ysi…");
  if (ysi.connect(IPAddress(192,168,0,21),1502)) {
    Serial.println("Connected!!!");
    ysi.write(readSensor,12);
    delay(99);
    int i = 1;
    while (ysi.available()) {
      char c = ysi.read();
      Serial.println(i);
      i++;
      Serial.println(c,HEX);
    }
    if (!ysi.connected()) {
      Serial.println();
      Serial.println("disconnecting.");
      ysi.stop();
      //for(;;);
    }
  }
  else {
    Serial.println("Connection failed.  Damn it!");
  }

}

From the Modbus simulator (Ananas) developer in response to my question if there are any limitations to the application:

No limitations (except two simultanious tcp connections) and nagle has no effect in normal case whatsoever. Could it be that tcp connections remains open at OS running Ananas and new connection attempts are rejected, due to missing RST -flag from micro? Reset port used by toggling ctrl+P. Deactivate and reactivate port to see if Micro can connect to it after port reset. If it succeeds, I would say that Micro is not closing the tcp connection(s) properly. That can happen in case of wire break or sudden power off at client end. Or you try to establish a new tcp connection for each mb-package, which is not right without closing the previous one first.

@ctmorrison, calling stop() will close the open socket. However, your code doesn’t call stop() after a successful transaction and leaves the socket open. On the next call to readYSI you would call ysi.connect() again, opening a new socket. You can either open the socket once and leave it open or every time you call readYSI, open the socket, transact and call stop() to close the socket. :wink:

@peekay123 – I had hacked this code from a working version and didn’t even notice what you pointed out. Thanks for showing me my oversight! Sorry for wasting your time with such a simple issue.

Onward!!!

@ctmorrison, this is what this community is all about! No time wasting here :smirk:

@peekay123 I stand corrected – it appears the bug has been fixed. I wrote a micro app specifically to track down that bug but I haven’t run it in probably 6 months. It runs successfully now without throwing an error, so yup: I can use both TCPClient and Particle.publish in the same code! Thanks for the correction.

@bheliker, gotta love it when things come together like that. The more I use the Photon, the more I love it!

Just to close this issue…it turns out that the above information was very helpful, but not relevant to the actual problem I was experiencing. For some unknown reason, the Windows system upon which I was running Ananas decided to activate its firewall. That’s what was preventing the connection.

Once I cleared that up, I am now able to query the Modbus simulator at will, receive the response and successfully decode it, including the big-Endian floating point numbers that are being returned. This last part is due to this amazing forum.

I’m on my way and feel very confident I’ll be able to assist my associate in pushing the Modbus device’s readings to the cloud. Woohoo!!!

Thanks for the assist!

2 Likes