handling USSD resquets from sim800l

hi
i wan to asck by USSD network operator for the sim card sold,so im using USSD there is my code :

#include <SoftwareSerial.h>
#include <String.h>
//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 7

//SIM800 RX is connected to Arduino D7
#define SIM800_RX_PIN 8

//Create software serial object to communicate with SIM800
SoftwareSerial sim800l(SIM800_TX_PIN, SIM800_RX_PIN);
boolean creditDA;
boolean creditMo;
void initialiser();
void verifieCredit();
void recharger();

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial);
  sim800l.begin(9600);
  delay(2000);
}

void loop() {
  // put your main code here, to run repeatedly:
  initialiser();
  if (creditMo)localiser();
}

void localiser() {}

void initialiser() {
  verifieCredit();
  delay(50000);
  if (creditDA)recharger();
  delay(500);
  Serial.println("initialiser");
}

void verifieCredit() {
  unsigned int i, j ;

  String s = "", l = "";
  char ch[300];
  creditMo = false;
  creditDA = false;
  sim800l.println("AT+CUSD=1");
  delay(1000);
  while (!sim800l.available()) {}
  Serial.println(sim800l.readString());
  while (!Serial.available()) {}
  sim800l.println("AT+CUSD=1,\"*222#\"");
  while (!sim800l.available()) {}
  Serial.print(sim800l.readString());
  while (!Serial.available()) {}
  Serial.print(sim800l.readString());
  while (!sim800l.available()) {}
  readSerial(ch);




  i = 0;

  delay(5000);


  for (int k = 1; k < i; k++) {
    while (!Serial.available()) {};
    Serial.print(ch[k]);
  }
  delay(5000);
  while (!Serial.available()) {}
  Serial.println("s:" + s.length()); // just to know what happning

  delay(1000);
  j = 1;
  while (j <= i) {
    if (ch[j] == 'M')
      if (ch[j + 1] == 'o')
      {

        j = j - 2;
        while (ch[j] != ' ') {
          if (ch[j] != '0')
          {
            creditMo = true;
            break;
            while (Serial.available() == 0) {}
            Serial.println("trouve");
          }
          else j = j - 1;
        }
        j = i + 1;
      }
      else {
        j = j + 1;
        while (Serial.available() == 0) {}
      }
  }
  Serial.println("non trouve Mo");

  if (!creditMo)
  {
    j = 1;
    while (j <= i) {
      if (ch[j] == 's')
        if (ch[j + 1] == 'o')
          if (ch[j + 2] == 'l')
            if (ch[j + 3] == 'd')
              if (ch[j + 4] == 'e')
              {
                j = j + 6;
                if ((ch[j] != '0') && (ch[j + 1] != ',') && (ch[j + 2] != ','))
                {
                  creditDA = true;
                }
                j = i + 1;
              }
              else
                j = j + 1;
    }
  }
  Serial.println("creditDA,creditMo");
}




void recharger() {
  sim800l.println("AT+CUSD=1,\"*600#\"");
  delay(1000);
  sim800l.println("AT+CUSD=1,\"3\"");
  delay(1000);
  sim800l.println("AT+CUSD=1,\"1\"");
  Serial.println("Recherger");
}
/*
  Serial.println("Get data HTTP");
  //set up GPRS, connection type
  sim800l.print("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r");
  delay(1000);
  // set the APN
  sim800l.print("AT+SAPBR=3,1,\"internet\",\"internet\"\r");
  delay(1000);
  //tries to connect to GPRS
  sim800l.print("AT+SAPBR=1,1\r");
  delay(2000);
  // initialise embedded HTTP ruttine
  sim800l.print("AT+HTTPINIT\r");
  delay(2000);
  // set the HTTP session
  sim800l.print("AT+HTTPPARA=\"CID\",1\r");
  delay(1000);
  Serial.println("Enter the URL of the website: ");
  char url[100];
  readSerial(url);  // votre URL
  Serial.println(url);
  // set the HTTP URL
  sim800l.print("AT+HTTPPARA=\"URL\",\"");
  sim800l.print(url);
  sim800l.print("\"\r");
  delay(1000);
  // start the session
  sim800l.print("AT+HTTPACTION=0\r");
  delay(10000);
  // read the data of the HTTP server
  sim800l.print("AT+HTTPREAD\r");
  delay(1000);
  // terminate the HTTP server
  sim800l.print("AT+HTTPTERM\r");
  delay(100);
  sim800l.println();
  }*/

int readSerial(char result[]) {
  int i = 0;
  while (1) {
    while (sim800l.available() > 0) {
      char inChar = sim800l.read();
      if (inChar == '\n') {
        result[i] = '\0';
        sim800l.flush();
        return 0;
      }
      if (inChar != '\r') {
        result[i] = inChar;
        i++;
      }
    }
  }
}

in the normal way with the AT+CUSD=1,"*222#" i got

AT+CUSD=1,"*222#"
OK

+CUSD: 0, "Plan Top, solde 246,02DA", 15

i can’t figure how to parse +CUSD: 0, “Plan Top, solde 246,02DA”, 15 to char

help plz

i can't figure how to parse +CUSD: 0, "Plan Top, solde 246,02DA", 15 to char

First, you don't seem to understand what parse means. Parsing is the act of collecting tokens, and making sense of them. Storing that data in a char array needs to happen BEFORE the array can be parsed.

Serial communication is asynchronous. If you intend to force the Serial (or sim800l) communication into a synchronous pattern, you must read all serial data that makes up a response, NOT just whatever has arrived within some time frame.

hi ,thanks for responce i changed my code ty be synchrone but not working at all,however it seems good coding

there is my code

#include <SoftwareSerial.h>
#include <String.h>
//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 7

//SIM800 RX is connected to Arduino D7
#define SIM800_RX_PIN 8

//Create software serial object to communicate with SIM800
SoftwareSerial sim800l(SIM800_TX_PIN, SIM800_RX_PIN);
boolean creditDA;
boolean creditMo;
boolean working;
char ch0[300];


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial);
  sim800l.begin(9600);
  delay(2000);
  sim800l.println("AT+CUSD=1,\"*222#\"");  
  working=true;
  delay(5000);
}

void loop() {
  // put your main code here, to run repeatedly:
  static int i;
  if (sim800l.available())
  {
   working=true;
   Serial.println("loop sim800L");
   i =readSerial(ch0);      
   Serial.println("loop sim800L_");
   working=false;
  } 
  else if (!working){  
  Serial.println("loop initialiser sim800L");
  initialiser(ch0,i);
  Serial.println("loop initialiser sim800L_");
  }
}

void localiser() {}

void initialiser(char result[],int i) {
  working = true;
  Serial.println("Intialiser");
  verifieCredit(result,i);
  delay(1000);
  if (creditDA)recharger();
  delay(500);
  Serial.println("Intialiser_");
  working = false;

}

void verifieCredit(char ch[],int i) {
    working = true;
  Serial.println("verifieCredit");

  unsigned int j ;
  creditMo = false;
  creditDA = false;
  delay(1000);
  j = 1;
  while (j <= i) {
    if (ch[j] == 'M')
      if (ch[j + 1] == 'o')
      {

        j = j - 2;
        while (ch[j] != ' ') {
          if (ch[j] != '0')
          {
            creditMo = true;
            break;
          }
          else j = j - 1;
        }
        j = i + 1;
      }
      else {
        j = j + 1;
      }
  }

  if (!creditMo)
  {
    j = 1;
    while (j <= i) {
      if (ch[j] == 's')
        if (ch[j + 1] == 'o')
          if (ch[j + 2] == 'l')
            if (ch[j + 3] == 'd')
              if (ch[j + 4] == 'e')
              {
                j = j + 6;
                if ((ch[j] != '0') && (ch[j + 1] != ',') && (ch[j + 2] != ','))
                {
                  creditDA = true;
                }
                j = i + 1;
              }
              else
                j = j + 1;
    }
  }
    Serial.println("verifieCredit_");
      working = false;


}




void recharger() {
  working = true;

  sim800l.println("AT+CUSD=1,\"*600#\"");
  delay(1000);
  sim800l.println("AT+CUSD=1,\"3\"");
  delay(1000);
  sim800l.println("AT+CUSD=1,\"1\"");
    working = false;

}

int readSerial(char result[]) {
  working = true;
  Serial.println("readSerial");
  int i = 0;
  while (1) {
    while (sim800l.available() > 0) {
      char inChar = sim800l.read();
       if (inChar == '\n') {
        result[i] = '\0';
        //sim800l.flush();
        return 0;
      }
      if (inChar != '\r') {
        result[i] = inChar;
        i++;
          Serial.println("inChar :"+inChar);
      }
    }
  }
    Serial.println("readSerial_");

  return i;
  working = false;
}

am getting this result

loop sim800L
readSerial
eCredit_
"*600#"
r
redit_
*600#"
,"*600#"
edit_
rifieCredit_
fieCredit

Intialiser
er
ieCredit
ieCredit
ieCredit
ntialiser
Intialiser
loop sim800L_
loop sim800L
readSerial
SD=1,"*600#"
T+CUSD=1,"*600#"
loop sim800L_
loop sim800L
readSerial
loop sim800L_
loop sim800L
readSerial
r
redit_
*600#"
,"*600#"
edit_

L
ifieCredit

L
Intialiser
D=1,"*600#"
+CUSD=1,"1"
SD=1,"3"
USD=1,"1"
L
"*600#"
SD=1,"1"
D=1,"1"

L
,"1"
SD=1,"1"
+CUSD=1,"1"
1,"3"
,"3"
L
ieCredit
Credit
edit

ifieCredit
ieCredit
edit_
eCredit_
Intialiser

i can’t get it at all

i changed my code ty be synchrone

  sim800l.println("AT+CUSD=1,\"*222#\""); 
  working=true;
  delay(5000);

Send a message. Stick your head in the sand for a while. Don't bother with any response from the other device. That's hardly the idea behind synchronous communication.

i is a stupid name for an argument or for a static variable. The value in the variable means something. The name of the variable should reflect the meaning of the value it contains.

      if (ch[j] == 's')
        if (ch[j + 1] == 'o')
          if (ch[j + 2] == 'l')
            if (ch[j + 3] == 'd')
              if (ch[j + 4] == 'e')
              {

EVERY if statement should have curly braces.

There are better ways to check 5 successive elements of an array.

hi
and thank u PaulS

for "Stick your head in the sand for a while." is the readBytes() setTimeout() a good choise ???

for “Stick your head in the sand for a while.” is the readBytes() setTimeout() a good choise

No. You need to spin in a while loop until there is no more serial data to read or some time has elapsed (setTimeout() sets the value; readBytes() does the spinning). But, instead of using those two functions, you need to write your own code, so you can break out of the while loop if you get the expected response or if you get the end of the response, regardless of whether the response is what you expected, or not.

hi

well the problem is that when i send "AT+CUSD=1,"*222#" i get "OK" the the status of sim800l probably is not availeble then it turn availible agen and give the responce of the GSM operator,so i don't know how to handle that .

well the problem is that when i send "AT+CUSD=1,"*222#" i get "OK" the the status of sim800l probably is not availeble then it turn availible agen and give the responce of the GSM operator,so i don't know how to handle that .

Some punctuation is sorely needed in that run-on collection of words.

If you send a message, you must think of it like posting here.

You need to wait for a complete response, or until a reasonable period of time has elapsed. The entire response may consist of more than just OK.

The real challenge is determining when you have received a complete response. It is unfortunate that most things that understand AT commands do not send an end of packet marker so you know when they are done responding.

hi

problem solved by using

...
  sim800l.setTimeout(5000); 
...
sim800l.readBytes(ch0,300)