ESP32 t-call Не получается парсить ответ модема.
- Войдите на сайт для отправки комментариев
Вс, 07/02/2021 - 20:48
Добрый день, коллеги!
В наличие плата ESP32 t-call (это которая с SIM800L на борту). Пытаюсь разобраться с платкой. Начал с того, что скетч должен отправить АТ команды. Отправлять последовательно не интересно. Решил дожидаться от модема ответа. Написал скетч, который отправляет команду, после чего ждем ответ от модема. Далее попытался парсить ответ, что бы выделить из него "ОК" ну для начала проверять, есть ли в ответе искомая подстрока. Вот такой скетч получился.
#define DEBUG 1 // 0 - Debug OFF, 1 - Debug ON /********************************************* * Натройка SIM800 * ******************************************/ #define MODEM_RST 5 // Pin RST SIM800L #define MODEM_PWRKEY 4 // Pin PWRKEY SIM800L #define MODEM_POWER_ON 23 // Pin PowerOn SIM800K #define MODEM_TX 27 // Pin TX SIM800L #define MODEM_RX 26 // Pin RX SIM800L #define LED_GPIO 13 // Pin #define LED_ON HIGH #define LED_OFF LOW #define SIM800Ready 15 // Пин светодиода готовности SIM800 #define SerialMon Serial // Set serial for debug console (to the Serial Monitor, default speed 115200) #define SerialAT Serial1 // Set serial for AT commands (to the module) /********************************************************* Подключение библиотек *********************************************************/ #include <Arduino.h> /********************************************************* Объявление переменных *********************************************************/ boolean firstStart = HIGH; // Признак первого запуска системы для настройки uint8_t caseNumber = 0; // Этапы отправки команд при начальной настройке uint32_t firstStartTime; // Переменная для хранения переменной паузы ввода команд /********************************************************* Объявление функций *********************************************************/ void setupModem(); void firstStartModem(); String sendCommand(String command, boolean weitingResponse); String waitResponse(); void pause(uint16_t pauseLenght); void setup() { // Функция первого запуска #if (DEBUG == 1) SerialMon.begin(115200); // Инициирование работы с монитором порта delay(300); SerialMon.println("Debug is ON. Print LOG information."); #endif SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX); // инициирование работы с модемом setupModem(); firstStartTime = millis(); } void loop() { if (firstStart){ // Если установлен признак первого запуска системы, то... firstStartModem(); // ... запуск функции ввода АТ команд настройки модема } while (SerialAT.available()) SerialMon.write(SerialAT.read()); while (SerialMon.available()) SerialAT.write(SerialMon.read()); } /********************************************************* * ФУНКЦИИ РАБОТЫ С МОДЕМОМ *********************************************************/ void setupModem(){ // Функция инициирование модема на плате ESP32 t-call pinMode(SIM800Ready, OUTPUT); digitalWrite(SIM800Ready, LOW); pinMode(MODEM_RST, OUTPUT); digitalWrite(MODEM_RST, HIGH); pinMode(MODEM_PWRKEY, OUTPUT); pinMode(MODEM_POWER_ON, OUTPUT); // Turn on the Modem power first digitalWrite(MODEM_POWER_ON, HIGH); // Pull down PWRKEY for more than 1 second according to manual requirements digitalWrite(MODEM_PWRKEY, HIGH); delay(100); digitalWrite(MODEM_PWRKEY, LOW); delay(1000); digitalWrite(MODEM_PWRKEY, HIGH); // Initialize the indicator as an output pinMode(LED_GPIO, OUTPUT); digitalWrite(LED_GPIO, LED_OFF); // Временная задержка на 5 секунд перед стартом системы и началом настройки модема uint32_t TimePause = millis(); SerialMon.println("Pause to boot the system"); pause(9000); SerialMon.println("Start entering AT commands"); } void firstStartModem(){ // Функция отправки АТ команд при начальной настройке if (caseNumber == 0){ String response_firstStartModem = sendCommand("AT", HIGH); firstStartTime = millis(); caseNumber++; } else if (caseNumber == 1 && millis() - firstStartTime >500){ sendCommand("ATE1", LOW); firstStartTime = millis(); caseNumber++; } else if (caseNumber == 2 && millis() - firstStartTime >500){ sendCommand("ATV1", LOW); firstStartTime = millis(); caseNumber++; } else if (caseNumber == 3 && millis() - firstStartTime >500){ sendCommand("AT+CMEE=1", LOW); firstStartTime = millis(); caseNumber++; } else if (caseNumber == 4 && millis() - firstStartTime >500){ sendCommand("AT+CLIP=1", LOW); firstStartTime = millis(); caseNumber++; } else if (caseNumber == 5 && millis() - firstStartTime >500){ sendCommand("AT+CMGF=1", LOW); firstStartTime = millis(); caseNumber++; } else if (caseNumber == 6 && millis() - firstStartTime >500){ sendCommand("AT&W", LOW); firstStartTime = millis(); caseNumber++; } else if (caseNumber == 7){ firstStart = LOW; } } String sendCommand(String command, boolean weitingResponse){ String response_sendCommand = "No response was expected"; SerialAT.println(command); if (weitingResponse){ response_sendCommand = waitResponse(); //response_sendCommand = response_sendCommand.substring(0, response_sendCommand.indexOf("\r")); SerialMon.println("Команда: " + command); SerialMon.println("Ответ: " + response_sendCommand); if (response_sendCommand.startsWith(command)) { // Убираем из ответа дублирующуюся команду SerialMon.println("совпадает с командой"); response_sendCommand = response_sendCommand.substring(response_sendCommand.indexOf("\r", command.length()) + 2); } } return response_sendCommand; } String waitResponse(){ // Ожидание ответа от модема String response_WeitResponse = ""; // Переменная для хранения результата uint32_t timeout_WeitResponse = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) while (!SerialAT.available() && millis() < timeout_WeitResponse) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... if (SerialAT.available()) { // Если есть, что считывать... response_WeitResponse = SerialAT.readString(); // ... считываем и запоминаем response_WeitResponse.trim(); } else { // Если пришел таймаут, то... #if (DEBUG == 1) SerialMon.println("Timeout..."); // ... оповещаем об этом и... #endif } return response_WeitResponse; } /********************************************************* * ФУНКЦИИ СОПУТСТВУЮЩЕЙ РАБОТЫ *********************************************************/ void pause(uint16_t pauseLenght){ // Функция паузы в миллисекундах uint32_t timeNow = millis(); while(millis() - timeNow < pauseLenght){} }
По сути 146 строка должна была определять, что в ответе есть дубль команды и далее удалить ее. LOG в мониторе порта вот такой....
Debug is ON. Print LOG information.
Pause to boot the system
Start entering AT commands
Комманда: AT
Ответ: ...
И вот даже сюда не копируется текст из монитора. После слова "Ответ:" есть какой то символ... естественно его не видно. По программе я не понимаю, какой там символ вставляется. Соответственно я не могу удалить его программно.
Прошу помощи в исправлении кривизны рук. Как удалить не нужные символы?
Так выглядит ответ в мониторе порта.
Изменил код на ожидание ответа во второй строке.
Сейчас распознает, что в ответе есть исходная команда, но все равно ответ содержит перенос на другую строку. И снова не понимаю, откуда он берется и как от него избавиться.
И вот даже сюда не копируется текст из монитора. После слова "Ответ:" есть какой то символ... естественно его не видно. По программе я не понимаю, какой там символ вставляется. Соответственно я не могу удалить его программно.
Переписал код вот так:
Можно считать вопрос решеным. Хотя я не понимаю, в чем разница. Почему по разному отображает монитор порта информацию.
я бы так не радовался, ибо в коде ошибка и в 9 строке всегда будет "ОК" :)
не долго музыка играла...
Так в чем же причина? :(
Поправил... естественно работать перестала программа.
Никак не соображу, как преобразовать переменную String в массив (например char) и вывести цифровые значения в монитор порта.
надо смотреть что там вы "нарезаете"
Вот такой код
Вот такой ответ в мониторе
может эхо для начала выключить? я не помню как там - АТЕ0 чтоль, не помню...
Со всеми ответами разобрался. Усекаю исходный ответ до символа char(10) и остается только ответ "ОК". А вот с форматом и содержанием ответа на запрос "АТ" не понятно.
Спасибо за подсказку. После реализации Вашего предложения стало понятно, что нужно сделать.
Усекаю исходный ответ до символа char(10)
зря, некоторые команды после ОК еще что то нужное/важное могут прислать, если уж вам необходимо искать именно последний ответ ОК то я например ищу строку "OK\r\n"
http://arduino.ru/forum/apparatnye-voprosy/vse-o-sim800l-i-vse-chto-s-ni...