0

I am trying to make a program that receives commands contained in SMS. The commands can be $CMD1 and $CMD2. Of course I need to verify the phone number of the sender by its last 6 digits. Other than this I have to ask and receive rtc clock information from the modem. AT commands format: +CCLK: "YY/MM/DD,HH:MM:SS+TT" (works properly) +CMTI: "SM",N (where N is the index number of the sms in the phone mem) +CMGR: "REC READ","+1234567890","","04/01/01,00:00:00+00" (it reaches only the 15th char and hangs)

My code:

const long interval = 1000;
static long currentMillis;

byte searchcharpos = 0; //To determine where is the + in +CCLK in the char array

char serialdata[256]; //Array to store the chars before parsing

char rtcy1[3]; //Current year  Format: yy\0
char rtcm1[3]; //Current month  Format: mm\0
char rtcd1[3]; //Current day  Format: dd\0
char rtch1[3]; //Current hour  Format: hh\0
char rtcmm1[3]; //Current minute  Format: mm\0
char rtcs1[3]; //Current second  Format: ss\0

char esemesemes[3];

byte pointingfinger = 0;

char enabledtime = 0;

char cclkenabl = 0;

char foundchar[6];

byte cmtienabl = 0;

byte witdqt = 0;

byte acceptsms = 0;

byte ocpos = 0;

byte occurence = 0;

byte cmgrenabl = 0;

byte esemindex[3];

char phone1[6] = {'5', '6', '7', '8', '9', '0'};

char phone2[6];

byte enableclock = 1;

void setup() {
  Serial.begin(9600); //USB to Computer
  Serial1.begin(9600); //UART to Modem
  Serial1.print("ATE0\r"); //Disable echo
}

void loop() {
  if (millis() - currentMillis >= interval) //This is done every second
  {
    if (enableclock == 1) {
      Serial1.print("AT+CCLK?\r");
    }
    Serial.println("=========");
    Serial.print(serialdata[searchcharpos]);
    Serial.print(serialdata[searchcharpos + 1]);
    Serial.print(serialdata[searchcharpos + 2]);
    Serial.print(serialdata[searchcharpos + 3]);
    Serial.print(serialdata[searchcharpos + 4]);
    Serial.print(serialdata[searchcharpos + 5]);
    Serial.print(serialdata[searchcharpos + 6]);
    Serial.print(serialdata[searchcharpos + 7]);
    Serial.print(serialdata[searchcharpos + 8]);
    Serial.print(serialdata[searchcharpos + 9]);
    Serial.print(serialdata[searchcharpos + 10]);
    Serial.print(serialdata[searchcharpos + 11]);
    Serial.print(serialdata[searchcharpos + 12]);
    Serial.print(serialdata[searchcharpos + 13]);
    Serial.print(serialdata[searchcharpos + 14]);
    Serial.print(serialdata[searchcharpos + 15]);
    Serial.print(serialdata[searchcharpos + 16]);
    Serial.print(serialdata[searchcharpos + 17]);
    Serial.print(serialdata[searchcharpos + 18]);
    Serial.print(serialdata[searchcharpos + 19]);
    Serial.print(serialdata[searchcharpos + 20]);
    Serial.print(serialdata[searchcharpos + 21]);
    Serial.print(serialdata[searchcharpos + 22]);
    Serial.print(serialdata[searchcharpos + 23]);
    Serial.print(serialdata[searchcharpos + 24]);
    Serial.print(serialdata[searchcharpos + 25]);
    Serial.print(serialdata[searchcharpos + 26]);
    Serial.print(serialdata[searchcharpos + 27]);
    Serial.print(serialdata[searchcharpos + 28]);
    Serial.print(serialdata[searchcharpos + 29]);
    Serial.print(serialdata[searchcharpos + 30]);
    Serial.print ("=========");
    //Serial1.print("AT+CCLK?\r"); //ask for the time
    //delay(50);
    Serial.println("");
    Serial.println("=====");
    Serial.println(millis());

    if (enableclock == 1) {
      Serial.println("YEAR: ");
      Serial.print(rtcy1[0]);
      Serial.println(rtcy1[1]);
      Serial.println("MONTH: ");
      Serial.print(rtcm1[0]);
      Serial.println(rtcm1[1]);
      Serial.println("DAY: ");
      Serial.print(rtcd1[0]);
      Serial.println(rtcd1[1]);
      Serial.println("HOUR: ");
      Serial.print(rtch1[0]);
      Serial.println(rtch1[1]);
      Serial.println("MINUTE: ");
      Serial.print(rtcmm1[0]);
      Serial.println(rtcmm1[1]);
      Serial.println("SECOND: ");
      Serial.print(rtcs1[0]);
      Serial.println(rtcs1[1]);
    }
    enabledtime = 1;

    currentMillis = millis();
  }

  if (enabledtime == 1) {
    if (Serial1.available () > 0) {
      foundchar[0] = foundchar[1];
      foundchar[1] = foundchar[2];
      foundchar[2] = foundchar[3];
      foundchar[3] = foundchar[4];
      foundchar[4] = foundchar[5];
      foundchar[5] = Serial1.read();

      if (foundchar[0] == '+' && foundchar[1] == 'C' && foundchar[2] == 'C' && foundchar[3] == 'L' && foundchar[4] == 'K' && foundchar[5] == ':' && enableclock == 1) {
        cclkenabl = 1;
        pointingfinger = 0;
      }

      if (foundchar[0] == '+' && foundchar[1] == 'C' && foundchar[2] == 'M' && foundchar[3] == 'T' && foundchar[4] == 'I' && foundchar[5] == ':') {
        cmtienabl = 1;
        pointingfinger = 0;
        enableclock = 0;
      }

      if (foundchar[0] == '+' && foundchar[1] == 'C' && foundchar[2] == 'M' && foundchar[3] == 'G' && foundchar[4] == 'R' && foundchar[5] == ':') {
        cmgrenabl = 1;
        pointingfinger = 0;
      }

      if (foundchar[0] == '$' && foundchar[1] == 'C' && foundchar[2] == 'M' && foundchar[3] == 'D' && foundchar[4] == '1') {
        if (acceptsms == 1) {
          while (true) {
            Serial.println("CMD1");
          }
        }
      }

      if (foundchar[0] == '$' && foundchar[1] == 'C' && foundchar[2] == 'M' && foundchar[3] == 'D' && foundchar[4] == '2') {
        if (acceptsms == 1) {
          Serial.println("CMD2");
        }
      }

      if (cclkenabl == 1) {
        while (foundchar[0] != '\n') {
          if (Serial1.available() > 0) {
            serialdata[pointingfinger] = foundchar[0];
            serialdata[pointingfinger + 1] = 0;
            pointingfinger++;
            foundchar[0] = foundchar[1];
            foundchar[1] = foundchar[2];
            foundchar[2] = foundchar[3];
            foundchar[3] = foundchar[4];
            foundchar[4] = foundchar[5];
            foundchar[5] = Serial1.read();

          }
        }
        cmgrenabl = 0;
        cclkenabl = 0;
        //pointingfinger = 0;
        enabledtime = 0;
        rtcy1[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
        rtcy1[1] = serialdata[searchcharpos + 9];
        rtcy1[2] = '\0';
        rtcm1[0] = serialdata[searchcharpos + 11];
        rtcm1[1] = serialdata[searchcharpos + 12];
        rtcm1[2] = '\0';
        rtcd1[0] = serialdata[searchcharpos + 14];
        rtcd1[1] = serialdata[searchcharpos + 15];
        rtcd1[2] = '\0';
        rtch1[0] = serialdata[searchcharpos + 17];
        rtch1[1] = serialdata[searchcharpos + 18];
        rtch1[2] = '\0';
        rtcmm1[0] = serialdata[searchcharpos + 20];
        rtcmm1[1] = serialdata[searchcharpos + 21];
        rtcmm1[2] = '\0';
        rtcs1[0] = serialdata[searchcharpos + 23];
        rtcs1[1] = serialdata[searchcharpos + 24];
        rtcs1[2] = '\0';
      }

      if (cmtienabl == 1) {
        while (foundchar[0] != '\n') {
          if (Serial1.available() > 0) {
            serialdata[pointingfinger] = foundchar[0];
            serialdata[pointingfinger + 1] = 0;
            pointingfinger++;
            foundchar[0] = foundchar[1];
            foundchar[1] = foundchar[2];
            foundchar[2] = foundchar[3];
            foundchar[3] = foundchar[4];
            foundchar[4] = foundchar[5];
            foundchar[5] = Serial1.read();

          }
        }
        cmtienabl = 0;
        //pointingfinger = 0;
        enabledtime = 0;
        enableclock = 0;
        esemesemes[0] = serialdata[searchcharpos + 8]; //getting first char with its offset
        esemesemes[1] = serialdata[searchcharpos + 9];
        esemesemes[2] = '\0';
        esemindex[0] = serialdata[searchcharpos + 12];
        esemindex[1] = '\0';
        Serial.println("CMTI");
        Serial.println(esemesemes[0]);
        Serial.println(esemesemes[1]);
        Serial.println(esemindex[1]);
        if (esemesemes[0] == 'S' && esemesemes[1] == 'M') {
          Serial1.println("AT+CMGF=1");
          Serial.println("AT+CMGF=1");
          delay(100);
          Serial1.println("AT+CMGR=1");
          Serial.println("AT+CMGR=1");
        }
        if (esemesemes[0] != 'S' || esemesemes[1] != 'M') {
          Serial1.println("AT+CMGD=4,1");
          Serial.println("Deleted");
        }
      }

      if (cmgrenabl == 1) {
        while (foundchar[0] != '\n') {
          if (Serial1.available() > 0) {
            serialdata[pointingfinger] = foundchar[0];
            serialdata[pointingfinger + 1] = 0;
            pointingfinger++;
            foundchar[0] = foundchar[1];
            foundchar[1] = foundchar[2];
            foundchar[2] = foundchar[3];
            foundchar[3] = foundchar[4];
            foundchar[4] = foundchar[5];
            foundchar[5] = Serial1.read(); //                       I THINK HERE WE HAVE SOME PROBLEM
            Serial.println("Searching");
            Serial.println(serialdata[pointingfinger]);
            Serial.println(pointingfinger);
            Serial.print(serialdata[searchcharpos]);
            Serial.print(serialdata[searchcharpos + 1]);
            Serial.print(serialdata[searchcharpos + 2]);
            Serial.print(serialdata[searchcharpos + 3]);
            Serial.print(serialdata[searchcharpos + 4]);
            Serial.print(serialdata[searchcharpos + 5]);
            Serial.print(serialdata[searchcharpos + 6]);
            Serial.print(serialdata[searchcharpos + 7]);
            Serial.print(serialdata[searchcharpos + 8]);
            Serial.print(serialdata[searchcharpos + 9]);
            Serial.print(serialdata[searchcharpos + 10]);
            Serial.print(serialdata[searchcharpos + 11]);
            Serial.print(serialdata[searchcharpos + 12]);
            Serial.print(serialdata[searchcharpos + 13]);
            Serial.print(serialdata[searchcharpos + 14]);
            Serial.print(serialdata[searchcharpos + 15]);
            Serial.print(serialdata[searchcharpos + 16]);
            Serial.print(serialdata[searchcharpos + 17]);
            Serial.print(serialdata[searchcharpos + 18]);
            Serial.print(serialdata[searchcharpos + 19]);
            Serial.print(serialdata[searchcharpos + 20]);
            Serial.print(serialdata[searchcharpos + 21]);
            Serial.print(serialdata[searchcharpos + 22]);
            Serial.print(serialdata[searchcharpos + 23]);
            Serial.print(serialdata[searchcharpos + 24]);
            Serial.print(serialdata[searchcharpos + 25]);
            Serial.print(serialdata[searchcharpos + 26]);
            Serial.print(serialdata[searchcharpos + 27]);
            Serial.print(serialdata[searchcharpos + 28]);
            Serial.print(serialdata[searchcharpos + 29]);
            Serial.print(serialdata[searchcharpos + 30]);
          }
        }
        //pointingfinger = 0;
        enabledtime = 1;
        occurence = 0;
        ocpos = 0;
        Serial.println("mode1");
        while (occurence < 7) {
          Serial.println("mode2");
          if (serialdata[ocpos] == '\"') {
            Serial.println("mode3");
            occurence++;
            Serial.println(occurence);
          }
          Serial.println("mode4");
          ocpos++;
          Serial.println(ocpos);
        }
        witdqt = ocpos;
        Serial.println("PHONE1: ");
        Serial.print(serialdata[witdqt - 1]);
        Serial.print(serialdata[witdqt - 2]);
        Serial.print(serialdata[witdqt - 3]);
        Serial.print(serialdata[witdqt - 4]);
        Serial.print(serialdata[witdqt - 5]);
        Serial.print(serialdata[witdqt - 6]);
        Serial.println("");
      }
      acceptsms = 0;

      if (serialdata[witdqt - 1] == phone1[5] && serialdata[witdqt - 2] == phone1[4] && serialdata[witdqt - 3] == phone1[3] && serialdata[witdqt - 4] == phone1[2] && serialdata[witdqt - 5] == phone1[1] && serialdata[witdqt - 6] == phone1[0])
      {
        acceptsms = 1;
        Serial.println("Accepted");
      }

      if (serialdata[witdqt - 1] == phone2[5] && serialdata[witdqt - 2] == phone2[4] && serialdata[witdqt - 3] == phone2[3] && serialdata[witdqt - 4] == phone2[2] && serialdata[witdqt - 5] == phone2[1] && serialdata[witdqt - 6] == phone2[0])
      {
        acceptsms = 1;
        Serial.println("Accepted");
      }

      /*Serial.println("");
        Serial.print(foundchar[0]);
        Serial.print(foundchar[1]);
        Serial.print(foundchar[2]);
        Serial.print(foundchar[3]);
        Serial.print(foundchar[4]);
        Serial.print(foundchar[5]);
        Serial.println("");*/

    }
  }
}

This is the Serial Monitor: enter image description here

15
  • 1
    What is the exact question? You presented your project and your code. You want code for general AT command parsing? Commented May 13, 2018 at 10:18
  • 2
    That is the most bizarre serial parsing code I have ever seen. You're not making life easy on yourself with that stuff... Commented May 13, 2018 at 10:34
  • 1
    This might help you to write better parsing code: hackingmajenkoblog.wordpress.com/2016/02/01/… and hackingmajenkoblog.wordpress.com/2017/04/08/… Commented May 13, 2018 at 10:37
  • 1
    I also cannot comprehend that parsing code. You might want to start working on a general ATCmdParser like mbed-os has or look at the parsing code from other libraries which receive AT commands (example) Commented May 13, 2018 at 10:39
  • 1
    Or, in short: Read an entire line into the buffer, and only once the line is complete do you analyse it and decide what to do with it. A sliding window is not what you want for line-based ASCII communication. Commented May 13, 2018 at 10:40

1 Answer 1

2

You should throw away all your own code and read the serial data in a line at a time. Only once a complete line has been received should you then examine it to see what you have.

For example, here's something I just threw together based around a snippet I posted here:

int readline(int readch, char *buffer, int len) {
  static int pos = 0;
  int rpos;

  if (readch > 0) {
    switch (readch) {
      case '\r': // Ignore CR
        break;
      case '\n': // Return on new-line
        rpos = pos;
        pos = 0;  // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
            buffer[pos++] = readch;
            buffer[pos] = 0;
        }
        break;
    }
  }
  return 0;
}

// ... later, in your loop:

if (Serial1.available()) {
    // Read one character and send it to the readline function.
    if (readline(Serial1.read(), serialdata, 512)) { // do you really need 512 bytes of buffer?!?!

        // readline() told us we got a valid string. Let's
        // parse it.

        // If the string starts with '+CCLK: "'    
        if (strncmp(serialdata, "+CCLK: \"", 8) == 0) {
            // Slice it up by the different delimiters
            // starting at the 9th character:
            char *cyear = strtok(serialdata + 8, "/");
            char *cmonth = strtok(NULL, "/");
            char *cday = strtok(NULL, ",");
            char *chour = strtok(NULL, ":");
            char *cmin = strtok(NULL, ":");
            char *csec = strtok(NULL, "+");

            // Check the last slicing worked
            if (sec != NULL) { // It parsed OK
                // And convert each slice to a number.
                year = atoi(cyear);
                month = atoi(cmonth);
                day = atoi(cday);
                hour = atoi(chour);
                minute = atoi(cmin);
                sec = atoi(csec);

                // Show the time.
                Serial.print(F("The time is "));
                Serial.print(minute);
                Serial.print(F(" minutes past "));
                Serial.println(hour);
            }     
        }
    }

    // Do similar operations for the different possible messages
    // you may get.

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.