yasheena / telnetspy

Telnet Server For ESP8266: Cloning the serial port via Telnet. "Debugging over the air"

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

do I have to keep calling handle()

supersjimmie opened this issue · comments

I am looking for a telnet logging method, that basically only send logging to the telnet client.
The code in which I want to implement it contains a very long running loop(), which will make the SerialAndTelnet.handle(); being called only once in a long time.
Is that handle() needed when I only want to SEND data TO the telnet-client and not receive data from the client? (for me it only needs to send at several points in the long loop)
And also, will it be possible for a telnet-client to connect when the loop is already running or is the handle() needed for a client to connect?

The handle() is needed also for sending data to the client and for connecting/disconnecting. Because the module has a buffer and stores the data to send even if there is still no connection, it is not so time critical to connect the client.
Because every call of handle() sends out 1 block only, the data already stored in buffer may need a longer time to be send. The default block size is 512 bytes, but you can increase this value with the method setMaxBlockSize.
If the buffer is filled faster than the data will be send out via the handle() function, extra blocks will be send during the write calls itself so that the buffer will not overflow. This then needs more time for the write calls. But if there is no client connection the oldest data will be lost, if the buffer is full. The default size of the buffer is 3000 bytes. Use the method setBufferSize to increase the buffer, if neccessary (if the data is too much before the client connects).

Thank you!
So one way to do this might be to call handle() immediately after each SERIAL.print()/println() and periodically (e.g. with the ticker library every 5-10 sec?) to allow a client to connect/disconnect? Would that work?

I think this would work. You need a connection time out for the client which is long enough for the periodic call of handle().

It does seem to work.
I added a ticker that calls a small function with SerialAndTelnet.handle() every 5 seconds.
I can connect over telnet.
Then the loop sends something to SERIAL.println every 30 seconds and it appears in the telnet session.

Since the ticker calls the SerialAndTelnet.handle() every 5s, there is a delay of a few sec until it appears in the telnet session. I thought that I would be able to reduce that delay by calling the handle() immediately after each SERIAL.println, but strangely there is still a delay (as if the extra call after the SERIAL.println is ignored or does not work?).

void setup() {
... (basic init of wifi and normal serial)

  SerialAndTelnet.setWelcomeMsg("Welcome to the TelnetSpy\n\n");
  SerialAndTelnet.setCallbackOnConnect(telnetConnected);
  SerialAndTelnet.setCallbackOnDisconnect(telnetDisconnected);
  SERIAL.setDebugOutput(false);
  telnetTicker.attach(5, handleTelnet);
  Serial.println(WiFi.localIP());
}

void loop() {
  SERIAL.println("Test1");  handleTelnet();
  delay(30000);
  SERIAL.println("Test2");  handleTelnet();
  delay(30000);
  SERIAL.println("Test3");  handleTelnet();
  delay(30000);
  SERIAL.println("Test4");  handleTelnet();
  delay(30000);
  SERIAL.println("Test5");  handleTelnet();
  delay(30000);
  SERIAL.println("Test6");  handleTelnet();
  delay(30000);
}


void telnetConnected() {
  Serial.println("Telnet connection established.");
}

void telnetDisconnected() {
  Serial.println("Telnet connection closed.");
}

void handleTelnet() {
  SerialAndTelnet.handle();
}

With this code, the lines appear on serial immediately but almost 5s later in the telnet.

having really long loops() is bad practice as it will cause WDTs (watch-dog timeouts). I suggest keeping the telnet handle() close to <100ms to avoid lag and find smarter ways to handle the logic within the main loop, either via ticker() or interrupts.

Sorry @proddy, but having a long loop won't cause WDTs if you play the game by the rules.
Look for example at https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code where the entire program actually is made up out of one loopcycle without any problem.

Since this is irrelevant to the question, can we continue searching on what is needed to make it just respond "smoothly" (or learn why it won't be faster, if that is the case)?

@supersjimmie, you are right with the delay. I forgot my function to avoid many small packets instead of using a bigger one: data is collected till a minimum ammount is reached or a maximum time elapsed. So your handle call call direct after the print is ignored, because both conditions aren't true at that moment. Please use the method setMinBlockSize(1) to force sending data independent of the data size (the default value is 64).