Arduino получает ответ от SIM800H на AT+CCLK? команда

Я пытался создать программу, которая взаимодействует с SIM800H с помощью AT-команд. Он работал с классом String, но был полон "утечек памяти" и через несколько часов просто зависал. Затем я попытался написать его снова с массивами символов, но по какой-то причине мне не удалось заставить его работать должным образом.

Может ли кто-нибудь предложить мне поправку к моей программе, а также способ получения char за char с помощью цикла и Serial.read();? Serial в данном случае (Arduino Leonardo) — это USB-порт, а Serial1 — это порт модема.

Вот мой код:

const long interval = 2000;
static long currentMillis;

char wherecclk = 0; //Чтобы определить, где находится + в +CCLK в массиве символов

char serialdata[256] = ""; // Массив для хранения символов перед синтаксическим анализом

char rtcy1[3]; // Текущий год Формат: гг\0
char rtcm1[3]; //Текущий месяц Формат: мм\0
char rtcd1[3]; // Текущий день Формат: дд\0
char rtch1[3]; //Текущий час Формат: чч\0
char rtcmm1[3]; //Текущая минута Формат: мм\0
char rtcs1[3]; //Текущая секунда Формат: ss\0

int rdpos = 0;

void setup() {
    Serial.begin(9600); //USB к компьютеру
    Serial1.begin(9600); //UART к модему
    Serial1.print("ATE0\r"); //Отключить эхо
}

void loop() {
    wherecclk = 0;
    if (Serial1.available () > 0) { // когда что-то приходит на реальный серийный номер
        strcpy(serialdata, "OK\n\n+CCLK: \"04/01/01,01:35:31+00\"\n\nOK\n"); //Это реальный образец ответа от эмулируемого модема
        while (rdpos < 256) // время ожидания цикла: 256 байт
        {
            if (serialdata[rdpos] == '+') {
                break; //Мы достигли первого + char. Прекратите увеличивать его
            }
            rdpos++;
        }
        if (serialdata[rdpos + 1] == 'C' && serialdata[rdpos + 2] == 'C' && serialdata[rdpos + 3] == 'L' && serialdata[rdpos + 4] == 'K') { //Если последовательная команда соответствует +CCLK, сохранить свою позицию
            wherecclk = rdpos;
        }
        rdpos = 0;

        if (wherecclk != 0) {
            rtcy1[0] = serialdata[wherecclk + 8]; //получение первого символа с его смещением
            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) // Это делается каждую секунду
    {
        Serial1.print("AT+CCLK?\r"); // спрашиваем время
        // задержка (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();
    }
}

Вот результат (скриншот, потому что последовательный монитор не дает мне полный код):

последовательный монитор

, 👍2


2 ответа


Лучший ответ:

2

Вы объявляете переменные для месяца и минуты по-разному (rtcm1[3] и rtcm1[3]), но загружаете rtcm1 с месяц, а затем несколькими строками позже, с минутами.

,

Дурак я! Наверное, я проглядел опечатку и подумал, что это какая-то другая ошибка., @A. Somov


1

Вот окончательный код на случай, если он кому-то понадобится:

const long interval = 1000;
static long currentMillis;

char wherecclk = 0; //Чтобы определить, где находится + в +CCLK в массиве символов

char serialdata[256] = ""; // Массив для хранения символов перед синтаксическим анализом

char rtcy1[3]; // Текущий год Формат: гг\0
char rtcm1[3]; //Текущий месяц Формат: мм\0
char rtcd1[3]; // Текущий день Формат: дд\0
char rtch1[3]; //Текущий час Формат: чч\0
char rtcmm1[3]; //Текущая минута Формат: мм\0
char rtcs1[3]; //Текущая секунда Формат: ss\0

int rdpos = 0;

int pointingfinger = 0;

void setup() {
  Serial.begin(9600); //USB к компьютеру
  Serial1.begin(9600); //UART к модему
  Serial1.print("ATE0\r"); //Отключить эхо
}

void loop() {
  if (Serial1.available () > 0) { // когда что-то приходит на реальный серийный номер
    rdpos = 0;
    wherecclk = 0;
    if (pointingfinger == 255) {
      pointingfinger = 0;
    }

    serialdata[pointingfinger] = Serial1.read();

    while (rdpos < 256) // время ожидания цикла: 256 байт
    {
      if (serialdata[rdpos] == '+') {
        break; //Мы достигли первого + char. Прекратите увеличивать его
      }
      rdpos++;
    }
    if (serialdata[rdpos + 1] == 'C' && serialdata[rdpos + 2] == 'C' && serialdata[rdpos + 3] == 'L' && serialdata[rdpos + 4] == 'K') { //Если последовательная команда соответствует +CCLK, сохранить свою позицию
      wherecclk = rdpos;
    }

    pointingfinger++;
  }

  if (millis() - currentMillis >= interval) // Это делается каждую секунду
  {
    pointingfinger = 0;
    //Serial.println("=========");
    //Serial.println(serialdata);
    //Serial.println("=========");
    if (wherecclk != 0) {
      rtcy1[0] = serialdata[wherecclk + 8]; //получение первого символа с его смещением
      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"); // спрашиваем время
    // задержка (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();
  }
}
,