Как реализовать MQTT по GPRS на модеме A6 в асинхронном режиме
- Войдите на сайт для отправки комментариев
Всем привет
Создаю контроллер, работающий по GPRS с протоколом MQTT
Контроллер использую ESP32
Нашел хорошую библиотеку TinyGSM все это реализующую. Но вот беда. Когда эта библиотека взаимодействует с GSM модемом, то использует функцию waitResponse(). Получается, после посылки команды в модем контроллер ничем не может заниматься в основном цикле до ожидания ответа
Если бы это было только один раз, но GPRS соединение периодически отваливается и приходится запускать переподключение в основном цикле программы.
Никто не видел реализации такой работы в асинхронном режиме?
Чтобы я запускал команду в модем и спокойно бы обрабатывал основной цикл, периодически проверя статус ответа модема?
Путь в нем будет LoopGSM() отвечающий за прием данных от модема, но только когда есть эти данные, если уж нельзя реализовать данную функцию по прерыванию
Там унутре waitResponse() вызываеца TINY_GSM_YIELD(), может ей чонить присвоить, поиграца.
Я глубоко не рыл, счас посмотрю, что оно значит.
вот как она описана
можно её подменить на определение своей функции вне этой библиотеки. И таймаут там, кста, настраиваемый.
Но я, вероятнее всего, могу ошибаться, ибо не семи пядей в лобу. Может, Евгений Петрович что подскажет.
Чтобы я запускал команду в модем и спокойно бы обрабатывал основной цикл, периодически проверя статус ответа модема?
Не использовать библиотеки
Написать самим
Пример асинхронности
http://arduino.ru/forum/apparatnye-voprosy/vse-o-sim800l-i-vse-chto-s-ni...
вот как она описана
можно её подменить на определение своей функции вне этой библиотеки. И таймаут там, кста, настраиваемый.
Но я, вероятнее всего, могу ошибаться, ибо не семи пядей в лобу. Может, Евгений Петрович что подскажет.
Очень напрягают такие конструкции в библиотеке
или такая конструкция в цикле
Пока нашел другое решение. Повесил весь свой основной код на прерывание по таймеру.
Пускай основной цикл только занимается модемом. А мне только статусы проверять при каждом срабатывании таймера
Чтобы я запускал команду в модем и спокойно бы обрабатывал основной цикл, периодически проверя статус ответа модема?
Трудоемкость реализации MQTT over GPRS да еще и в AT командах моего модема A6/A7 достаточно велика.
Хотелось бы обойтись без крайностей.
TinyGSM нашел как единственную более менее законченную и рабочую реализацию
Ну я в таких вопросах нихрена не компетентен. :( Ждите гуру.
TinyGSM нашел как единственную более менее законченную и рабочую реализацию
TinyGSM - кривое глюкало.
Самое правильное все-таки написать самому. Трудоемкость там не так уж велика, как вам кажется. Пишете ведь не с нуля... Берете ту же TinyGSM или аналогичную библиотеку для SIM800|900 (команды модемов очень близки) - и дорабатываете.
Я в самом начале увлечения ардуиной переписывал библиотеку для SIM900 именно под модем А6. Несмотря на новичковость в ардуине справился с задачей за нескольо дней. Ничего там сложного нет.
Код выкладывать не стану - стыдно. :)
Кстати, примеры работы с GPRS для А6 есть в темах Logik-а на форуме.
Хотелось бы обойтись без крайностей.
Ну тогда если вам не требуется подписываться на топик MQTT сервера, тупо шлите
в модем последовательности команд по таймеру, т.е. например каждые 45 секунд отправка
цикла команд отправки PUBLISH пакетов MQTT с инициализацией сессии GPRS
с периодичностью 0,5 секунд, ответы игнорировать. Обязательно после цикла отправки
шлите DISCONNECT пакет MQTT. А что бы быть ну почти уверенным что все будет работать
каждые например 30 минут сбрасывайте модем и инициализируйте заново.
Вот для примера последовательность для SIM800, для вашего модема она другая.
http://arduino.ru/forum/programmirovanie/snova-mqtt-1#comment-411540
ЗЫ. Где то тут пробегала ссылка на хорошую библиотеку таймеров если уж не хотите сами с millis заморачиваться
Update: кстати про прерывания - в примере #4 чтения СМС при уменьшении скорости Serial со 115200 на меньшее, скетч перестает работать, не успевает обрабатывать ответ от модема и символы теряются, пришлось кардинально менять логику поиска подстроки (поиск с конца строки - время обработки увеличилось в 4 раза), и часть критичных переменных в ОЗУ переносить - тогда только стало работать с любой скоростью Serial, да еще и HTTP запросы слать и ответы обрабатывать успевал.
Всем большое спасибо за помощь. Работать с модемом в основном цикле и вызывать остальной код по таймеру оказалось хорошей идеей. Пока все работает довольно надежно.
TinyGSM - кривое глюкало.
Самое правильное все-таки написать самому. Трудоемкость там не так уж велика, как вам кажется. Пишете ведь не с нуля... Берете ту же TinyGSM или аналогичную библиотеку для SIM800|900 (команды модемов очень близки) - и дорабатываете.
Я в самом начале увлечения ардуиной переписывал библиотеку для SIM900 именно под модем А6. Несмотря на новичковость в ардуине справился с задачей за нескольо дней. Ничего там сложного нет.
В TinyGSM есть стыковка с MQTT библиотекой PuSubClient. При этом код MQTT переносится без проблем с WiFi и Ethernet интерфейсов. Так что пока буду мириться.
Писать свою реализацию MQTT включая все QOS, подписки, авторизацию и пр. все таки чере чур
Ну тогда если вам не требуется подписываться на топик MQTT сервера, тупо шлите
в модем последовательности команд по таймеру, т.е. например каждые 45 секунд отправка
цикла команд отправки PUBLISH пакетов MQTT с инициализацией сессии GPRS
с периодичностью 0,5 секунд, ответы игнорировать. Обязательно после цикла отправки
шлите DISCONNECT пакет MQTT. А что бы быть ну почти уверенным что все будет работать
каждые например 30 минут сбрасывайте модем и инициализируйте заново.
Вот для примера последовательность для SIM800, для вашего модема она другая.
http://arduino.ru/forum/programmirovanie/snova-mqtt-1#comment-411540
ЗЫ. Где то тут пробегала ссылка на хорошую библиотеку таймеров если уж не хотите сами с millis заморачиваться
Как раз управление по подписке - самая нужная функция. Так что как раз важна поддержка соединения. Просто посылать данные скорее всего реализовал бы на HTTP протоколе. Он как то проще и не требует постоянного соединения.
Так как код пишу на ESP32 - работа с таймерами там отлично реализована в библиотке Ticker