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();
}
}
Вот результат (скриншот, потому что последовательный монитор не дает мне полный код):
@A. Somov, 👍2
2 ответа
Лучший ответ:
Вы объявляете переменные для месяца и минуты по-разному (rtcm1[3]
и rtcm1[3]
), но загружаете rtcm1
с месяц, а затем несколькими строками позже, с минутами.
Вот окончательный код на случай, если он кому-то понадобится:
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();
}
}
- Печать массива с помощью функции печати и последовательной записи в Arduino Uno
- Как создать массив из serial.read?
- Последовательный разбор странных данных
- массив в последовательный порт
- Как преобразовать строку в шестнадцатеричный массив
- Матричный дисплей с Arduino UNO (ПРОБЛЕМА)
- Самый быстрый способ прочитать массив чисел из python
- Самый прямой способ назначить байты Serial.read() массиву?
Дурак я! Наверное, я проглядел опечатку и подумал, что это какая-то другая ошибка., @A. Somov