I just don't understand why this command is behaving like this

Thank you for the help so far guys, on this gsm project I am wanting to request the balance.

the command line is

 mySerial.println("AT+CUSD=1,\"*100#\"");

I am having trouble getting this to work properly.

The command line is in function StatusCredit();

If I call this by sending a Status text it doesn’t run unless I have called the same function via Serial monitor by pressing s first.

after pressing s I get +CUSD: 0, "Your network balance is ⸮ and no more data, however if I then send a status text I get +CUSD: 0,“Hi, your network balance is ⸮xx.xx.”, 15

clearly the routes to StatusCredit(0; function are different and this affects how it behaves. It also appears that the module is holding this information as removing the command line and flashing the unit can still generate the responses above until the unit is power cycled.

attached is the full code

gsm.ino (13.5 KB)

If I also print str1 when the module processes +CUSD I get 0, rather than
"Hi, your network balance is ⸮xx.xx." although it should be looking in the first two " marks?

response +CUSD: 0,"Hi, your network balance is ⸮xx.xx", 15

Then when parsed it is seeing "0," for str1 not "Hi, your network balance is ⸮xx.xx"

Didn’t open the file. When your project gets to 13KB+ size, you stand a much better chance of getting help if you make a MCVE. That way people don’t waste time wading through dozens (hundreds) of lines of unrelated code. Remember, people are doing this for free.

lol guess I cant win.....

when i post the code relating to what I am working on get asked for it all, when i post it all I get asked for what i am working on.

I will remove some of the code and retest to confirm, but suspect at least half if not more will still be there.

BeWayne:
lol guess I cant win.....

when i post the code relating to what I am working on get asked for it all, when i post it all I get asked for what i am working on.

I will remove some of the code and retest to confirm, but suspect at least half if not more will still be there.

You are not being asked for "what you are working on", you are being asked for a "Minimal, Complete, and Verifiable" example of the problem code. Preparing it can often lead to you discovering the cause of the problem and if not then others can more easily try it for themselves without wading through masses of code that is irrelevant to the problem. Note that MCV means that it must be possible to compile the program and that details of any external libraries, devices and sensors is given.

BeWayne:
I will remove some of the code and retest to confirm, but suspect at least half if not more will still be there.

Half of 13+k will be below the posting limit.

I completely agree and understand a minimal working copy of the problem.

okay stripped it down plenty and can still generate the problem.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8);
//+CMT: "+447xxxxxxxx","","18/09/21,20:54:59+04" SITE WHATS HAPPENING
//enter the message from serial monitor for testing
char Grsp[80];//size for max message
char str1[15];//size appropriately for parsed characters
char str2[30];//size appropriately for parsed characters

boolean newMessage = false;
boolean prefixMatch = false;

void setup()
{
  Serial.begin(57600);
  //set ms timeout for Serial.readBytes() if no data
  mySerial.begin(57600);
 
 mySerial.setTimeout(100);

  mySerial.println("AT+CMGF=1\r");
  delay(100);
  mySerial.println("AT+CNMI=2,2,0,0,0\r"); // AT Command to recieve a live SMS
  delay(100);
  mySerial.println("AT+CMGD=1,4");
  delay(100);

}

void loop() {
if (Serial.available() > 0)
    switch (Serial.read())
    {
      case 's':
        StatusCredit();
        break;}

  while (mySerial.available() > 0)
  {
    //readBytes returns number read not zero referenced
    byte numChars = mySerial.readBytes(Grsp, 100);
    Grsp[numChars] = '\0';//null Terminate
    newMessage = true;

    Serial.println(Grsp);

  }

if (strncmp(Grsp, "\r\n+CUSD:", 8) == 0 && newMessage == true)
  {
    Serial.println("USD no £");
    prefixMatch = true;
    newMessage = false;
 
  }else if (strncmp(Grsp, "\r\n+CMT", 6) == 0 && newMessage == true)
  {
    Serial.println("prefixMatch +");
    prefixMatch = true;
    newMessage = false;
  }
  else if (newMessage == true)
  {
    Serial.println("no prefixMatch");
    newMessage = false;
  }

  if (prefixMatch == true)
  {
    prefixMatch = false;
    char* strtokIndx;
    //find first "
    strtokIndx = strtok(Grsp, " \" ");//need escape character for " delimiter
    //find second "
    strtokIndx = strtok(NULL, " \" ");
    strcpy(str1, strtokIndx); //characters between first set of ""
    for (byte i = 0; i < 3; i++) //skip next 3 " delimiters
    {
      strtokIndx = strtok(NULL, " \" ");
    }
    //find ending character message
    strtokIndx = strtok(NULL, "\r\n"); //last " to end of string no delimiter \0 terminator
    strcpy(str2, strtokIndx); //skip space preceding SITE

    //Serial.println(str1);
    Commandprocess();
 }
}

void Commandprocess() {
  mySerial.print("AT+CMGS=\"");
  mySerial.print(str1);
  mySerial.print("\"\n\r");

 
  if (strncasecmp(str2, "STATUS", 6) == 0) {
    Serial.println("prefixMatch STATUS");
         Status();
  }
}


void  Status()
{ 
  StatusCredit();
  mySerial.println();
  mySerial.println((char)26);// ASCII code of CTRL+Z
        
      newMessage = false;

}

void StatusCredit(){

 mySerial.println("AT+CUSD=1,\"*100#\"");
delay(5000);
  }

Okay so the process is still the same:-

case s generates:- +CUSD: 0, "Your network balance is ⸮ //incomplete

using status command sent by text generates:-

+CUSD: 0,"Hi, your network balance is ⸮xx.xx", 15 //complete but only obtainable if s done first

if I turn off the command mySerial.println("AT+CUSD=1,"*100#""); //then result still shows until power cycle

*100# is the command from your sims network in this case giffgaff

AT+CMGF=1
15:55:56.529 -> OK
15:55:56.529 -> AT+CNMI=2,2,0,0,0
15:55:56.529 -> OK
15:55:56.529 -> AT+CMGD=1,4
15:55:56.529 -> OK // end of setup
15:55:56.529 ->
15:55:56.529 -> no prefixMatch //loop prefix match check NO MATCH

15:56:16.770 -> +CMT: "+447xxxxxxxxx","","18/10/16,15:56:16+04" //incoming SMS message 1
15:56:16.770 -> Status //incoming SMS message 1
15:56:16.770 ->
15:56:16.770 -> prefixMatch + //loop prefix match check MATCH +CMT
15:56:16.770 -> prefixMatch STATUS //loop prefix match check MATCH STATUS in message

AT+CMGS="+447xxxxxxxx"AT+CUSD=1,"*100#" //CreditStatus command

15:56:21.868 -> >
15:56:21.868 -> >
15:56:21.868 -> no prefixMatch //loop no match

15:56:25.664 -> +CMGS: 13 //sms message sent13
15:56:25.664 ->
15:56:25.664 -> OK
15:56:25.664 ->
15:56:25.664 -> no prefixMatch // loop no match

// serial monitor s pressed then enter
AT+CUSD=1,"*100#" //CreditStatus command

15:56:40.442 -> OK
15:56:40.442 ->
15:56:40.442 -> +CUSD: 0, "Your giffgaff balance is ⸮ //response incomplete
15:56:40.476 -> no prefixMatch // no match

15:56:58.719 -> +CMT: "+447xxxxxxxx","","18/10/16,15:56:58+04"
15:56:58.719 -> Status // process repeated with SMS status sent to module
15:56:58.719 ->
15:56:58.719 -> prefixMatch +
15:56:58.719 -> prefixMatch STATUS
AT+CMGS="+447xxxxxxxx"AT+CUSD=1,"*100#" //statuscredit

15:57:03.850 -> >
15:57:03.850 -> >
15:57:03.850 -> no prefixMatch

15:57:06.900 -> +CMGS: 14
15:57:06.900 ->
15:57:06.900 -> OK
15:57:06.900 ->
15:57:06.900 -> no prefixMatch

15:57:07.622 -> +CUSD: 0,"Hi, your giffgaff balance is ⸮xx.xx.", 15 // respone in full
15:57:07.622 ->
15:57:07.622 -> no prefixMatch

Note: I have removed the

if (strncmp(Grsp, "\r\n+CUSD:", 8) == 0 && newMessage == true)
  {
    Serial.println("USD no £");
    prefixMatch = true;
    newMessage = false;
 
  }else

as not required to look at the first problem of credit balance retrival
As you can see the current code, doesn't respond properly to the SMS command Sent of Status until it is first activated by s and enter in serial monitor.

Can't work out why Serial monitor response is always ending at ⸮ which should be currency symbol £ I suspect.
Can't work out why SMS to activate StatusCredit(); function doesn't work until serial monitor has used s.
Can't work out why the Status Credit function seems to respond even after taking out the request until a power cysle has been performed.

If you need anything else from me please let me know, will be looking at this again later today/ tomorrow.

Thanks again.

One issue I can see is that str1 is too small: it looks like you're trying to copy

Hi, your giffgaff balance is ⸮xx.xx.

into it which is considerably more than 15 characters.

Agreed that Str1 wouldn't be long enough, however I have stopped looking at parsing +CUSD: 0,"Hi, your giffgaff balance is ⸮xx.xx.", 15

as the issue occurs without this code being present then whilst it will need addressing later, it isn't the source of my initial issue I suspect.

When I did parse it saw 0, which is the wrong area anyway so that is another thing for me to look at.

Please correct me if I am wrong

Do you have the pure and unadulterated output from post 8 without the manual edits?
Am I right in thinking that you have command echoing turned on (even though I don't see it being turned on in the code)?

not now I don’t just having everything time stamped so I can see whats happening when.

I have managed to progress a little, in that I no longer need the Serial monitor and s to get it to fire up the balance.

current

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8);
//+CMT: "+447xxxxxxxx","","18/09/21,20:54:59+04" SITE WHATS HAPPENING
//enter the message from serial monitor for testing
char Grsp[100];//size for max message
char str1[15];//size appropriately for parsed characters
char str2[30];//size appropriately for parsed characters

boolean newMessage = false;
boolean prefixMatch = false;

void setup()
{
  Serial.begin(57600);
  //set ms timeout for Serial.readBytes() if no data
  mySerial.begin(57600);
 
 mySerial.setTimeout(100);

  mySerial.println("AT+CMGF=1\r");
  delay(100);
  mySerial.println("AT+CNMI=2,2,0,0,0\r"); // AT Command to recieve a live SMS
  delay(100);
  mySerial.println("AT+CMGD=1,4");
  delay(100);

}

void loop() {

  while (mySerial.available() > 0)
  {
    //readBytes returns number read not zero referenced
    byte numChars = mySerial.readBytes(Grsp, 100);
    Grsp[numChars] = '\0';//null Terminate
    newMessage = true;

    Serial.println(Grsp);

  }

if (strncmp(Grsp, "\r\n+CUSD:", 8) == 0 && newMessage == true)
  {
    Serial.println("USD no £");
    prefixMatch = true;
    newMessage = false;
 
  }else if (strncmp(Grsp, "\r\n+CMT", 6) == 0 && newMessage == true)
  {
    Serial.println("prefixMatch +");
    prefixMatch = true;
    newMessage = false;
  }
  else if (newMessage == true)
  {
    Serial.println("no prefixMatch");
    newMessage = false;
  }

  if (prefixMatch == true)
  {
    prefixMatch = false;
    char* strtokIndx;
    //find first "
    strtokIndx = strtok(Grsp, " \" ");//need escape character for " delimiter
    //find second "
    strtokIndx = strtok(NULL, " \" ");
    strcpy(str1, strtokIndx); //characters between first set of ""
    for (byte i = 0; i < 3; i++) //skip next 3 " delimiters
    {
      strtokIndx = strtok(NULL, " \" ");
    }
    //find ending character message
    strtokIndx = strtok(NULL, "\r\n"); //last " to end of string no delimiter \0 terminator
    strcpy(str2, strtokIndx); //skip space preceding SITE

    //Serial.println(str1);
    Commandprocess();
 }
  
}

void Commandprocess() {
  
 
  if (strncasecmp(str2, "STATUS", 6) == 0) {
    Serial.println("prefixMatch STATUS");
         Status();
  }
}


void  Status()
{ 
  StatusCredit();
 
  mySerial.println((char)26);// ASCII code of CTRL+Z
        
      newMessage = false;

}

void StatusCredit(){

 mySerial.println("AT+CUSD=1,\"*100#\"");
delay(5000);
 
  }

current issue to solve.

when I send Status via SMS the response is:-

+CUSD: 0, "Your giffgaff balance is ⸮

whilst not the full line, this is better than wheer i was at as it is direct from the incomming sms command status.

I don’t think you answered my question about the command echoing, but I will just take a wild stab in the dark anyway and suggest that (part of) the problem is delay(5000);, it may cause the serial buffer (likely 64 bytes) to overflow. Anyway, a 5 second delay in your code is just bollocks anyway.

As a test, try deleting the delay and maybe increasing mySerial.setTimeout(100); somewhat.

Long term, you need to be following Robin2’s advice about reliable serial input.

if I haven’t provided the information you want, then maybe I didn’t understand the question.

in earlier code the delay seemed to move things on for me, but you are indeed correct and it wasn’t relevant, I have removed the delay now and got a much more sensible answer.

The balance message is megga long, here it is in its entity.

+CUSD: 0, “Your giffgaff balance is ⸮xx.xx. It’s free to call and text anyone on giffgaff when you top up b
y ⸮10 or more every 3 months, so get your mates on board.”, 15

other sims it could be longer I guess but unlikely to be over 1 stndard message length, what ever that is.

code that now appears to have got this working is as follows:-

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8);
//+CMT: "+447xxxxxxxx","","18/09/21,20:54:59+04" SITE WHATS HAPPENING
//enter the message from serial monitor for testing
char Grsp[109];//size for max message
char str1[15];//size appropriately for parsed characters
char str2[30];//size appropriately for parsed characters

boolean newMessage = false;
boolean prefixMatch = false;

void setup()
{
  Serial.begin(57600);
  //set ms timeout for Serial.readBytes() if no data
  mySerial.begin(57600);
 
 mySerial.setTimeout(100);

  mySerial.println("AT+CMGF=1\r");
  delay(100);
  mySerial.println("AT+CNMI=2,2,0,0,0\r"); // AT Command to recieve a live SMS
  delay(100);
  mySerial.println("AT+CMGD=1,4");
  delay(100);

}

void loop() {

  while (mySerial.available() > 0)
  {
    //readBytes returns number read not zero referenced
    byte numChars = mySerial.readBytes(Grsp, 109);
    Grsp[numChars] = '\0';//null Terminate
    newMessage = true;

    Serial.println(Grsp);

  }
if (strncmp(Grsp, "\r\n+CUSD:", 8) == 0 && newMessage == true)
  {
    Serial.println("USD no £");
    prefixMatch = true;
    newMessage = false;
 
  }else 
if (strncmp(Grsp, "\r\n+CMT", 6) == 0 && newMessage == true)
  {
    Serial.println("prefixMatch +");
    prefixMatch = true;
    newMessage = false;
  }
  else if (newMessage == true)
  {
    Serial.println("no prefixMatch");
    newMessage = false;
  }

  if (prefixMatch == true)
  {
    prefixMatch = false;
    char* strtokIndx;
    //find first "
    strtokIndx = strtok(Grsp, " \" ");//need escape character for " delimiter
    //find second "
    strtokIndx = strtok(NULL, " \" ");
    strcpy(str1, strtokIndx); //characters between first set of ""
    for (byte i = 0; i < 3; i++) //skip next 3 " delimiters
    {
      strtokIndx = strtok(NULL, " \" ");
    }
    //find ending character message
    strtokIndx = strtok(NULL, "\r\n"); //last " to end of string no delimiter \0 terminator
    strcpy(str2, strtokIndx); //skip space preceding SITE

    //Serial.println(str1);
    Commandprocess();
 }
  
}

void Commandprocess() {
  
 
  if (strncasecmp(str2, "STATUS", 6) == 0) {
    Serial.println("prefixMatch STATUS");
         Status();
  }
}


void  Status()
{ 
  StatusCredit();
 
  mySerial.println((char)26);// ASCII code of CTRL+Z
        
      newMessage = false;

}

void StatusCredit(){

 mySerial.println("AT+CUSD=1,\"*100#\"");

 
  }

now for the next stage and thanks for the help and pushing me on, finding it very confusing how things that appear to be helping actually weren’t, but such is life.

Grsp still looks to be too small for slurping up the whole string that you posted plus any non-printable characters plus \0.

Once you overflow a buffer things can get very unpredictable very quickly. Avoid at all cost.

mySerial.setTimeout(100);

It was suggested previously that could try increase the mySerial.readBytes() timeout. Perhaps the incomplete balance message is due to latency in coming up with the balance amount. Is the balance coming from a giffgaff server, or is it on the sim card of the gsm module?

its 173 characters long by all accounts, and this was the next stage of the process.
Gprs set to 175 characters and is working properly now.

My initial error made it impossible to send a status text in and get the balance command to respond, that has been sorted.

Given its length I am not sure it its worth including, wouldn't mind but the bit I am interested in is the actual blance and not the text thats padding the message out.

the message itself is 153 characters which I believe is the maximum for a single sms, kind of make sense, then the additional information to make it work so i can realistically expect it shouldn't be any longer for any other provider as it would seem mad for them to send 2 messages as a reply just for a message.

so out of 153 characters I only want ⸮xx.xx

so my next question is there anything that can be done to reduce the demand on resources? or do I have to get it all n one go and then chop it down?

I could I guess when the status credit is requested assing gprs to 175 and reduce it back otherwise?

You could arrange to read the status credit message by a different mechanism that just reads and discards until it finds the '⸮' character.

But compiling it on an Uno, it seems that you have plenty of space to increase the size of your buffer, so why add complexity?

If you are really concerned about memory, try using the F macro to wrap some of the text you're printing e.g.

    Serial.println(F("prefixMatch STATUS"));

Not sure I understand how resources are allocated, but I am mindful that reources are limited. If it gets too tight, I either drop it or something else but if theres a way to include it that uses less resources then it has to be considered if that option is more benifcial, its not rocket science in that respect.

From where I was in this my first project, I am doing more and taking up less, which has to be a good thing.

If I move a global to a local how do I know I have enough space to run the local variables?