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: yy0円
char rtcm1[3]; // Current month Format: mm0円
char rtcd1[3]; // Current day Format: dd0円
char rtch1[3]; // Current hour Format: hh0円
char rtcmm1[3]; // Current minute Format: mm0円
char rtcs1[3]; // Current second Format: ss0円
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

ocrdu
1,7953 gold badges12 silver badges24 bronze badges
asked May 1, 2018 at 16:02

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.

answered May 1, 2018 at 16:05
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: yy0円
char rtcm1[3]; //Current month Format: mm0円
char rtcd1[3]; //Current day Format: dd0円
char rtch1[3]; //Current hour Format: hh0円
char rtcmm1[3]; //Current minute Format: mm0円
char rtcs1[3]; //Current second Format: ss0円
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();
 }
}
answered May 1, 2018 at 21:24

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.