comaring string

Pages: 12
hello ,
my code does (trying....) a simple thing :
1.sending command to device (working)
2.getting a response from it (not sure if working correct)
3. compare answer to known answer to turn on\off a led

my problem is that even when the device is not connected it's still tell me "Working!!!!)
can someone help me please?

Thanks ,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
int test=7;

void setup()  
{
  pinMode(test,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(19200); // Open serial communications and wait for port to open:
  delay(1500);
  Serial.println("Ready to work!");
  mySerial.begin(19200);
  delay(1500);

}

void loop() 
{
  if (digitalRead(test)==HIGH)
  {
    //for (int t=0;t<1;t++) //start of t
    //{
    char response[5];
    char finalPart[2];
    mySerial.println("AT");
    delay(1400); //
    if (mySerial.available() >4)
    {
      for (int i=0;i<6;i++)
      {
        response[i]=mySerial.read();
      }//end for i
    Serial.print(millis());
    Serial.print("this is the full respons - ");
    Serial.println(response);
    finalPart[0]=response[0];
    finalPart[1]=response[1];
    finalPart[2]=('\n');
    Serial.print("this is final - ");
    Serial.print(finalPart[0]);
    Serial.println(finalPart[1]);
    Serial.println(finalPart);
    }
    if ((finalPart[0]='O')||(finalPart[1]=='K'))
    {
      digitalWrite (13,HIGH);
      Serial.println("working!!!!!!!!!!!!!!");
      delay (1500);
      digitalWrite(13,LOW);
    }
    else 
{    Serial.println ("bla");
     }// 
  }//end if
  
  
}//end loop





¿library?
1
2
finalPart[2]=('\n'); //38 out of bounds
if ((finalPart[0]='O')||(finalPart[1]=='K')) //44 warning: suggest parentheses around assignment used as truth value [-Wparentheses] 

At line 44 you are using the '=' assignment operator instead of '==' "is equal to".
I didn't see it - thanks .
and I have look 10 times.

Thanks :-)

ne555

what do you mean by
finalPart[2]=('\n'); //38 out of bounds

I have 3 spaces in finalPart don't I?
and the ('\n') mean that the device have started a new line , no?
char finalPart[2];
has two elements. Valid index values are 0 and 1.

O.K
so why the compiler didn't tell my I have a mistake? something like - "there is no room"?


Unfortunately, C++ doesn't do boundary checks on array usage, its up to the programmer to do that.

Quote:
In C++ it is syntactically correct to exceed the valid range of indices for an array. This can create problems, since accessing out-of-range elements do not cause compilation errors but can cause runtime errors. The reason why this is allowed will be seen further ahead when we begin to use pointers.

http://www.cplusplus.com/doc/tutorial/arrays/
Last edited on
Good to know :-) , thanks ,

Now the problem is that only the second press give me "OK"
(The modem is always on for the test)
where is the problem now?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
int test=7;

void setup()  
{
  pinMode(test,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(19200); // Open serial communications and wait for port to open:
  delay(1500);
  Serial.println("Ready to work!");
  mySerial.begin(19200);
  delay(1500);

}

void loop() 
{
  if (digitalRead(test)==HIGH)
  {

    char response[5];
    char finalPart[2];
    mySerial.println("AT");
    delay(2000); //
    if (mySerial.available() >4)
    {
      for (int i=0;i<6;i++)
      {
        response[i]=mySerial.read();
      }//end for i
      
      Serial.print(millis() /1000);
      Serial.print("this is the full respons - ");
      Serial.println(response);
      finalPart[0]=response[0];
      finalPart[1]=response[1];
      //finalPart[2]=('\n');
      Serial.print("this is final - ");
      Serial.print(finalPart[0]);
      Serial.println(finalPart[1]);
      Serial.println(finalPart);
    }
    if ((finalPart[0]=='O')||(finalPart[1]=='K'))
    {//what to do answer OK
      digitalWrite (13,HIGH);
      Serial.print(millis() /1000);
      Serial.println("Modem is working!!!!");
      delay (1500);
      digitalWrite(13,LOW);
      Serial.println("******************");
    }// end answer OK
    else
    {//what to do if modem not ready
      Serial.print(millis() /1000);
      Serial.println ("  -Modem not ready yet......");
      Serial.println("******************");

    } //end modem not ready

  }//end if

}//end loop






One thing looks suspicious.
When you pass a string to be printed like this,
Serial.println("Modem is working!!!!");
remember that the string "Modem is working!!!!" is a null-terminated c-string.

Example, "AT" consists of the three characters { 'A', 'T', '\0' }

Similarly, I would expect
char finalPart[2];
to be instead
char finalPart[3];
where the 3rd character is set to 0, that is a zero byte to mark the end of the string.

something like this:
1
2
3
      finalPart[0]=response[0];
      finalPart[1]=response[1];
      finalPart[2]= 0; // Null terminator 


now I'm lost....
I get the answer in no order - sometime after 2 press ,sometime after 5.....

so I have start thinking - maybe the problem is in what I receive from the modem

I have try to write a simple code that send "AT" and then print whatever I get
but it didn't work -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <SoftwareSerial.h>
int ledPin=13;
SoftwareSerial mySerial(10, 11); // RX, TX
int in=0;


void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(19200);
  delay(1500);
  Serial.println("Ready to work!");
  mySerial.begin(19200);
  pinMode(ledPin, OUTPUT);
}

void loop() // start of loop
{
 Serial.println("Send at to modem");
  mySerial.println("AT");
  if (mySerial.available() >0)
  {
    in = mySerial.read() ;//print in the monitor what com18 send
    Serial.print("        I received from modem: ");
    Serial.println(in);
  }
  
  delay (5000);

}//end of loop



this is the output - every 10 prints it's return to the same numbers


Ready to work!
send at to modem
send at to modem
       I received from modem: 65
send at to modem
       I received from modem: 84
send at to modem
       I received from modem: 13
send at to modem
       I received from modem: 10
send at to modem
       I received from modem: 13
send at to modem
       I received from modem: 10
send at to modem
       I received from modem: 79
send at to modem
       I received from modem: 75
send at to modem
       I received from modem: 13
send at to modem
       I received from modem: 10

There are a lot of CR-LF pairs
carriage return, '\n' ASCII 13
linefeed, '\n' ASCII 10

The actual text is simply: AT, blank line, OK
O.K - thanks, I don't know why I didn't search it my self.
but now I (and you) know that when I send "AT" I get response
AT
new_line
OK
new_line


so I have try to take char 6 and 7 - but it work only once every 6 times
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
int test=7;

void setup()  
{
  pinMode(test,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(19200); // Open serial communications and wait for port to open:
  delay(1500);
  Serial.println("Ready to work!");
  mySerial.begin(19200);
  delay(1500);

}

void loop() 
{
  if (digitalRead(test)==HIGH)
  {

    char response[10];
    char finalPart[3];
    mySerial.println("AT");
    delay(2000); //
    if (mySerial.available() >4)
    {
      for (int i=0;i<9;i++)
      {
        response[i]=mySerial.read();
      }//end for i
      
      Serial.print(millis() /1000);
      Serial.print("   -   this is the full respons: ");
      Serial.println(response);
      finalPart[0]=response[6];
      finalPart[1]=response[7];
      finalPart[2]=('\0');
      Serial.print("this is final - ");
      Serial.print(finalPart[0]);
      Serial.println(finalPart[1]);
      Serial.println(finalPart);
    }
    if ((finalPart[0]=='O')||(finalPart[1]=='K'))
    {//what to do answer OK
      digitalWrite (13,HIGH);
      Serial.print(millis() /1000);
      Serial.println("Modem is working!!!!");
      delay (1500);
      digitalWrite(13,LOW);
      Serial.println("******************");
    }// end answer OK
    else
    {//what to do if modem not ready
      Serial.print(millis() /1000);
      Serial.println ("  -Modem not ready yet......");
      Serial.println("******************");

    } //end modem not ready

  }//end if

}//end loop


so what are we doing wrong?


My guess would be there might be differing numbers of CR-LF characters. First I would try printing out the details of the response each time, in order to get a clearer understanding of the data.

Secondly, you could try skipping the '\r' and '\n' characters and only inspect the other characters. That means, rather than looking in a fixed position e.g. response 6 and 7, step through response a character at a time until you reach the meaningful data.
1. I have try to that - and as I wrote yesterday it return every 10 char.
2.can you explain more about what you mean? to search in the response "O" and then "K" ?
how do I do this?
Well, I've come up with this, but I think it's a slightly misguided approach:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>

    using namespace std;

bool parseResponse(char * response, char * buffer, int & pos, int size);

int main()
{
    char response[10] = { 65, 84, 13, 10, 13, 10, 79, 75, 13, 10 };
    char buffer[30];
    int pos = 0;

    while (parseResponse(response, buffer, pos, 10))
    {
        cout << buffer << endl;
    }

}

bool parseResponse(char * response, char * buffer, int & pos, int size)
{
    int n = 0;

    // ignore any leading CR or LF
    while (pos < size && (response[pos] == '\r' || response[pos] == '\n'))
        pos++;

    // copy characters until CR or LF is reached
    while (pos < size && response[pos] != '\r' && response[pos] != '\n')
    {
        buffer[n] = response[pos];
        pos++;
        n++;
    }
    buffer[n] = 0; // add the null terminator;
    return (pos < size);
}

Output:
AT
OK


The reason I say it's probably misguided is that I'm dealing here with a fixed 10-character response, but it should probably be considered as a stream of characters instead.
WOW , Thanks - I understand what you are saying but if it will work it won't matter.

but where do I "put" it my code?
Well, The function parseResponse() can be placed anywhere, put it at the end, with the declaration bool parseResponse(char * response, char * buffer, int & pos, int size); somewhere at the top of the code.

Then put these lines:
1
2
3
4
5
6
7
    char buffer[30];
    int pos = 0;

    while (parseResponse(response, buffer, pos, 10))
    {
        cout << buffer << endl;
    }

... somewhere after you have filled the response buffer with your data.
And of course, tweak it as necessary, you could use strcmp() to compare the buffer string with "OK" or "AT" ot whatever you want.
http://www.cplusplus.com/reference/cstring/strcmp/
maybe I'm doing it wrong but - not good


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <SoftwareSerial.h>
#include <iostream>
SoftwareSerial mySerial(10, 11); // RX, TX
int test=7;
 using namespace std;

void setup()  
{
  pinMode(test,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(19200); // Open serial communications and wait for port to open:
  delay(1500);
  Serial.println("Ready to work!");
  mySerial.begin(19200);
  delay(1500);

}

void loop() 
{
  if (digitalRead(test)==HIGH)
  {

    char response[5];
    char finalPart[2];
    mySerial.println("AT");
    delay(2000); //
    if (mySerial.available() >4)
    {
      for (int i=0;i<6;i++)
      {
        response[i]=mySerial.read();
      }//end for i
      
      Serial.print(millis() /1000);
      Serial.print("this is the full respons - ");
      Serial.println(response);
      finalPart[0]=response[0];
      finalPart[1]=response[1];
      finalPart[2]=('\n');
      Serial.print("this is final - ");
      Serial.print(finalPart[0]);
      Serial.println(finalPart[1]);
      Serial.println(finalPart);
    }
    if ((finalPart[0]=='O')||(finalPart[1]=='K'))
    {//what to do answer OK
      digitalWrite (13,HIGH);
      Serial.print(millis() /1000);
      Serial.println("Modem is working!!!!");
      delay (1500);
      digitalWrite(13,LOW);
      Serial.println("******************");
    }// end answer OK
    else
    {//what to do if modem not ready
      Serial.print(millis() /1000);
      Serial.println ("  -Modem not ready yet......");
      Serial.println("******************");

    } //end modem not ready


char buffer[30];
    int pos = 0;

    while (parseResponse(response, buffer, pos, 10))
    {
        cout << buffer << endl;
    }
  }//end if

}//end loop

 

bool parseResponse(char * response, char * buffer, int & pos, int size);

int main()
{
    char response[10] = { 65, 84, 13, 10, 13, 10, 79, 75, 13, 10 };
    char buffer[30];
    int pos = 0;

    while (parseResponse(response, buffer, pos, 10))
    {
        cout << buffer << endl;
    }

}

bool parseResponse(char * response, char * buffer, int & pos, int size)
{
    int n = 0;

    // ignore any leading CR or LF
    while (pos < size && (response[pos] == '\r' || response[pos] == '\n'))
        pos++;

    // copy characters until CR or LF is reached
    while (pos < size && response[pos] != '\r' && response[pos] != '\n')
    {
        buffer[n] = response[pos];
        pos++;
        n++;
    }
    buffer[n] = 0; // add the null terminator;
    return (pos < size);
}

I don't fully understand your code because I don't know what is in #include <SoftwareSerial.h>

But when I look at the previous code you posted there is no function main(). I assume it is in some other part of the code which I can't see. So now, you added function main() which I guess means there are two different versions of main() ?
The version of main() which I posted was for testing/demonstration purposes only. You don't need it.

At any rate, I think tpy need to add the function call inside your function loop()
Last edited on
I don't have main()
I use loop() as the main part of the code .
and the <SoftwareSerial.h> is just so I can use the Serial
Pages: 12