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++;
}
}
}
}
Вот что получилось:

Спасибо!
@A. Somov, 👍1
Обсуждение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';
}
}
}
}
,
@A. Somov
Смотрите также:
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- В чем разница между Serial.write и Serial.print? И когда они используются?
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Программы построения последовательных данных
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Очистить существующий массив при получении новой последовательной команды
Попробуйте свести его к абсолютно минималистичному примеру. Выполните запрос один раз, а затем считывайте все доступные символы повторно. Попробуйте этот набросок: 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