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):
