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 Answers 2

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.

1
  • Silly me! I guess I overlooked the typo and thought it's some other error Commented May 1, 2018 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();
  }
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.