Комментарии
Да, там есть последовательный порт RS484, который прекрасно работает по ModBus, но этот порт занят системой диспетчеризации.

А разве порт RS485 не подразумевает использования шины с разделением на master/slave(s)? То есть к нему можно подключать более одного устройства одновременно.
Да. И это параллельное подключение подразумевает арбитраж. В промышленных системах, с которыми я работал, обычно используется главное устройство диспетчеризации или мониторинга, которое собирает данные со всех слейвов. Поэтому стандартный modbus подразумевает, что 99.99% контроллеров — слейвы и только отвечают на команды, а мониторинги/диспетчеры 99.99% — мастера только посылают команды.

А тут мне надо со слейва опросить еще одно устройство — вообще не представляю как это сделать на готовой системе (*).

(*) если система своя, и проектируется с нуля, можно предусмотреть алгоритм передачи «мастера» от контроллера к контроллеру по команде или таймауту. Или придумать вариант «транзитной» передачи данных. Например у контроллеров MPXpro Carel есть возможность собрать мини-сеть из 6 контроллеров. Из этих 6 контроллеров один главный и 5 второстепенных. Главный может общаться со второстепенными по своему протоколу и при этом быть «слейвом» для системы мониторинга. Когда мониторинг присылает запрос на второстепенный контроллер, главный контроллер работает шлюзом, пропуская все команды сквозняком.

Но в любом случае этот алгоритм зашит на заводе Carel и я ничего не могу изменить. Только пользоваться «как есть».

Насчёт аналогового выхода: попробуйте поиграться с командами 0xA4/0xA5 (https://revspace.nl/MH-Z19B). Но меньше чем 400ppm этот сенсор всё равно вам не выдаст.

Спасибо за наводку. Интересная ссылка. Почему то раньше я ее не замечал.
Результат: При диапазоне 2к, 5к, 10к ответ одинаковый:
Отправляем команду на чтение bounds DAC
Чтение ответа датчика
Прочитали: 255 165 1 144 7 208 0 0 243
1*256+144=400
7*256+208=2000

При этом он явно работает не в диапазоне 400-2000, а так, как я его переключал 400-10000:
CO2: 442 ppm 26 градусов 157 ADC 0.48 V ADC 0,4..2v: 97 2k 235 5k 477 10k
PS: питание передернул.

Ну да, эти диапазоны — не более чем границы измерений. Можно PWM настроить в один диапазон, DAC в другой. По факту прошивка берёт значение концентрации CO2 в ppm, приводит его к выходному значению с учётом границ диапазона, после чего выдаёт на DAC/PWM

В реальности такое сложно найти, а с точки зрения датчика — легко. Если по его мнению концентрация ниже 400, то он её "округляет" до 400. Это иногда приводит к довольно странным графикам.

Зачем пользоваться костылем SoftSerial, когда у ESP8266 два!!! аппаратных UART? В ардуино переключаются так.

Serial.begin(9600, SERIAL_8N1); //GPIO1 (TX) and GPIO3 (RX), 9600kbps, 8-bit data, no parity, 1-bit stop
 
//your brilliant code here
 
Serial.swap();  //GPIO15 (TX) and GPIO13 (RX)
Serial.flush(); //clear serial buffer
 
//your brilliant code here
 
Serial.swap();  //swap back to GPIO1 (TX) and GPIO3 (RX)
Serial.flush(); //clear serial buffer
 
//your brilliant code here


1. После старта esp8266 serial висит на пинах gpio01(TX) и gpio03(RX)
2. Переключаем на MH-Z19 командой Serial.swap() подключённый к gpio15(TX) и gpio13(TX)
3. На всякий случай чистим буфер serial (gpio15 и gpio13) от мусора оставшегося от предыдущего обмена, командой Serial.flush();
4. Передаем сообщения MH-Z19
5. Принимаем сообщение от MH-Z19 ВО ВРЕМЕННУЮ ПЕРЕМЕННУЮ
6. Переключаемся назад на serial (gpio01(TX) и gpio03(TX)) и чистим буфер (gpio01(TX) и gpio03(TX))
7. Посылаем данные из временной переменной в com gpio01(TX) и gpio03(TX)
8. Переключаемся назад на MH-Z19 и повторяем с п.3
Что-то я не понял, а зачем все эти переключения туда-обратно? Можно подробнее?
Куда уже подробнее? Но я постараюсь. У ESP8266 два полных аппаратных UART. Первый UART0 занят USB-COM мостом (для закачки прошивки и обмена с компьютером). Второй UART2 абсолютно свободен.

К AVR вопросов нет, там почти всегда один аппаратный UART и он занят USB-COM мостом и bootloder-ом, поэтому без SoftSerial никак. Но зачем тащить кривой ногодрыг в проекты на ESP8266 с двумя аппаратными UART?

В ESP8266 Serial.swap() нужен для переключения между UART0 и UART2. Команда Serial.flush() нужна для очистки буфера — он один на оба UART и после переключения там может оставаться непрочитанная информация от предыдущего обмена. Если необходимости в обмене между ESP8266 и компьютером по COM порту нет, то «все эти переключения туда-обратно» не нужны. Достаточно одного вызова Serial.swap() после загрузки ESP8266, для переключения на UART2.

Понятно?
Вопрос не в том, зачем переключаться обратно на UART0? Что-то сломается, если этого не сделать?
В вашем случае, при попытке отправить debug информацию на компьютер она попадет на MH-Z19.

Те. если необходимости в обмене между ESP8266 и компьютером по COM порту нет, то «все эти переключения туда-обратно» не нужны. Достаточно одного вызова Serial.swap() после загрузки ESP8266 и весь Serial.print() (в том числе и встроенный debug от Arduino ESP8266 core) будет валится в UART2. А оно вам надо?
Почему нельзя, можно если переключаться туда-обратно между UART0 и UART2 командой Serial.swap() и чистить буфер командой Serial.flush(). По другому задействовать оба UART в Arduino ESP8266 core нельзя.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.