ESP8266 WifiTelnetToSerial - convert received data from client

Good day

I have an ESP8266 running the WiFiTelnetToSerial original exampleWiFiTelnetToserial example sketch, which was uploaded using the Arduino IDE.

WiFiTelnetToSerial original example.

I am able to send it the following using PuTTY : 1234,12,123,999 and the data is received correctly in the serial console on the server.

What must be changed in the following code (hopefully it's the correct place in the example's code) in order to split the received data on the commas into char array variables?

//get data from the telnet client and push it to the UART
    while(serverClients[i].available()) Serial.write(serverClients[i].read());

As far as I can see, once the client is connected successfully (based on MAX CLIENT = the current client number stored in serverClients*) , the data from the client is read like this :*
serverClients[i].read() and the passed onto Serial.write. Serial.write(serverClients[i].read());
What is the correct format/method to place the data from here,
* *Serial.write(serverClients[i].read());* *
Into this for example ? :
* *char A char B char C char D* *
so that each Char would contain each value:
char A would hold value 1234
char B would hold value 12
char C would hold value 123
char D would hold value 999
other examples show using readStringUntil() :
So I tried this but then the server refuses any connection to it:
* *//check clients for data   for (i = 0; i < MAX_SRV_CLIENTS; i++) {     if (serverClients[i] && serverClients[i].connected()) {       if (serverClients[i].available()) {         //get data from the telnet client and push it to the UART         while (serverClients[i].available()) //Serial.write(serverClients[i].read());         String line = client.readStringUntil('\r');         Serial.println();         Serial.print(line);         Serial.println();         char myarray[21];         line.toCharArray(myarray, 21);         Serial.print(myarray[0]);         Serial.print(' ');         Serial.print(myarray[1]);         Serial.print(' ');* *
Attaching the WiFiTelnetToSerial example here for extra reference:
```
/
  WiFiTelnetToSerial - Example Transparent UART to Telnet Server for esp8266

Copyright (c) 2015 Hristo Gochkov. All rights reserved.
  This file is part of the ESP8266WiFi library for Arduino environment.

This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include <ESP8266WiFi.h>

//how many clients should be able to telnet to this ESP8266
#define MAX_SRV_CLIENTS 1
const char* ssid = "";
const char
password = "
*";

WiFiServer server(23);
WiFiClient serverClients[MAX_SRV_CLIENTS];

void setup() {
  Serial1.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial1.print("\nConnecting to "); Serial1.println(ssid);
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
  if(i == 21){
    Serial1.print("Could not connect to"); Serial1.println(ssid);
    while(1) delay(500);
  }
  //start UART and the server
  Serial.begin(115200);
  server.begin();
  server.setNoDelay(true);
 
  Serial1.print("Ready! Use 'telnet ");
  Serial1.print(WiFi.localIP());
  Serial1.println(" 23' to connect");
}

void loop() {
  uint8_t i;
  //check if there are any new clients
  if (server.hasClient()){
    for(i = 0; i < MAX_SRV_CLIENTS; i++){
      //find free/disconnected spot
      if (!serverClients[i] || !serverClients[i].connected()){
        if(serverClients[i]) serverClients[i].stop();
        serverClients[i] = server.available();
        Serial1.print("New client: "); Serial1.print(i);
        break;
      }
    }
    //no free/disconnected spot so reject
    if ( i == MAX_SRV_CLIENTS) {
      WiFiClient serverClient = server.available();
      serverClient.stop();
        Serial1.println("Connection rejected ");
    }
  }
  //check clients for data
  for(i = 0; i < MAX_SRV_CLIENTS; i++){
    if (serverClients[i] && serverClients[i].connected()){
      if(serverClients[i].available()){
        //get data from the telnet client and push it to the UART
        while(serverClients[i].available()) Serial.write(serverClients[i].read());
      }
    }
  }
  //check UART for data
  if(Serial.available()){
    size_t len = Serial.available();
    uint8_t sbuf[len];
    Serial.readBytes(sbuf, len);
    //push UART data to all connected telnet clients
    for(i = 0; i < MAX_SRV_CLIENTS; i++){
      if (serverClients[i] && serverClients[i].connected()){
        serverClients[i].write(sbuf, len);
        delay(1);
      }
    }
  }*
```

This pseudo code might help you get started. It shows the first stage of parsing a token (say 1234) out of the group. There may also, of course, be better methods of achieving the same thing.

// Define a buffer long enough to hold the largest token plus one, that is the values between the commas, for example:
char buffer [9] = {0} ;  // global or static. holds up to 8 chars plus a cstring terminator

// Define a pointer into that buffer
byte pointer = 0 ;  // global or static

get a character: charRead = serverClients[i].read() 
if charRead is a comma or a line end character
   buffer[pointer] = 0 ;  // cstring terminator
   process the buffer, say print it as a test,
     or use say strcpy to copy it somewhere
   reset pointer to zero
   clean buffer
else
   buffer[pointer] = charRead ;
   if pointer < 8 then increment pointer
   else optionally handle pointer overflow
   endif
endif

readStringUntil(), which you tried, blocks the sketch (until a timeout) while waiting for the specified character, so must be used with care.

Hi there

@6v6gt

Thank you so much for the pseudo code .. it did get me searching further .. I have been battling with this for two weeks or more (lots of very late nights ;-().
I have cobbled together some code found on the forums for reading serial input (I believe originating from PaulS ? ..Thank you PaulS).

This code works first time and then totally crashed the ESP :frowning:

Hopefully someone can pinpoint where I've gone wrong.

Below is the code :

#include "ESP8266WiFi.h"

const char* ssid = "yours";
const char* password = "yours";

const char *deviceName = "ESP-slave";

//how many clients should be able to telnet to this ESP8266
#define MAX_SRV_CLIENTS 2

WiFiServer server(5252);
WiFiClient serverClients[MAX_SRV_CLIENTS];

//declare vars for receive
char A[5] = {'\0' }; //4 + NULL
char B[3] = {'\0' }; //2 + NULL
char C[4] = {'\0' }; //3 + NULL
char D[5] = {'\0' }; //4 + NULL
//4+2+3+4 = 13 total

//receive vars for chars
#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[16];//13 for vars + SOP +EOP +NULL = 16 total
byte indexA;


void setup() {
  Serial.begin(115200);
  delay(1000);
  wifi_dynamic();
  server.begin();
  //server.setNoDelay(true);

  Serial.print("Ready! Use 'Custom TCP server ");
  Serial.print(WiFi.localIP());
  Serial.println(" 5252' to connect");
  delay(1000);
}

void loop() {
  uint8_t i;
  //check if there are any new clients
  if (server.hasClient()) {
    for (i = 0; i < MAX_SRV_CLIENTS; i++) {
      //find open lot for client
      if (!serverClients[i] || !serverClients[i].connected()) {
        if (serverClients[i]) serverClients[i].stop();
        serverClients[i] = server.available();
        Serial.println("New TCP client : "); Serial.print(i);
        Serial.println("");
        break;
      }
    }
    //no free/disconnected slot so reject
    if ( i == MAX_SRV_CLIENTS) {
      WiFiClient serverClient = server.available();
      serverClient.stop();
      Serial.println("Connection rejected ");
    }
  }

  //check clients for data
  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
    if (serverClients[i] && serverClients[i].connected()) {
      if (serverClients[i].available()) {
        
        while (serverClients[i].available())
        {
          char inChar = serverClients[i].read();
          if (inChar == SOP)
          {
            indexA = 0;
            inData[indexA] = '\0';
            started = true;
            ended = false;
          }
          else if (inChar == EOP)
          {
            ended = true;
            break;
          }
          else
          {
            if (indexA < 17)
            {
              inData[indexA] = inChar;
              indexA++;
              inData[indexA] = '\0';
            }
          }

        }
        // We are here either because all pending serial
        // data has been read OR because an end of
        // packet marker arrived. Which is it?
        if (started && ended)
        {
          // The end of packet marker arrived. Process the packet
          Serial.println("we have reached the end");
          sscanf(inData, "%s,%s,%s,%s", A, B, C, D);
          Serial.println(inData);
          Serial.println(A);
          Serial.println(B);
          Serial.println(C);
          Serial.println(D);
          // Reset for the next packet
          started = false;
          ended = false;
          indexA = 0;
          inData[indexA] = '\0';
        }

      } //end of IF serveClints.available loop
    }
  }


  //check UART for data
  if (Serial.available()) {
    size_t len = Serial.available();
    uint8_t sbuf[len];
    Serial.readBytes(sbuf, len);
    //push UART data to all connected telnet clients
    for (i = 0; i < MAX_SRV_CLIENTS; i++) {
      if (serverClients[i] && serverClients[i].connected()) {
        serverClients[i].write(sbuf, len);
        delay(1);
      }
    }
  }
}

void wifi_dynamic() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial1.print("\nConnecting to "); Serial1.println(ssid);
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
  if (i == 21) {
    Serial1.print("Could not connect to"); Serial1.println(ssid);
    while (1) delay(500);
  }
}

and for reference here's the output of the serial monitor :

Ready! Use 'Custom TCP server 192.168.1.124 5252' to connect
New TCP client : 
0
we have reached the end
1234,12,123,9999
1234,12,123,9999




Exception (9):
epc1=0x402022cf epc2=0x00000000 epc3=0x00000000 excvaddr=0x2c333265 depc=0x00000000

ctx: cont 
sp: 3ffefbb0 end: 3ffefdc0 offset: 01a0

>>>stack>>>
3ffefd50:  3ffee4c0 3ffeeac8 3ffeed6c 402023e0  
3ffefd60:  40107018 00000000 00001388 3ffeeda0  
3ffefd70:  00000000 3fff0a44 000003e8 4020136f  
3ffefd80:  3fffdad0 00000000 3ffeeac8 40202155  
3ffefd90:  00000000 00000000 00000001 3ffeed98  
3ffefda0:  3fffdad0 00000000 3ffeed90 40203b44  
3ffefdb0:  feefeffe feefeffe 3ffeeda0 40100710  
<<<stack<<<

 ets Jan  8 2013,rst cause:1, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v614f7c32
~ld
Ready! Use 'Custom TCP server 192.168.1.124 5252' to connect

I look forward to and welcome any help/guidance etc.

NOTE : I Am still using putty as a client but am now sending : <1234,12,123,999>

robot_constant:
NOTE : I Am still using putty as a client but am now sending : <1234,12,123,999>

No, you didn't, according to the output you were sending: <1234,12,123,9999> which results in a buffer overflow.

if (indexA < 17)
            {
              inData[indexA] = inChar;
              indexA++;
              inData[indexA] = '\0';
            }

When indexA == 16, this block will still be executed which put "inChar" to inData[16] (invalid location) and "'\0'" to inData[17] (invalid location). So you violated not just one but two memory cells.

@arduino_new ...Thank you very much for pointing that out. It forced me to do further checking and testing.

As it turns out, that's not quite what was crashing the ESP8266 and the output of a missing character was indeed correct as per the tests I tried.

In fact the serial.read routine here is very robust thanks to the SOP and EOP. Special thanks to its creator(s).

In my tests I played around with 3 things :

1:

char inData[16];//13 for vars + SOP +EOP +NULL = 16 total

I discovered that if this is set for < 16 you may see chars cut-off/missing or connections repudiated

2 :

if (indexA < 16)

If this is less than your char inData setting then you'll see that characters are missing, <16 in this case
NOTE : this can be larger than char inData setting from what I've experienced in testing.

3:

//sscanf(inData, "%s,%s,%s,%s", A, B, C, D);

The culprit it seems ! With this enabled the ESP crashed and may even reboot , thereafter refusing connections
I also tried to use memset in here to copy the array and sscanf it outisde this loop but experienced the same behavior namely EPS8266 crash.

So now I would like to know :

  1. How can inData be correctly split into char arrays ?
    I would love to know/understand where I'm going wrong.

  2. Why is the code casuing the EPS8266 to crash and/or refuse any connections ?

  3. A sanity check please ... is my magic number 16 the correct packet count ?
    Should the commas (,) be added as well ?

  4. Are the the arrays A, B, C , D correctly sized ?

For reference and discussion find the amended code below. It is functional and expects the following packet :
<1234,12,123,9999>

It's pretty fast and the server seems pretty robust even after sending plenty packets at it in sequence and also bogus data sometimes with only one SOP or EOP or multiples of them.

I look forward to your replies/tips/tricks etc.

#include "ESP8266WiFi.h"

const char* ssid = "yours";
const char* password = "yours";

const char *deviceName = "ESP-slave";

//how many clients should be able to telnet to this ESP8266
#define MAX_SRV_CLIENTS 2

WiFiServer server(5252);
WiFiClient serverClients[MAX_SRV_CLIENTS];

//declare vars for receive
char A[5] = {'\0' }; //4 + NULL
char B[3] = {'\0' }; //2 + NULL
char C[4] = {'\0' }; //3 + NULL
char D[5] = {'\0' }; //4 + NULL
//4+2+3+4 = 13 total

//receive vars for chars
#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[16];//13 for vars + SOP +EOP +NULL = 16 total (if this is set for < 16 < you may see chars cut-off/missing or connections repudiated
byte indexA;


void setup() {
  Serial.begin(115200);
  delay(1000);
  wifi_dynamic();
  server.begin();
  //server.setNoDelay(true);

  Serial.print("Ready! Use 'Custom TCP server ");
  Serial.print(WiFi.localIP());
  Serial.println(" 5252' to connect");
  delay(1000);
}

void loop() {
  uint8_t i;
  //check if there are any new clients
  if (server.hasClient()) {
    for (i = 0; i < MAX_SRV_CLIENTS; i++) {
      //find open lot for client
      if (!serverClients[i] || !serverClients[i].connected()) {
        if (serverClients[i]) serverClients[i].stop();
        serverClients[i] = server.available();
        Serial.println("New TCP client : "); Serial.print(i);
        Serial.println("");
        break;
      }
    }
    //no free/disconnected slot so reject
    if ( i == MAX_SRV_CLIENTS) {
      WiFiClient serverClient = server.available();
      serverClient.stop();
      Serial.println("Connection rejected ");
    }
  }

  //check clients for data
  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
    if (serverClients[i] && serverClients[i].connected()) {
      if (serverClients[i].available()) {
       
        while (serverClients[i].available())
        {
          char inChar = serverClients[i].read();
          if (inChar == SOP)
          {
            indexA = 0;
            inData[indexA] = '\0';
            started = true;
            ended = false;
          }
          else if (inChar == EOP)
          {
            ended = true;
            break;
          }
          else
          {
            //if this is less than your char inData setting then you'll see that characters are missing, <16 in this case
            //NOTE : this can be larger that your char inData setting from what I've experienced in testing
            if (indexA < 16)
            {
              inData[indexA] = inChar;
              indexA++;
              inData[indexA] = '\0';
            }
          }

        }
        // We are here either because all pending serial
        // data has been read OR because an end of
        // packet marker arrived. Which is it?
        if (started && ended)
        {
          // The end of packet marker arrived. Process the packet
          Serial.println("we have reached the end");
          //sscanf(inData, "%s,%s,%s,%s", A, B, C, D); //with this enabled the ESP crashed and may even reboot , thereafter refusing connections
          Serial.println(inData);
          Serial.println(A);
          Serial.println(B);
          Serial.println(C);
          Serial.println(D);
          // Reset for the next packet
          started = false;
          ended = false;
          indexA = 0;
          inData[indexA] = '\0';
        }

      } //end of IF serveClints.available loop
    }
  }


  //check UART for data
  if (Serial.available()) {
    size_t len = Serial.available();
    uint8_t sbuf[len];
    Serial.readBytes(sbuf, len);
    //push UART data to all connected telnet clients
    for (i = 0; i < MAX_SRV_CLIENTS; i++) {
      if (serverClients[i] && serverClients[i].connected()) {
        serverClients[i].write(sbuf, len);
        delay(1);
      }
    }
  }
}

void wifi_dynamic() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial1.print("\nConnecting to "); Serial1.println(ssid);
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
  if (i == 21) {
    Serial1.print("Could not connect to"); Serial1.println(ssid);
    while (1) delay(500);
  }
}

Hello all

After days and now weeks of combing the web and these forums for answers , I am almost at my wits end :frowning:

So perhaps I should simplify the question because maybe I'm going about this the wrong way:

Is there a very simple, efficient and low overhead way to mainpulate/decode/convert/etc this received uint8 value:

<1234,12,123,9999>

So that I end up with 4 variables that I can use to compare and ultimately make a yes/no decision if any or all of the values don't match ?

NOTE:
I have found issues with sscanf not liking commas (so I used spaces instead) , I also found that as long as SOP and EOP were present any old values would be accepted , even something like <>.

I have aslo noticed that most of the examples of any sort of send(TX) and receive (RX) gernally have something like this to fire up a collection buffer of sorts:

char inChar = serverClients[i].read();

or

char inChar = Serial.read();

or

char inChar = Client.read();

or

char inChar = Something.read();

Where inChar could be any name for example C etc etc etc.

The concept is generally the same:

  1. Check for a unique qualifier usually a packet (But cant this be something like STARTX ?)
  2. Start receiving each byte, group the bytes and push them into an array(the type already declared) and keep on until the end of input qualifier is received usually '\n'(or whatever you decide (Could this be something like ENDX ?)
  3. Once the End of input is received , do something.

And this is where the battle is (well at least for me).
The sender(TX) sent it in uint8 and it has probably arrived as such.
but on the receive(RX) the examples mostly declare char Whatever =.
Could you instead select String Whatever = or Int Whatever = or byte Whatever = ?

Help..!

Thanking you in advance and look forward to any replies

Your problem is still with buffer overflows.
Just increase your inChar size to 20.

Then once you have the data, you can parse it like this:

int val1, val2, val3, val4;
sscanf(inChar, "%d,%d,%d,%d", &val1, &val2, &val3, &val4);

@arduino_new

Woooow ..Thank you kindly .. that definitely solved the problem :slight_smile:

What would be the sscanf change if something like :<robot,area,123,9999>

were received ?

Would it then be something like :

string str1,str2;
int val1, val2;
sscanf(inChar, "%s,%s,%d,%d", &str1, &str2, &val1, &val2);

Thank you in advance

D

robot_constant:
@arduino_new

Woooow ..Thank you kindly .. that definitely solved the problem :slight_smile:

What would be the sscanf change if something like :<robot,area,123,9999>

were received ?

Would it then be something like :

string str1,str2;

int val1, val2;
sscanf(inChar, "%s,%s,%d,%d", &str1, &str2, &val1, &val2);




Thank you in advance

D

No, %s will scan the whole string and digits are still string. You will have to use strtok() to parse your string in this case. Check out Robin2's post to parse it.

arduino_new:
No, %s will scan the whole string and digits are still string. You will have to use strtok() to parse your string in this case. Check out Robin2's post to parse it.

Hi arduino_new

Which post are you referring to by Robin2 ?

robot_constant:
Hi arduino_new

Which post are you referring to by Robin2 ?

Should be: Simple and Reliable way to receive data

Which post are you referring to by Robin2 ?

http://forum.arduino.cc/index.php?topic=396450.0

If you use strtok(), be aware that it does not handle empty tokens like you may see when, for example, parsing a comma separated list (csv file)

1234,12,123,999,   //OK if there are no empty tokens
1234,,123,999,      //fails

robot_constant:
...

What would be the sscanf change if something like :

<robot,area,123,9999>

were received ?

...

try

sscanf(inChar,"%[^,],%[^,],%d,%d",&str1, &str2, &val1, &val2);

Read about scansets in scanf() and fscanf() a quick guide is here.

WOW

Thank you all for the replies and tips ..so much to read and research.

@darrob .. I tried your example and it crashed the esp..will investigate

though.
@Pauls thanks a million for the link.And to Robin too
@6v6gt ..so it seems so where to from here ?

The topic of converting the received data seems to be a bit of an it seems.

The sending part seems fairly straightforward , and it's moved down through all

the layers to the receiver things may change.

I have tested the code I posted here including the various suggestions (once

again thanks amillion for pointing out the errors and providing solutions to

those who have replied)

What I was sending was this :

<1234,12,123,9999>

If you count these up you end up with 18 (Correct me if I'm wrong) ,
a NULL could also be included (So 18+1=19) ..

SO this :

char inData[19];

and this :

if (indexA < 19)

and this :

int val1, val2, val3, val4;
          sscanf(inData, "%d,%d,%d,%d", &val1, &val2, &val3, &val4);

work fine !

2 questions here though :

  1. Should indexA <19 actually be indexA <20 ? If so why does it still work with

indexA<191. ?

  1. If I just send this <> it works even if its something like <<<<<>>>>>>> it

works !
So if there a double-check/test that can be done as a SOP and/or EOP qualifier

?

Next up is the sscanf behavior:

If i leave these :

char inData[19];
if (indexA < 19)

and set sscanf as :

String str1, str2, str3, str4;
          sscanf(inData, "%s,%s,%s,%s", &str1, &str2, &str3, &str4);

The ESP crashes and reboots :frowning:

What's wrong ? Is it because I'm not using char arrays to hold the strings or

do I have the pointers wrong etc etc.
Was referncing this page An online C, SQL and Java programming tutorial website

handling/sscanf-function-c/

So onward I go ...
Create the buffers (the intention to hold all the data we got .. correct me if

I'm wrong but it's already on the device in a buffer down there

somewhere...just waitng to be disected and packaged and formatted and presented

..surely theres and easier way ..if so what is it ?)
Anyways there are the buffers .. hopefully NUll terminated correctly and ready

for action, oh and once they've been filled and correctly used , we need to

clear them out for the next round ..is that memset..hope I'm on the right

track.
Let's see .. 4 +1 , 2+1, 3+1, 4+1

//char buffers for packet
char A[5] = {'\0' };
char B[3] = {'\0' };
char C[4] = {'\0' };
char D[5] = {'\0' };

Sanity check please ..is this correct ?
Now to clear them:

memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));
memset(C, 0, sizeof(C));
memset(D, 0, sizeof(D));

Ok now sscanf (again sanity check.. I used what I saw on most site's examples)

sscanf(inData, "%s,%s,%s,%s", A, B, C, D);

Send it the magic/not-so magic packet (yip not 99 and eek with commas too)
I'm guessing if you're a C guru and reading this you know exactly what's going

to happen .. or not ..is it a gamble ? Side bets ?

<1234,12,123,9999>

YIP ..IT WORKS ..woohooo!
But wait ... Something odd now ... here's the output :

we have reached the end
123,9999
1
2
3
4
,
1

But MA that's not what I wanted to see :frowning:
I wanted this :

1234,12,123,9999
1
2
3
4

etc

Apparently sscanf doesn't handle the comma thing too well ? Correct/enlighten

me if I'm wrong or off the mark.

Well anyways I decided to dump the commas (,) and replace with a space
and here's the output (note I am just doing a Serial.print of inData and char

A[0 to 5] :

we have reached the end
1234 12 123 9999
1
2
3
4

Now we can play a bit more , throw a few more space in ... poke the bear a

little, upset the apple cart.

<1234     12 123    9999>
<1234 12 123 9999>
<1234 12  123         9999>

and the output get seriously funky :slight_smile: missing lett... !
And that's because of the packet capture number right ? 19 is the boundary so

far .. Oh by the way I adjusted the main buffer to 80 and left inData to 19

earlier ... so increase the number 19 and see.

Now it's time for the main question again , based on the title.
ESP8266 WifiTelnetToSerial - convert received data from client
Here it is :
What must be changed in the following code (hopefully it's the correct place in

the example's code) in order to split the received data on the commas into char

array variables?

Did I attain the goal ?

Yes it seems so, but this raises a few more :

How do you do a simialr thing is the received data varies .. since this is a

telenet/TCP server and client of sorts ?

There must be an easier way or ways to handle dynamic data coming from the

client?
Please tell me how or what they are if you know of some.

I also found out that there is an issue with the code in this example where the

server takes ages to 'WAKE UP' after random intervals of no action/use.
And thats with all sleep modes disabled.
To test this send it a few packets try bang your packet through a few times

(think 10 or 15 even).Yes the magic one in my post ..wait for either a very

very long resonse or none.
Then try send it a few ping packets and it wakes up.
Hmmm that's not really a robust TCP server is it ?
Sounds more like UDP either way though you get NACK NACK NACK quite often , and

sadly I want the server replying to the first packet if I'm to use TCP !
Rumor has it that this is a problem with the SDK ? Can someone kindly confirm ?

So I think I'll abort this mission for now captain .. I'm off to try the

websockets example next where I have a question which is similar and deals with

the received PAYLOAD buffer ,yes similar just not exactly the same or exactly

the same just slightly different.

I look forward to your replies.

Thank you to all those who have commented and offered help , I appreciate it.

D

PS .. Sorry about the formatting ..not sure why it ended up like this.

sscanf() and most cstring functions take an address to a memory location and expect to be able to write to it. An address is just a number
str1 is a String object, itself is a number, so when you pass it to sscanf(), it writes to that adress and magic happens.

Hi robot_constant

I'm just going to address one small portion of your last post.

when using sscanf with a %s in the format portion, the sccanf will scan the input string until it encounters a whitespace character or the end of the string. Whitespace is defined as space, tab or newline.
so when you use sscanf(inData, "%s,%s,%s,%s", A, B, C, D); and the inData string has no whitespace characters it, you will get a memory overrun and possible a crash.
Think it through - for variable A, sscanf scans inData to the null terminator and puts that into A. There is a buffer overrun right there. Sscanf will then start scanning again, from where it stopped, looking for a whitespace, tab, newline or null to put into B. But the memory it is attempting to scan is -- undefined, or used by something else. And the amount of data it then tries to stuff into B is ?? And then sscanf will continue for C

Get the picture???

This behaviour is why I suggested using a scanset.

The reason that my example crashed it because I suggested using inChar (I did not properly read the question code)

so the correct call would be

sscanf(inData,"%[^,],%[^,],%d,%d",&str1, &str2, &val1, &val2);

given that:

  • inData is a character array containing a string like "robot,area,123,9999"
  • str1 and str2 are character arrays that are large enough contain "robot" plus one extra character