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
};