Совсем недавно, проводя ревизию в одной из старых лабораторий университета, руководство поставило задачу как‑то использовать часть её старого оснащения. В качестве пациента и героя дальнейшего рассказа будет выступать вот такое незамысловатое сооружение, которое когда‑то было одним из тренажеров для студентов‑движенцев — дежурных по станции. Работало это хозяйство под управлением ПК начала «нулевых» с горячим сердцем в виде Pentium 4, с ОС Windows 2000 на борту. Речи о том, чтобы использовать эти старые компьютеры, разумеется не шло — времена уже не те, современный софт и средства разработки далеко переросли и характеристики этого процессора и этой ОС. Системные блоки, естественно, отправятся в утиль.  Единственным, что можно хоть как‑то использовать оказались телевизор, то же не слишком изящный по нынешним временам — NEC LCD4010 c разрешением 1360×768, и два сенсорных встраиваемых монитора Elo Touchscreen с разрешением 1024×768. Было решено подключить это хозяйство к более‑менее современному компьютеру с Linux на борту и попробовать собрать на этом уже другой тренажер, для локомотивщиков. Тут надо отметить, что старую технику я люблю, но вот использовать её в рабочих решениях, по понятным причинам как‑то не очень. Если с телевизором все более‑менее понятно, хоть и габаритный и тяжелый, с VGA‑интерфейсом, но завести его через кабель DisplayPort‑VGA в общем‑то задача тривиальная. Другое дело — Elo Touchscreen, как выяснилось модели ET1547L-8SWC оптимизма явно не внушал. Однако, настоящие джедаи так просто не сдаются, поэтому Видеоинтерфейс сенсорного экрана — VGA, что в общем не является проблемой. Разрешение 1024×768 — тоже проблемой не является, современные встраиваемые 15-дюймовые Elo тоже имеют такое разрешение, по крайней мере те, что закупались нами для тренажеров уже в 2017 году. Но современные мониторы имеют разъем DisplayPort, а для touch‑сенсора используется USB‑интерфейс. Здесь же я увидел нечто, что сначала повергло меня в задумчивость. Два загадочных зеленых разъема тянулись к плате, воткнутой в PCI‑слот. Кто‑то из читателей на этом моменте нетерпеливо воскликнет — «Это же COM‑порты, идиот!» и будет совершенно прав, но для меня, не работавшего с такими решениями в области сенсорных экранов этот ответ был неочевиден. Тем более что кабель ну никак не был похож на стандартный нуль‑модемный, с двумя «мамами». На момент изучения вопроса у меня было даже подозрение что это USB, но в каком‑то проприетарном исполнении, с проприетарной же PCI‑платой сопряжения, драйверов на которую в 2023 году не найти. Плата была извлечена из корпуса старого системного блока маркировка чипов была отдана на съедение гуглу и выяснилось что плата ничто иное, как PCI‑расширитель COM‑портов. Причем установка её в материнскую плату добавляла в систему три порта в формате DB9 и один в формате DB25. Это было, как в известном анекдоте — хорошая и плохая новость одновременная. Хорошая в том, что такая плата наверняка поддерживается ядром Linux из коробки и не нужно будет искать драйвера. Плохая заключалась в моем опасении, что распайка странного кабеля «папа»‑»мама» будет отличатся от стандартной, а может там и ещё какой сюрприз — кто их знает, эти корпорации... Подключение нуль‑модемного кабеля к двум портам на плате показало — да, Linux прекрасно работает с данной платой, второе — распайка как портов так и странного зеленого кабеля совершенно стандартная. Rx встретился с Tx, судя по весело побежавшим сообщениям терминала, отправляемым из одного порта в другой. Соответственно, вместо старой PCI‑платы расширителя, можно, в современном системнике, использовать и новую, на интерфейсе PCI‑Express. Таким образом первая часть Марлезонского балета завершилась и увенчалась, для порядка, написанием правила udev для назначения прав доступа на COM‑порты /etc/udev/rules.d/90-serial.rules Сборка тестовой системы, однако, показала, что тактильный сенсор на экранах не подает никаких признаков жизни. Я‑то привык к тому что современные мониторы Elo, крайний из которых я использовал в 2021 году для тренажера электровоза ЧС2т, заводятся в Linux из коробки, и даже, часто не нуждаются ни в установке софта от производителя, ни даже в калибровке, если таковой монитор один. Здесь же предстояло ещё много вкусного красноглазия. Но наживка мной была захвачена, запустить этот экран в работу стало делом принципа. Разумеется, на технику начало 2000-х на официальном сайте Elo Touchsystems ничего не нашлось. При том, что мой опыт работы с изделиями этой фирмы достаточно положителен и я доволен — мало по мало они упорядочили поддержку Linux для всех своих актуальных устройств. Мой коллега, работавший над проблемой вместе со мной, под моё недовольное брюзжание о том что найденное в сети для ядер Linux версии 2.4 — 2.6 работать не будет в принципе, проведя масштабный поиск наткнулся таки на архив с софтом под Elo Serial Touchscreen версии 3.6.0 от 2021 года, где нашлись и модуль ядра и программы калибровки, совместимые с ядрами Linux версии 5.x. В дистрибутиве Arch Linux, который использован на тестовой машине, на момент написания данной статьи присутствует ядро версии 6.2.9. Но, когда скачанный софт, согласно инструкции был развернут на целевой системе, и согласно инструкции же, загружен оригинальные модуль ядра от Elo Touchsystems, таки да — курсор, хоть и невпопад, но забегал по экрану. Значит сенсор жив и работает, но экраны не откалиброваны просто. Утилита калибровки в архиве с софтом Elo нашлась. И вот тут‑то и началась настоящая свистопляска длиной в неделю. Не хотели эти экраны калиброваться! Что мы не делали — по разному настраивали xorg.conf то объединяя три экрана в один, то разнося каждый монитор на свой экран, пробовали и те настройки утилит калибровки (коих в комплекте оказалось несколько) то эти. Устойчиво работала только конфигурация с одним единственным сенсорным экраном. Стоило подключить второй экран или телевизор — все тут же шло прахом. Дело усугублялось тем, что весь сервисный софт Elo (кроме модуля ядра) — проприетарный, исходники не посмотреть, причину не понять. В голову закралась мысль, что современные мониторы Elo работают в Linux «из коробки», не требуя применения специализированного софта для своей настройки в большинстве случаев. Значит, наверняка, решение существует среди открытого софта. И эта мысль оказалась верной — первое же, достаточно яростное, гугление вывело нас... в репозторий ядра Linux где оказался вот такой код  Исходя из комментария в начале кода, понятно, что модуль ядра для Elo и именно с последовательным портом в качестве интерфейса присутствует в ядре Linux, а может быть только начал писаться — но аж в 2004 году! А крайний коммит датирован 2021 годом, то есть драйвер во вполне актуальном состоянии. Выполнение и последующее дало следующий выхлоп Оставалось только понять, как заставить загруженный драйвер правильно взаимодействовать с Xorg. Перед началом новой фазы экспериментов было решено откатиться на такую конфигурацию мониторов Не буду перечислять бесчисленные Stack Owerflow, и прочие ресурсы, которые пришлось перешерстить в поисках решения. А оно, что удивительно, нашлось на... ЛОРе, вот в этом трэде. Исходя из полученной информации в системе были установлены пакеты Прежде всего, следовало понять, как связать экран с соответствующим ему COM‑портом. Эта задача решилась просто Ключик ‑elo как раз и сообщает утилите inputattach какой модуль ядра загрузить. После выполнения первой из команд, если модуль elo и не был загружен, то он загрузится. Далее, в качестве параметра указывается COM‑порт, при этом, используя модуль ядра, inputattach находит на данном порту сенсорный экран и инициализирует его. Ключ ‑daemon запускает экземпляр процесса inputattach в фоне, отпуская консоль. После этой процедуры курсор опять забегал по экрану, при прикосновению к нему, но опять забегал как умалишенный. Применение ветхой утилиты xinput_calibrator ничего толком не дало — генерируемые им параметры Xorg адекватно не воспринимал. Однако первый этап — заставить систему загрузить модуль ядра и инициализировать экран — прошел успешно, о чем свидетельствует вот такой выхлоп Наши сенсорные экраны в списке с идентификаторами id=6 и id=7. Посмотрим поближе на свойства этих устройств Добытая информация и собственные размышления привели к выводу, что стоило бы обратить внимание на параметр с номером (278) libinput Calibration Matrix, которая в неоткалиброванном экране оказалась диагональной единичной матрицей 3х3. Очевидно, её модификация для каждого из экранов должна была бы привести нас к нужному результату, и было принято отчаянное решение - выполнить закат Солнца вручную, настроив эту калибровочную матрицу самостоятельно. Формулы, приведенные в частности по этой ссылке, эффекта не дали. Откуда они вообще взялись и как были выведены - тот еще вопрос. Поэтому пришлось применить оружие настоящего джедая, ещё более изящное чем световой меч, а именно - аппарат линейной алгебры. Для начала был проведен эксперимент, имевший своей целью выяснить куда попадает курсор при касание угловых точек экрана. Этот эксперимент дал, в существующей конфигурации результат, выражаемый рисунком Черными парами координат без скобок показаны фактические координаты восьми точек, куда прикасался палец в процессе эксперимента, выраженные в долях ширины и высоты обще области ввода, с учетом разрешения всех задействованных мониторов. Зeлеными парами в скобках показаны фактические координаты точек, куда Xorg перемещал курсор. Очевидно, что здесь мы имеем дело с отображением одного линейного пространства в другое, при этом, такое преобразование мы можем представить в виде или в развернутом виде Очевидно, что при некалиброванном экране матрица C — единичная, никак не влияет на результат преобразования, а матрица Msv — то правило, по которому ведет преобразование некалиброванный экран. Очевидно, для совпадения координат точки, куда попадает палец xs и ys и туда, куда в итоге перемещается курсор xv и yv необходимо подобрать такую матрицу C, чтобы оказалось что где E — единичная матрица. Очевидно, что для этого надо обратить матрицу Msv При единичной калибровочной матрице, получаем два уравнения  Для левого экрана, взяв точки 1 и 3 (диагональ) получаем конкретные уравнения откуда вытекает, что матрица Msv (которая соответствует не калиброванному экрану) равна обращая которую получаем калибровочную матрицу для левого экрана Аналогично, для правого экрана, имеем уравнения получая матрицу текущего преобразования и калибровочную матрицу Остается только задать эти матрицы для каждого из экранов, использую id, выводимые xinput ииии... дело в общем-то в шляпе! Все эти настройки после перезагрузки, разумеется превратятся в «тыкву». Чтобы этого не произошло, следует, во первых, при загрузке системы и инициализации графики выполнить запуск демонов inputattach, что решаем средствами systemd, написав такой юнит /etc/systemd/system/elotouch@.service после чего, протестировав службу, помещаем её в автозагрузку, передав в качестве параметра имена COM‑портов, на которых висят сенсоры. Для загрузки матрицы калибровки, настроим в xorg.conf соответствующие устройства ввода  Внимание следует обратить на следующие секции /etc/X11/xorg.conf Здесь связываются между собой драйвер устройства, его нода в /dev/input, которую можно узнать из выхлопа xinput list-props. Кроме того, эти устройства следует указать в секции ServerLayout /etc/X11/xorg.conf Теперь, после перезагрузки и запуска "иксов" наши экраны инициализируются и откалибруются. Естественно, тесты работы данных экранов показали и низкую отзывчивость сенсора, и его нелинейность, усугубляющуюся к краям экрана. Всё таки технике скоро стукнет второй десяток. Однако, они вполне пригодны к использованию в некритичных к этим недостатках применениях. Второй момент — всё это было бы трудно осуществимо в ОС семейства Windows. На версию 7 драйвера Elo Serial Touchscreen еще худо бедно ставятся, а вот на 10 или 11 — не дождетесь. Надеюсь было интересно, спасибо за внимание и до новых встреч!