Arduino +CCLK при разборе команды

У меня есть arduino leonardo и модуль sim800h. Кажется, я не нашел проблему в своей программе, это, наверное, 5-й раз, когда я ее переписываю. Пожалуйста, кто-нибудь, скажите мне, что мне нужно изменить, чтобы она работала нормально. Я декодирую ответы, но некоторые символы, похоже, исчезают и иногда появляются снова. Со временем остается только +CCLK, все остальное исчезает. Также время должно обновляться все время, но секунды остаются прежними в течение 5-10 секунд.

Вот код:

const long interval = 200;
static long currentMillis;

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

char serialdata[256]; //Массив для хранения символов перед разбором

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

byte pointingfinger = 0;

char enabledtime = 0;

char readenabl = 0;

char foundchar[6];

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

void loop() {
  if (millis() - currentMillis >= interval) //Это делается каждую секунду
  {
    Serial1.print("AT+CCLK?\r");

    Serial.println("=========");
    Serial.print(serialdata[searchcharpos]);
    Serial.print(serialdata[searchcharpos + 1]);
    Serial.print(serialdata[searchcharpos + 2]);
    Serial.print(serialdata[searchcharpos + 3]);
    Serial.print(serialdata[searchcharpos + 4]);
    Serial.print(serialdata[searchcharpos + 5]);
    Serial.print(serialdata[searchcharpos + 6]);
    Serial.print(serialdata[searchcharpos + 7]);
    Serial.print(serialdata[searchcharpos + 8]);
    Serial.print(serialdata[searchcharpos + 9]);
    Serial.print(serialdata[searchcharpos + 10]);
    Serial.print(serialdata[searchcharpos + 11]);
    Serial.print(serialdata[searchcharpos + 12]);
    Serial.print(serialdata[searchcharpos + 13]);
    Serial.print(serialdata[searchcharpos + 14]);
    Serial.print(serialdata[searchcharpos + 15]);
    Serial.print(serialdata[searchcharpos + 16]);
    Serial.print(serialdata[searchcharpos + 17]);
    Serial.print(serialdata[searchcharpos + 18]);
    Serial.print(serialdata[searchcharpos + 19]);
    Serial.print(serialdata[searchcharpos + 20]);
    Serial.print(serialdata[searchcharpos + 21]);
    Serial.print(serialdata[searchcharpos + 22]);
    Serial.print(serialdata[searchcharpos + 23]);
    Serial.print(serialdata[searchcharpos + 24]);
    Serial.print(serialdata[searchcharpos + 25]);
    Serial.print(serialdata[searchcharpos + 26]);
    Serial.print(serialdata[searchcharpos + 27]);
    Serial.print(serialdata[searchcharpos + 28]);
    Serial.print(serialdata[searchcharpos + 29]);
    Serial.print(serialdata[searchcharpos + 30]);
    Serial.print ("=========");
    //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]);

    enabledtime = 1;

    currentMillis = millis();
  }

  if (enabledtime == 1) {
  if (Serial1.available () > 0) {
    if (foundchar[0] == '\n') {
      /*for (byte a = 0; a < 255; a = a + 1 ) {
        serialdata[a] = 0;
        }*/
        readenabl = 0;
      //указывающий палец = 0;
      enabledtime = 0;
      rtcy1[0] = serialdata[searchcharpos + 8]; //получение первого символа с его смещением
    rtcy1[1] = serialdata[searchcharpos + 9];
    rtcy1[2] = '\0';
    rtcm1[0] = serialdata[searchcharpos + 11];
    rtcm1[1] = serialdata[searchcharpos + 12];
    rtcm1[2] = '\0';
    rtcd1[0] = serialdata[searchcharpos + 14];
    rtcd1[1] = serialdata[searchcharpos + 15];
    rtcd1[2] = '\0';
    rtch1[0] = serialdata[searchcharpos + 17];
    rtch1[1] = serialdata[searchcharpos + 18];
    rtch1[2] = '\0';
    rtcmm1[0] = serialdata[searchcharpos + 20];
    rtcmm1[1] = serialdata[searchcharpos + 21];
    rtcmm1[2] = '\0';
    rtcs1[0] = serialdata[searchcharpos + 23];
    rtcs1[1] = serialdata[searchcharpos + 24];
    rtcs1[2] = '\0';
    }

    if (foundchar[0] == '\r') {
      readenabl = 0;
      //указывающий палец = 0;
      enabledtime = 0;
      rtcy1[0] = serialdata[searchcharpos + 8]; //получение первого символа с его смещением
    rtcy1[1] = serialdata[searchcharpos + 9];
    rtcy1[2] = '\0';
    rtcm1[0] = serialdata[searchcharpos + 11];
    rtcm1[1] = serialdata[searchcharpos + 12];
    rtcm1[2] = '\0';
    rtcd1[0] = serialdata[searchcharpos + 14];
    rtcd1[1] = serialdata[searchcharpos + 15];
    rtcd1[2] = '\0';
    rtch1[0] = serialdata[searchcharpos + 17];
    rtch1[1] = serialdata[searchcharpos + 18];
    rtch1[2] = '\0';
    rtcmm1[0] = serialdata[searchcharpos + 20];
    rtcmm1[1] = serialdata[searchcharpos + 21];
    rtcmm1[2] = '\0';
    rtcs1[0] = serialdata[searchcharpos + 23];
    rtcs1[1] = serialdata[searchcharpos + 24];
    rtcs1[2] = '\0';
    }
    foundchar[0] = foundchar[1];
    foundchar[1] = foundchar[2];
    foundchar[2] = foundchar[3];
    foundchar[3] = foundchar[4];
    foundchar[4] = foundchar[5];
    foundchar[5] = Serial1.read();

    if (foundchar[0] == '+' && foundchar[1] == 'C' && foundchar[2] == 'C' && foundchar[3] == 'L' && foundchar[4] == 'K') {
      readenabl = 1;
      pointingfinger = 0;
    }
    if (readenabl == 1) {
      serialdata[pointingfinger] = foundchar[0];
      serialdata[pointingfinger + 1] = 0;
      pointingfinger++;
    }
  }
  }
}

Вот что получилось:

Спасибо!

, 👍1

Обсуждение

Попробуйте свести его к абсолютно минималистичному примеру. Выполните запрос один раз, а затем считывайте все доступные символы повторно. Попробуйте этот набросок: https://pastebin.com/sRJy63Dt. Вы получили полный ответ?, @Maximilian Gerhardt

О, я вижу серьёзную проблему: скорость передачи данных для Serial такая же, как и для Serial1. Печать отладочной информации или чего-то подобного на Serial происходит крайне медленно. Увеличьте скорость передачи данных на Serial как минимум до 115200 бод, чтобы исключить вероятность слишком долгого ожидания последовательной записи., @Maximilian Gerhardt

Я получаю полный ответ, даже если интервал = 200. Теперь мне нужно найти + и скопировать все параметры со смещением. Но как? Увеличение скорости казалось логичным, но в данном случае это мало что изменило., @A. Somov

Думаю, вам стоит изменить подход к чтению и обработке последовательных данных. После отправки запроса по Serial необходимо циклически повторять данные до получения конца ответа (кажется, это двойной \r\n?). В этом цикле просто сбрасывайте полученные данные в буфер. После полного получения проанализируйте полученный ответ (разбив его на год, месяц, день и т.д.). Думаю, вы теряете слишком много времени в вашем комбинированном методе «чтения и обработки» с миллиардом присваиваний переменных перед каждым чтением., @Maximilian Gerhardt

Можете ли вы привести пример полной строки ответа? Возможно, вам удастся просто отсканировать целые числа с помощью sscanf., @Maximilian Gerhardt

это вывод вашей программы: `Отправка запроса +CCLK: "04/01/01,06:33:06+00" Хорошо. Мне действительно удалось использовать эту идею для цикла в моей программе, и пока что всё работает отлично., @A. Somov

Если это работает, вы, возможно, могли бы написать полный ответ о коде и методах, использованных для того, чтобы это заработало., @Maximilian Gerhardt


1 ответ


1

Это окончательная рабочая программа, которая запрашивает время и анализирует ответ:

const long interval = 1000;
static long currentMillis;

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

char serialdata[256]; //Массив для хранения символов перед разбором

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

byte pointingfinger = 0; //индекс массива

char enabledtime = 0; //эта переменная устанавливается в 1 каждую секунду и устанавливается в 0 после завершения анализа

char readenabl = 0; //устанавливается в 1, когда завершается чтение из последовательного порта

char foundchar[6]; //небольшой буфер, который работает как сдвиговый регистр, чтобы хранить только команду для сравнения

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

void loop() {
  if (millis() - currentMillis >= interval) //Это делается каждую секунду
  {
    Serial1.print("AT+CCLK?\r");

    Serial.println("=========");
    Serial.print(serialdata[searchcharpos]);
    Serial.print(serialdata[searchcharpos + 1]);
    Serial.print(serialdata[searchcharpos + 2]);
    Serial.print(serialdata[searchcharpos + 3]);
    Serial.print(serialdata[searchcharpos + 4]);
    Serial.print(serialdata[searchcharpos + 5]);
    Serial.print(serialdata[searchcharpos + 6]);
    Serial.print(serialdata[searchcharpos + 7]);
    Serial.print(serialdata[searchcharpos + 8]);
    Serial.print(serialdata[searchcharpos + 9]);
    Serial.print(serialdata[searchcharpos + 10]);
    Serial.print(serialdata[searchcharpos + 11]);
    Serial.print(serialdata[searchcharpos + 12]);
    Serial.print(serialdata[searchcharpos + 13]);
    Serial.print(serialdata[searchcharpos + 14]);
    Serial.print(serialdata[searchcharpos + 15]);
    Serial.print(serialdata[searchcharpos + 16]);
    Serial.print(serialdata[searchcharpos + 17]);
    Serial.print(serialdata[searchcharpos + 18]);
    Serial.print(serialdata[searchcharpos + 19]);
    Serial.print(serialdata[searchcharpos + 20]);
    Serial.print(serialdata[searchcharpos + 21]);
    Serial.print(serialdata[searchcharpos + 22]);
    Serial.print(serialdata[searchcharpos + 23]);
    Serial.print(serialdata[searchcharpos + 24]);
    Serial.print(serialdata[searchcharpos + 25]);
    Serial.print(serialdata[searchcharpos + 26]);
    Serial.print(serialdata[searchcharpos + 27]);
    Serial.print(serialdata[searchcharpos + 28]);
    Serial.print(serialdata[searchcharpos + 29]);
    Serial.print(serialdata[searchcharpos + 30]);
    Serial.print ("=========");
    //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]);

    enabledtime = 1;

    currentMillis = millis();
  }

  if (enabledtime == 1) {
    if (Serial1.available () > 0) {
      /*
        if (foundchar[0] == '\n') {
          readenabl = 0;
        //указывающий палец = 0;
        enabledtime = 0;
        rtcy1[0] = serialdata[searchcharpos + 8]; //получение первого символа с его смещением
        rtcy1[1] = serialdata[searchcharpos + 9];
        rtcy1[2] = '\0';
        rtcm1[0] = serialdata[searchcharpos + 11];
        rtcm1[1] = serialdata[searchcharpos + 12];
        rtcm1[2] = '\0';
        rtcd1[0] = serialdata[searchcharpos + 14];
        rtcd1[1] = serialdata[searchcharpos + 15];
        rtcd1[2] = '\0';
        rtch1[0] = serialdata[searchcharpos + 17];
        rtch1[1] = serialdata[searchcharpos + 18];
        rtch1[2] = '\0';
        rtcmm1[0] = serialdata[searchcharpos + 20];
        rtcmm1[1] = serialdata[searchcharpos + 21];
        rtcmm1[2] = '\0';
        rtcs1[0] = serialdata[searchcharpos + 23];
        rtcs1[1] = serialdata[searchcharpos + 24];
        rtcs1[2] = '\0';
        }
        if (foundchar[0] == '\r') {
        readenabl = 0;
        //указывающий палец = 0;
        enabledtime = 0;
        rtcy1[0] = serialdata[searchcharpos + 8]; //получение первого символа с его смещением
        rtcy1[1] = serialdata[searchcharpos + 9];
        rtcy1[2] = '\0';
        rtcm1[0] = serialdata[searchcharpos + 11];
        rtcm1[1] = serialdata[searchcharpos + 12];
        rtcm1[2] = '\0';
        rtcd1[0] = serialdata[searchcharpos + 14];
        rtcd1[1] = serialdata[searchcharpos + 15];
        rtcd1[2] = '\0';
        rtch1[0] = serialdata[searchcharpos + 17];
        rtch1[1] = serialdata[searchcharpos + 18];
        rtch1[2] = '\0';
        rtcmm1[0] = serialdata[searchcharpos + 20];
        rtcmm1[1] = serialdata[searchcharpos + 21];
        rtcmm1[2] = '\0';
        rtcs1[0] = serialdata[searchcharpos + 23];
        rtcs1[1] = serialdata[searchcharpos + 24];
        rtcs1[2] = '\0';
        }

        if (foundchar[0] == '\r') {
        readenabl = 0;
        //указывающий палец = 0;
        enabledtime = 0;
        rtcy1[0] = serialdata[searchcharpos + 8]; //получение первого символа с его смещением
        rtcy1[1] = serialdata[searchcharpos + 9];
        rtcy1[2] = '\0';
        rtcm1[0] = serialdata[searchcharpos + 11];
        rtcm1[1] = serialdata[searchcharpos + 12];
        rtcm1[2] = '\0';
        rtcd1[0] = serialdata[searchcharpos + 14];
        rtcd1[1] = serialdata[searchcharpos + 15];
        rtcd1[2] = '\0';
        rtch1[0] = serialdata[searchcharpos + 17];
        rtch1[1] = serialdata[searchcharpos + 18];
        rtch1[2] = '\0';
        rtcmm1[0] = serialdata[searchcharpos + 20];
        rtcmm1[1] = serialdata[searchcharpos + 21];
        rtcmm1[2] = '\0';
        rtcs1[0] = serialdata[searchcharpos + 23];
        rtcs1[1] = serialdata[searchcharpos + 24];
        rtcs1[2] = '\0';
        }
      */
      foundchar[0] = foundchar[1];
      foundchar[1] = foundchar[2];
      foundchar[2] = foundchar[3];
      foundchar[3] = foundchar[4];
      foundchar[4] = foundchar[5];
      foundchar[5] = Serial1.read();

      if (foundchar[0] == '+' && foundchar[1] == 'C' && foundchar[2] == 'C' && foundchar[3] == 'L' && foundchar[4] == 'K' && foundchar[5] == ':') {
        readenabl = 1;
        pointingfinger = 0;
      }
      if (readenabl == 1) {
        while (foundchar[0] != '\n') {
          if (Serial1.available() > 0) {
            serialdata[pointingfinger] = foundchar[0];
            serialdata[pointingfinger + 1] = 0;
            pointingfinger++;
            foundchar[0] = foundchar[1];
            foundchar[1] = foundchar[2];
            foundchar[2] = foundchar[3];
            foundchar[3] = foundchar[4];
            foundchar[4] = foundchar[5];
            foundchar[5] = Serial1.read();

          }
        }
        readenabl = 0;
        //указывающий палец = 0;
        enabledtime = 0;
        rtcy1[0] = serialdata[searchcharpos + 8]; //получение первого символа с его смещением
        rtcy1[1] = serialdata[searchcharpos + 9];
        rtcy1[2] = '\0';
        rtcm1[0] = serialdata[searchcharpos + 11];
        rtcm1[1] = serialdata[searchcharpos + 12];
        rtcm1[2] = '\0';
        rtcd1[0] = serialdata[searchcharpos + 14];
        rtcd1[1] = serialdata[searchcharpos + 15];
        rtcd1[2] = '\0';
        rtch1[0] = serialdata[searchcharpos + 17];
        rtch1[1] = serialdata[searchcharpos + 18];
        rtch1[2] = '\0';
        rtcmm1[0] = serialdata[searchcharpos + 20];
        rtcmm1[1] = serialdata[searchcharpos + 21];
        rtcmm1[2] = '\0';
        rtcs1[0] = serialdata[searchcharpos + 23];
        rtcs1[1] = serialdata[searchcharpos + 24];
        rtcs1[2] = '\0';
      }
    }
  }
}
,