I can not relly understanf the function WaitResp(), could you help me?

Hello all,

Due to serveral issues, I decided to use another function to read the response. It look simplest
However, I really need to understand it well and there a part I can understand.

My first worry is the two first parameters of WaitResp(); : start_comm_tmout and max_interchar_tmout
My second worry is why IsStringReceived() is called twice. First by IsRxFinished() and secondly by WaitResp()

Firstly
(All codes are at the bottom)

As far I understood, start_comm_tmout (start_reception_tmout, see RxInit()) is the timeout to get the first caracter of the response. IF it do not receive a caraceter within that time, it stop.

The second parameters max_interchar_tmout (interchar_tmout see RxInit) it is allowed time to read the expected_resp_string.

If it's right, why there is start_comm_tmout and how to use it. I could always leave it 0 or 10? I do not understand the use and how to use it.

You can read there is two comments (may be my enflish is not good enough):
(Note: the comments in the function is not mine)

// timeout elapsed => GSM module didn't start with response
// so communication is takes as finished

This is my first worry. If I set is to 100 and I do not get an response, it leaves. So how can I define the value?? Should I set it 1000 or 5000. In that case I am sure the get the response if it come after 100?
If I am totaly wrong, could give me your point of view?

// timeout between received character was reached
// reception is finished

Timout between received carater: At the begining, I though is the timeout beween two caraters but I could not make a sens of this, and I finally think, it the timeout between all caraters received. In other work, it's the exepected timeout to get/read the expected_resp_string

I would really appreciate if you can heilight my regarding the use of start_comm_tmout

Secondly
I can see that IsStringReceived() is called twice. Firstly by IsRxFinished() and then by WaitResp().
I can not understand exactely why. I supposed it's a double check but I would not be able to explain why to someone else.

You can read those two comment

// something was received but what was received?
// expected string was received

But if you check the IsRxFinished() function, that function already make that check here

 if (IsStringReceived(expected_resp_string) == 1){
        //Serial.println("not ready");
        return (RX_FINISHED);
      }

So I do not understand why, it check it "twice"

It would be nice if you could highlight me, and particulary on the first case.

Here is the function WaitResp and teh related functions.
Many thank!!!!

Codes
Here is the code of WaitResp() function and the related function

byte WI968C::WaitResp(uint16_t start_comm_tmout, uint16_t max_interchar_tmout,
                   char const *expected_resp_string)
{
  byte status;
  byte ret_val;

  RxInit(start_comm_tmout, max_interchar_tmout);
  // wait until response is not finished
  do {
    status = IsRxFinished(expected_resp_string);
  } while (status == RX_NOT_FINISHED);

  if (status == RX_FINISHED) {
    // something was received but what was received?
    // ---------------------------------------------
 
    if(IsStringReceived(expected_resp_string)) {
      // expected string was received
      // ----------------------------
      ret_val = RX_FINISHED_STR_RECV;     
    }
    else {
  ret_val = RX_FINISHED_STR_NOT_RECV;
  }
  }
  else {
    // nothing was received
    // --------------------
    ret_val = RX_TMOUT_ERR;
  }
  return (ret_val);
}


// Here is the code of IsRxFinished used by WaitResp()

byte WI968C::IsRxFinished(char const *expected_resp_string)
{
  byte num_of_bytes;
  byte ret_val = RX_NOT_FINISHED;  // default not finished

  // Rx state machine
  // ----------------

  if (rx_state == RX_NOT_STARTED) {
    // Reception is not started yet - check tmout
    if (!_cell.available()) {
      // still no character received => check timeout
  /* 
  #ifdef DEBUG_GSMRX
   
      DebugPrint("\r\nDEBUG: reception timeout", 0);     
      Serial.print((unsigned long)(millis() - prev_time)); 
      DebugPrint("\r\nDEBUG: start_reception_tmout\r\n", 0);     
      Serial.print(start_reception_tmout); 
     
   
  #endif
  */
      if ((unsigned long)(millis() - prev_time) >= start_reception_tmout) {
        // timeout elapsed => GSM module didn't start with response
        // so communication is takes as finished
    /*
      #ifdef DEBUG_GSMRX   
        DebugPrint("\r\nDEBUG: RECEPTION TIMEOUT", 0); 
      #endif
    */
        comm_buf[comm_buf_len] = 0x00;
        ret_val = RX_TMOUT_ERR;
      }
    }
    else {
      // at least one character received => so init inter-character
      // counting process again and go to the next state
      prev_time = millis(); // init tmout for inter-character space
      rx_state = RX_ALREADY_STARTED;
    }
  }

  if (rx_state == RX_ALREADY_STARTED) {
    // Reception already started
    // check new received bytes
    // only in case we have place in the buffer
    num_of_bytes = _cell.available();
    // if there are some received bytes postpone the timeout
    if (num_of_bytes) prev_time = millis();
     
    // read all received bytes     
    while (num_of_bytes) {
      num_of_bytes--;
      if (comm_buf_len < COMM_BUF_LEN) {
        // we have still place in the GSM internal comm. buffer =>
        // move available bytes from circular buffer
        // to the rx buffer
        *p_comm_buf = _cell.read();

        p_comm_buf++;
        comm_buf_len++;
        comm_buf[comm_buf_len] = 0x00;  // and finish currently received characters
                                        // so after each character we have
                                        // valid string finished by the 0x00
      if (IsStringReceived(expected_resp_string) == 1){
        //Serial.println("not ready");
        return (RX_FINISHED);
      }
   
      }
      else
{

        _cell.read();

   
   
      }
    }

    // finally check the inter-character timeout
  /*
  #ifdef DEBUG_GSMRX
   
      DebugPrint("\r\nDEBUG: intercharacter", 0);   
     Serial.print((unsigned long)(millis() - prev_time)); 
      DebugPrint("\r\nDEBUG: interchar_tmout\r\n", 0);     
      Serial.print(interchar_tmout); 
     
   
  #endif
  */

   
    /*
      #ifdef DEBUG_GSMRX
   
      DebugPrint("\r\nDEBUG: OVER INTER TIMEOUT", 0);       
    #endif
    */
      comm_buf[comm_buf_len] = 0x00;  // for sure finish string again
                                      // but it is not necessary
      ret_val = RX_FINISHED;
    }
  }

  return (ret_val);
}


// Here is the code of WaitResp() and IsRxReceived

byte WI968C::IsStringReceived(char const *compare_string)
{
  char *ch;
  byte ret_val = 0;

  if(comm_buf_len) {
  #ifdef DEBUG
    Serial.println("ATT: ");
    Serial.print(compare_string);
    Serial.print("RIC: ");
    Serial.println((char *)comm_buf);
  #endif
    ch = strstr((char *)comm_buf, compare_string);
    if (ch != NULL) {
      ret_val = 1;
    /*#ifdef DEBUG_PRINT
    DebugPrint("\r\nDEBUG: expected string was received\r\n", 0);
    #endif
    */
    }
  else
  {
    /*#ifdef DEBUG_PRINT
    DebugPrint("\r\nDEBUG: expected string was NOT received\r\n", 0);
    #endif
    */
  }
  }
  return (ret_val);
}

// Here is the code of RxInit used by WaitResp

void WI968C::RxInit(uint16_t start_comm_tmout, uint16_t max_interchar_tmout)
{
  rx_state = RX_NOT_STARTED;
  start_reception_tmout = start_comm_tmout;
  interchar_tmout = max_interchar_tmout;
  prev_time = millis();
  comm_buf[0] = 0x00; // end of string
  p_comm_buf = &comm_buf[0];
  comm_buf_len = 0;
  _cell.flush(); // erase rx circular buffer
}

This can be heloful (wi968c.h)

enum rx_state_enum 
{
  RX_NOT_FINISHED = 0,       // not finished yet
  RX_FINISHED,               // finished, some character was received
  RX_FINISHED_STR_RECV,     // finished and expected string received
  RX_FINISHED_STR_NOT_RECV, // finished, but expected string not received
  RX_TMOUT_ERR,             // finished, no character received 
  RX_LAST_ITEM // initial communication tmout occurred
};

It would be nice if you could highlight me, and particulary on the first case.

me
Is highlighting in yellow okay?

If you really want help, you'll post ALL of your code - the header file, the source file, AND the sketch that uses the class.

Due to several issues, I decided to use another function to read the response. It look simplest
However, I really need to understand it well and there a part I can understand.

So, are you saying that you had several issues with some code, and decided to use some other code, but you want us to explain to you why the first code did not do what you expected it to. Not exactly at the top of my list to give advice on today !

Hello!

Thank for your answers but I can not understand the sens of it.
All of the code is below the word "Many Thank!!!", at the bottom (I just splited it between [ code ] section.

May be I missed to write how to call it

_cell.println("AT");
WaitResp(500,1000,"OK"); //timeout1,timeout2,response

or

_cell.println("AT+CIFSR");
WaitResp(500,1000,"OK");

or

_cell.println("AT+CPMS?");
WaitResp(500,1000,"OK");

May be I missed it as well

#include <SoftwareSerial.h>
#include <Wi968c.h>

My worry is regarding a function and I posted all of its code, and all of the code of other function that the concerned function calls.

I do want you to explain why my first code does not work because I am not using it any more. I am more interrested of the first ca**s**e below the word First which concern the function WaitResp() and its 2nd and 3rd parameters. My worriy now is particulary the 2nd parameters. What that timeout is used for exactely?

:slight_smile:

Don't split the code.
It just makes work for someone to join it up and maybe make errors in the process.

...R