Loop

Okay, so I have some code that listens for an SMS, when the correct starting phrase is seen it processes the data and stores it.

however using

while(1)

this seems limited to about 7 messages incoming and then stops working completely on the 8th command sentm, it doesn’t recognise the command sent even if the same command has been set each time.

SMS1078xxxxxxxx or
MSG1abcdefghijk

doesn’t matter to be honest

I need to get it to go on indefinitely, coming out of the loop to process the command and then go back to listening. for the next command.

void RecieveMessage() {
  Serial.println("listening");
  while (1) {
if (mySerial.find("+CMT: \"")){
nor =mySerial.readString();
nors = nor.substring(0,(13));
Serial.println(nors);
mySerial.println(nor);

if(mySerial.find("SMS")){
  no1 = mySerial.readString();j=4;
  ProcessNumber();
    }else {   
if(mySerial.find("MSG")){no1 = mySerial.readString();j=3;
     ProcessNumber(); 
    }else {   
if(mySerial.find("SITE")) {no1 = mySerial.readString();
        Site();
      }else {
if(mySerial.find("STATUS")) {no1 = mySerial.readString();
        Status();
    }else {    
      Serial.println("Command not recognised, please try again");
      no1 = mySerial.readString();
        Unrecon();
    }
   }
  }
 }
}
  } //end while
}//end recieve messages function

it is then processed by

void ProcessNumber()
{
Serial.println(no1);
no2 =no1;
no2.remove(1);
delay(100);
int i = no2.toInt();
i=i-1;
// mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
mySerial.print("AT+CMGS=\"" + nors +"\"\n\r"); // Replace x with mobile number mySerial.println("AT+CMGS=\"xxxxx\"\n\r");

 if (no1.length()<14 && j==4){
      mySerial.print("Not enough numbers, try again");
      
}else{
   if (no1.length()>14){
   if (j==4){mySerial.print("Too many numbers, try again");
   }else if (j==3){
    mySerial.print("Too many characters, try again");} 
      
   }else{
  if (j==4){i=i;}else if (j==3){i=i+9;}
      if(j<=4){
      Serial.print("Saving variable string to address: ");
      Serial.println(i * 14);
      Serial.println(no1);
      myString = no1;
      myString.toCharArray(myStringChar, BUFSIZE); //convert string to char array
      strcpy(buf, myStringChar);
      eeprom_write_string((i * 14), buf);
      Serial.print("Reading string from address : ");
      Serial.println(i * 14);
      eeprom_read_string((i * 14), buf, BUFSIZE);
      Serial.println(buf);
      if (j==4){mySerial.print("Number ");i=i;}
        else if (j==3){mySerial.print("Message "); i=i-9;}
      mySerial.print(i+1);
      mySerial.print(": ");
      no1s = no1.substring(1,(12));
      mySerial.print("Stored as: ");
      mySerial.print(no1s);
      
  }else{
mySerial.print("Only allowed 5 Numbers");


}mySerial.println((char)26);// ASCII code of CTRL+Z
  RecieveMessage();}}
}

// eventually all the recieved messages will be processed in the process number code above.

I am still looking into the loops and only been able to get the code to recieve infinite commands via SMS for SMS only and then nothing for MSG, not posted this code as still trying to work out why the loop sor of works but only processes te one command type.

You have mangled the code tags, so your post is nearly impossible to read.

You do NOT have an unlimited amount of memory, so your desire to save an unlimited amount of data is unrealistic.

Your code is littered with (useless) (parentheses), missingspaces, multiple statement on one line, and other things that make it difficult to read.

You did not post all of your code.

Without showing ALL of your properly formatted code, and providing a decent description of the problem, you can’t expect us to help you.

Remove all usage of the "String" class.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

When using Cstrings you must use strcmp() to compare values rather than ==

If you need more help please post a complete program. Add the .ino file as an attachment if it is too long - but hopefully it won't be.

...R

When using Cstrings you must use strcmp() to compare values rather than ==

Except that OP is only sending single characters, so there is no reason to use an array at all.

okay I will post all the code later out and about at the minute. it doesnt store unlimited data, it needs to be able to process it, although once setup its unlikely to change much at all.

currently it would store in eeprom 5 numbers 4 messages, and a SITE ID.

the current code only recieves upto 7 commands via SMS before it flakes out.

to first program the information required I would need to send a minimum pf 10 SMS commands.

SMS1.xxxxx to SMS5..... MSG1.xxxx to MSG4 SITE ID

these can be requested in STATUS command but that isnt storing any data. its just recalling all stored data.

the issue is CMDs being recieved that are sent bySMS seems to have a limit, rather than there shouldnt be a limit to how many cmds can be received.

currently to program the unit with the details required, i would have to reboot the unit once ie & + 7 commands giving me 4 spare.

ie 5 + 4 + 1 command, but I can only send 7 with it flaking out.

but I can only send 7 with it flaking out.

Arduinos do not "flake out". You REALLY need to describe what it ACTUALLY does without resorting to colorful, but completely useless, jargon.

Thanks

will update this also with a very specific explanation to describe nothing as it was.

Pictures maybe better but that may not be possible.

I send a command the system responds and tells me it's stored the data via a return SMS, send 7 and 8th doesn't seem to register or return anything.

Restart the unit or serial monitor it will start again.

Suggesting it's got to the end and then stopped?

When something works and then stops working after a while, memory is most likely the issue with arduino's. Using "String" is a problem - but you are not posting all your code, so for now memory-issues related to the usage of the "String" class is the best guess.

current code works as follows:-

on opening serial monitor:-

 /// whilst this isn't code its output thought it make sense to make it scrollable?
AT+DDET=1
OK
AT+GMD=1,4
OK

On pressing r, it opens RecieveMessage() and displays:-


Listening


From Mobile SEND SMS MSG1abcdefghij1 to 9  we get the following:-


listening
+4478xxxxxxxx
1abcdefghij1

1
1abcdefghij1

14
Saving variable string to address: 126
1abcdefghij1


Reading string from address : 126
1abcdefghij1


+
Command not recognised, please try again

listening
+447815698180
Command not recognised, please try again

listening
+4478xxxxxxxx
1abcdefghij2

1
1abcdefghij2
14
Saving variable string to address: 126
1abcdefghij2


Reading string from address : 126
1abcdefghij2

etc etc up till:-
+4478xxxxxxxx
1abcdefghij6

1
1abcdefghij6

14
Saving variable string to address: 126
1abcdefghij6


Reading string from address : 126
1abcdefghij6

listening
+44781xxxxxxx
1abcdefghij7


1
1abcdefghij7


14
Saving variable string to address: 126
1abcdefghij7


Reading string from address : 126
1abcdefghij7
listening
+                                                                   //at the point MSG1abcdefghij8 is submited
Command not recognised, please try again

listening
+44781xxxxxx                                              //at the point MSG1abcdefghij9 is submited
Command not recognised, please try again

listening

note as its the same command it saves to the same address ie MSG1 saves to 126, it moves on if I use MSG2.... etc etc, but the max number of SMS's sent before it falls over is 7.

doesn't matter if I mix the commands with SMS instead of MSG, just the storage points change.

Please note all the code below is not finished, the processes involved in this case are

RecieveMessage(); then followed by ReturnMessage(); then back to RecieveMessage() ;

code in next post, be aware some code may be duplicated in seperate functions, but will be merged at a later point.

The "String" class is your biggest problem, so remove any use of it. Another thing that may become a problem is the excessive use of EEPROM write's - after 100.000 writes, EEPROM cells will be worn out. AFAICT you application and coding is more aimed at a Raspberry Pi than it is an Arduino - but with the right changes it will work with an arduino! :)

Maybe I am finding this a little too confusing at present.

The data needs permanently storing: so what are the options?

As for working the closest I have it to working, is it being limited to 7 commands being sent and being processed properly then it stops.

so I need the data to be read and processed every time its sent, but it must be permanently stored as it.

What is the issue with String? the code currently only occupies just over a third of the space available and the variables under half, although some of the strings will be easier to get rid of than others.

As there is too much code, due to duplication, I will simplify tomorrow probably, however I am interested in as to what you think I need to be looking as viable alternatives to what I have so far.

Removing your source code is not getting you any help.. The MMU (or the lack thereof) on an Arduino is very crude and it is not good at handling dynamic memory usage. For long term stability you should allocate all the memory you need before the "setup()" function completes. All memory allocated during the "loop()" phase requires expert knowledgement of how the memory on an Arduino works. The "String thing" uses dynamic memory "uncontrollably" and even an expert may not be able to use it without running into problems.

The data needs permanently storing: so what are the options?

Depends on how much data you need to permanently store. The builtin EEPROM isn't very big. An SD card is many orders of magnitude larger.

What is the issue with String?

Mostly, the fact that you do NOT know whether any given instance of the String class actually allocated the required memory to append the new data to the existing instance. The fact that all that dynamic memory allocation takes place, with little memory, means that you can end up not being able to allocate the required amount of memory. On a larger system, that would result in an exception being thrown. On the Arduino, exception handling consists of "Forget it. It wasn't that important".

however I am interested in as to what you think I need to be looking as viable alternatives to what I have so far.

Mostly what WE are interested in is the code you haven't posted. You CAN attach your code if it exceeds the 9000 character limit.

PaulS: Mostly what WE are interested in is the code you haven't posted.

In fact he did post the entire code (Sigh.. 13 global instances of String and all the local ones on top of that), but he removed it again for some reason. I guess he is part of The Lone Gunmen which causes his code to be clandestine. LOL! :-/

I haven't posted all the code because it was too long at the time.... over 9000 character warning, 5 minute warning, 30 second warning got my well and truly fried and time for a break and refuelling, not all of us are super human.

as I can only post every 5 mins splittng got messy etc etc. (excuses but fact) so appeared and disappeared some it certainly did.

as for the strings, yes there were lots of them but in reality some of them werent in use and I just hadn't got round to cleaning up properly (bad I know).

as for the strings, yes there were lots of them but in reality some of them werent in use and I just hadn't got round to cleaning up properly (bad I know).

I don't understanding creating anything - arrays, Strings, or any type variable - until you NEED it. If you don't create horseshit in the first place, you don't need a shovel to clean it up later.

If the program is too long then just add the .ino file as an attachment.

...R

Sorry about the delay.

#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial mySerial(7, 8);
String nors;
String nor;
String sig;
String no1;
String no2;

const int EEPROM_MIN_ADDR = 0;
const int EEPROM_MAX_ADDR = 1023;
boolean eeprom_is_addr_ok(int addr) {
  return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}
boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
  // counter
  int i;
  if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
    return false;
  }
  for (i = 0; i < numBytes; i++) {
    EEPROM.update(startAddr + i, array[i]);
  }
  return true;
}
boolean eeprom_write_string(int addr, const char* string) {
  int numBytes; // actual number of bytes to be written
  //write the string contents plus the string terminator byte (0x00)
  numBytes = strlen(string) + 1;
  return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}
boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
  byte ch; // byte read from eeprom
  int bytesRead; // number of bytes read so far
  if (!eeprom_is_addr_ok(addr)) { // check start address
    return false;
  }

  if (bufSize == 0) { // how can we store bytes in an empty buffer ?
    return false;
  }

  // is there is room for the string terminator only, no reason to go further
  if (bufSize == 1) {
    buffer[0] = 0;
    return true;
  }
  bytesRead = 0; // initialize byte counter
  ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
  buffer[bytesRead] = ch; // store it into the user buffer
  bytesRead++; // increment byte counter

  while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
    // if no stop condition is met, read the next byte from eeprom
    ch = EEPROM.read(addr + bytesRead);
    buffer[bytesRead] = ch; // store it into the user buffer
    bytesRead++; // increment byte counter
  }
  if ((ch != 0x00) && (bytesRead >= 1)) {
    buffer[bytesRead - 1] = 0;
  }
  return true;
}

const int BUFSIZE = 13;
char buf[BUFSIZE];
String myString;
char myStringChar[BUFSIZE];
String strip;
int i;
int j;
void setup()
{
  mySerial.begin(57600);   // Setting the baud rate of GSM Module
  Serial.begin(57600);    // Setting the baud rate of Serial Monitor (Arduino)
  delay(100);
  mySerial.println("AT+DDET=1");
  delay(100);
  mySerial.println("AT+CMGD=1,4");
  mySerial.println("AT+CSQ");
}
void loop()
{
  if (Serial.available() > 0)
    switch (Serial.read())
    {
      case'd':
        DialCall();
        break;
      
      case'r':
        RecieveMessage();
        break;
    }

  if (mySerial.available() > 0)
    Serial.write(mySerial.read());

}


void ReturnMessage()
{
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(100);
  mySerial.flush();
  Serial.flush();
  RecieveMessage();
}


void ProcessNumber()
{
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.print("AT+CMGS=\"" + nors +"\"\n\r"); // Replace x with mobile number mySerial.println("AT+CMGS=\"xxxxx\"\n\r");

const int BUFSIZE = 13;
char buf[BUFSIZE];
String myString;
char myStringChar[BUFSIZE];
String strip;

Serial.println(no1);
no2 =no1;
no2.remove(1);
Serial.println(no2);
Serial.println(no1);
Serial.println(no1.length());

int i = no2.toInt();
i=i-1;
if (i>=0){
     if (no1.length()<14){
     mySerial.print("Not enough numbers, try again");
      ReturnMessage();
     }else{
   if (no1.length()>14){
    if(j==1){mySerial.print("Too many numbers, try again");}
    if(j==2){mySerial.print("Too many characters, try again");}
      ReturnMessage();     
}else{
  if (j==1){i=i;}else{if(j==2)i=i+9;}
      Serial.print("Saving variable string to address: ");
      Serial.println(i * 14);
      Serial.println(no1);
      myString = no1;
      myString.toCharArray(myStringChar, BUFSIZE); //convert string to char array
      strcpy(buf, myStringChar);
      eeprom_write_string((i * 14), buf);
      Serial.print("Reading string from address : ");
      Serial.println(i * 14);
      eeprom_read_string((i * 14), buf, BUFSIZE);
      Serial.println(buf);
      if (j==1){i=i+1;mySerial.print("Number ");}else{if(j==2)i=i-8;mySerial.print("Message ");}
      mySerial.print(i);
      mySerial.print(" ");
      mySerial.print("Stored as: ");
      mySerial.print(no1.substring(1,(12)));
      ReturnMessage();}}
}else{

ReturnMessage();
}}
void Site() {
const int BUFSIZE = 20;
char buf[BUFSIZE];
String myString;
char myStringChar[BUFSIZE];
String strip;
//int i;
mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
 Serial.println("SITE details submitted");
 Serial.print("Saving variable string to address: ");
      Serial.println(100);
      Serial.println(no1);
      myString = no1;
      myString.toCharArray(myStringChar, BUFSIZE); //convert string to char array
      strcpy(buf, myStringChar);
      eeprom_write_string((100), buf);
      Serial.print("Reading string from address : ");
      Serial.println(100);
      eeprom_read_string((100), buf, BUFSIZE);
      Serial.println(buf);
      delay(1000);  // Delay of 1000 milli seconds or 1 second
      mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
       mySerial.print("AT+CMGS=\"" + nors +"\"\n\r"); // Replace x with mobile number mySerial.println("AT+CMGS=\"xxxxx\"\n\r");
  mySerial.print("SITE ID RECORDED AS: ");
  mySerial.print(buf);  
      ReturnMessage(); 
}

void RecieveMessage() {
  mySerial.println("AT+CMGF=1\r");
  mySerial.println("AT+CNMI=2,2,0,0,0\r"); // AT Command to recieve a live SMS
  Serial.println();
  Serial.println("listening");
  while (1) {
if (mySerial.find("+CMT: \"")){
nor =mySerial.readString();
nors = nor.substring(0,(13));
Serial.println(nors);
mySerial.println(nor);

if(mySerial.find("SMS")){
  no1 = mySerial.readString();
  j=1;
     ProcessNumber();
    }else {   
      mySerial.println(nor);
      if(mySerial.find("SITE")) {
      no1 = mySerial.readString();
        Site();
    }else {   
      mySerial.println(nor);
     if(mySerial.find("MSG")){
      j=2;
  no1 = mySerial.readString();
     ProcessNumber();
      }else {
     mySerial.println(nor);
      if(mySerial.find("STATUS")) {
      no1 = mySerial.readString();
        Status();
    }else {    
      mySerial.println(nor);
      Serial.println("Command not recognised, please try again");
      no1 = mySerial.readString();
        Unrecon();
    }
   }
  }
 }
}
  } //end while
}//end recieve messages function

void DialCall()
{
  eeprom_read_string(0, buf, BUFSIZE);
  Serial.println(buf);
  no1 = buf;
  no1.remove(0,1);
  mySerial.println("ATD" + no1 + ";"); // ATDxxxxxxxxxx; -- watch out here for semicolon at the end!!"ATD07815698180;"
  delay(100);
  
  while (1) {
    if (mySerial.find("+DTMF:")) {
      int cmd = mySerial.parseInt();
      mySerial.flush();
Serial.println(cmd);
      switch (cmd) {
        
        case 0:
          Serial.println("Call Acknowledged and Terminated");
          delay(10);
          mySerial.println("ATH");
          break;
      }
    }
  }
}

void Unrecon(){
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
 

  mySerial.print("AT+CMGS=\"" + nors +"\"\n\r"); // Replace x with mobile number mySerial.println("AT+CMGS=\"xxxxx\"\n\r");
mySerial.println("Command not recoginised. ");
mySerial.println("Please try again");
  ReturnMessage(); 
  }

void  Status()
{
  mySerial.println("AT+CSQ");
  if(mySerial.find("+CSQ: ")){
  sig = mySerial.readString();
}
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second

  mySerial.print("AT+CMGS=\"" + nors +"\"\n\r"); // Replace x with mobile number mySerial.println("AT+CMGS=\"xxxxx\"\n\r");
 mySerial.print("SITE ID : ");
 eeprom_read_string((100), buf, BUFSIZE);
 mySerial.print(buf);
 mySerial.println();
  int i;
  for (i = 0; i < 5; i++) {
    mySerial.print("Telephone No:");
    mySerial.print(i + 1);
    mySerial.print(": ");
    eeprom_read_string((i * 14), buf, BUFSIZE);
    no1 =(buf);
    no1.remove(0,1);
    mySerial.println(no1); }

  for (i = 0; i < 4; i++) {
    mySerial.print("Message No:");
    mySerial.print(i + 1);
    mySerial.print(": ");
    eeprom_read_string(((i+9) * 14), buf, BUFSIZE);
    no1 =(buf);
    no1.remove(0,1);
    mySerial.println(no1); }

mySerial.print("Signal Strength: "+sig);
 ReturnMessage();
}

Please use the AutoFormat tool to indent your program for easier reading. As it is it is too difficult to see which parts belong together.

...R