2

I've been trying to make a program that interacts with SIM800H trough AT commands. It worked with the String class, but it was full of "memory leaks" and after a few hours it just hanged. Then I tried to write it again with char arrays, but for some reason I couldn't get it to work properly.

Can someone suggest me a correction to my program and also a way to get char by char with loop and Serial.read();? Serial in this case (Arduino Leonardo) is the USB port and Serial1 is the port to the modem.

Here is my code:

const long interval = 2000;
static long currentMillis;

char wherecclk = 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

int rdpos = 0;

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

void loop() {
    wherecclk = 0;
    if (Serial1.available () > 0) { //when something comes on real serial
        strcpy(serialdata, "OK\n\n+CCLK: \"04/01/01,01:35:31+00\"\n\nOK\n"); //This is a real sample of the response coming from the modem emulated
        while (rdpos < 256) //loop timeout: 256 bytes
        {
            if (serialdata[rdpos] == '+') {
                break; //We have reached the first + char. Stop incrementing it
            }
            rdpos++;
        }
        if (serialdata[rdpos + 1] == 'C' && serialdata[rdpos + 2] == 'C' && serialdata[rdpos + 3] == 'L' && serialdata[rdpos + 4] == 'K') { //If the serial command mathes +CCLK save its position
            wherecclk = rdpos;
        }
        rdpos = 0;

        if (wherecclk != 0) {
            rtcy1[0] = serialdata[wherecclk + 8]; //getting first char with its offset
            rtcy1[1] = serialdata[wherecclk + 9];
            rtcy1[2] = '\0';
            rtcm1[0] = serialdata[wherecclk + 11];
            rtcm1[1] = serialdata[wherecclk + 12];
            rtcm1[2] = '\0';
            rtcd1[0] = serialdata[wherecclk + 14];
            rtcd1[1] = serialdata[wherecclk + 16];
            rtcd1[2] = '\0';
            rtch1[0] = serialdata[wherecclk + 17];
            rtch1[1] = serialdata[wherecclk + 18];
            rtch1[2] = '\0';
            rtcm1[0] = serialdata[wherecclk + 20];
            rtcm1[1] = serialdata[wherecclk + 21];
            rtcm1[2] = '\0';
            rtcs1[0] = serialdata[wherecclk + 23];
            rtcs1[1] = serialdata[wherecclk + 24];
            rtcs1[2] = '\0';
        }

    }

    if (millis() - currentMillis >= interval) //This is done every second
    {
        Serial1.print("AT+CCLK?\r"); //ask for the time
        //delay(50);
        Serial.println("");
        Serial.println("=====");
        Serial.println(millis());

        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]);

        currentMillis = millis();
    }
}

Here is the output (a screenshot, because serial monitor doesn't give me full code):

serial monitor

2

You declare your variables for month and minute differently (rtcm1[3] vs rtcmm1[3]), but you load rtcm1 with month, and then a few lines later, with minutes.

  • Silly me! I guess I overlooked the typo and thought it's some other error – A. Somov May 1 '18 at 16:19
1

Here's the final code in case someone needs it:

const long interval = 1000;
static long currentMillis;

char wherecclk = 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

int rdpos = 0;

int pointingfinger = 0;

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

void loop() {
  if (Serial1.available () > 0) { //when something comes on real serial
    rdpos = 0;
    wherecclk = 0;
    if (pointingfinger == 255) {
      pointingfinger = 0;
    }

    serialdata[pointingfinger] = Serial1.read();

    while (rdpos < 256) //loop timeout: 256 bytes
    {
      if (serialdata[rdpos] == '+') {
        break; //We have reached the first + char. Stop incrementing it
      }
      rdpos++;
    }
    if (serialdata[rdpos + 1] == 'C' && serialdata[rdpos + 2] == 'C' && serialdata[rdpos + 3] == 'L' && serialdata[rdpos + 4] == 'K') { //If the serial command mathes +CCLK save its position
      wherecclk = rdpos;
    }

    pointingfinger++;
  }

  if (millis() - currentMillis >= interval) //This is done every second
  {
    pointingfinger = 0;
    //Serial.println("=========");
    //Serial.println(serialdata);
    //Serial.println("=========");
    if (wherecclk != 0) {
      rtcy1[0] = serialdata[wherecclk + 8]; //getting first char with its offset
      rtcy1[1] = serialdata[wherecclk + 9];
      rtcy1[2] = '\0';
      rtcm1[0] = serialdata[wherecclk + 11];
      rtcm1[1] = serialdata[wherecclk + 12];
      rtcm1[2] = '\0';
      rtcd1[0] = serialdata[wherecclk + 14];
      rtcd1[1] = serialdata[wherecclk + 15];
      rtcd1[2] = '\0';
      rtch1[0] = serialdata[wherecclk + 17];
      rtch1[1] = serialdata[wherecclk + 18];
      rtch1[2] = '\0';
      rtcmm1[0] = serialdata[wherecclk + 20];
      rtcmm1[1] = serialdata[wherecclk + 21];
      rtcmm1[2] = '\0';
      rtcs1[0] = serialdata[wherecclk + 23];
      rtcs1[1] = serialdata[wherecclk + 24];
      rtcs1[2] = '\0';
    }
    Serial1.print("AT+CCLK?\r"); //ask for the time
    //delay(50);
    Serial.println("");
    Serial.println("=====");
    Serial.println(millis());

    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]);

    currentMillis = millis();
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.