Мне кажется, что разобрался.
Отправной точкой была информация о том, что GSM модемы плохо разрывают соединение ("кладут трубку"). Т.к. модем с ПЛК соединён по RS485, то можно "прослушать" их обмен:
Код:
ATI <------- ПЛК опрашивает готовность модема
SIM900D R11.0 <------- у модема всё хорошо
OK
ATDT89181111111 <------- набор номера
CONNECT 9600 <------- соединение установлено
:01700000018E
:0171000001107D
:01700000018E
:0171000001107D
:01700000018E
:0171000001107D
:01700000018E
:0171000001107D
:01700000018E
:0171000001107D
:01700000018E
:0170000001008E
:0171000001107D
:01700000018E
:01710000018D
:017░ВВВВВККВ║"5 <------- сбой в обмене
01107E
:01700000018E
:01710000018D
:0171000001107D
:01700000018E
:0170000001107E
:017AАИ║КВВВВВККВ║"5
00018D
:0170000001107E
:01710000018D
:0170000001107E
:01710000018D
Э└ААВККВ║*5 <------- сбой в обмене
:0170000001107E
+++чар° <------- сбой при смене режима
ATH <------- и как следствие - не "кладётся трубка"
ATI <------- ПЛК опрашивает модем, но ответа нет
ATI
ATI
ATI
ATI
На основе лога я пришёл к выводу, что
1) для избежания сбоя при обмене (rs485 ведёт приём и передачу по одной и той же паре) нужно увеличить время между опросом (polling time)
2) для стабильного переключения режима нужно, чтобы к моменту подачи "+++" обмен уже прекратился.
Реализация:
1) Настройка Universal Modbus Device -> Work Mode -> By command
2) после установления соединения запускаю таймер и с его периодичностью произвожу обмен - подаю команду 16#FF в Universal Modbus Device (UMD)
3) когда выполняются какие-либо условия завершения обмена - подаю команду 16#FE в UDM
4) запускаю таймер ожидания завершения обмена по rs485
5) после гарантированного завершения обмена - в модем подаю команды "Stop_Dial=1" и "Start_Auto_Dial=0"
Возможно, было бы правильнее, если бы завершение обмена по Modbus и подача команд "+++" и "ATH" согласовывались на уровне прошивки контроллера. Но тут разработчикам "виднее" - в этом пожелании я не учитываю множества других факторов.