Программная симуляция нажатия кнопки мембранной клавиатуры

ursoft
Offline
Зарегистрирован: 08.02.2022

Возможно, уже обсуждалось - но не понимаю, как найти (

Дано: материнская плата с шлейфом клавиатуры, на разъём которого можно припаяться с обратной стороны платы (уже). Нет исходников ПО, нет возможности припаяться куда-то еще (слишком мелко, залито лаком и вообще страшно испортить). Найдена пара контактов шлейфа, замыкание которых друг на друга даёт в прошивку нажатие целевой кнопки (всего 2 кнопки, т.е. 2 пары). Один контакт на осциллограмме представляет из себя меандр 3.3В 10мс каждые 50мс. Если на второй контакт приходит 3.3 В в той же форме, кнопка считается нажатой.

Задача: в программе под ArduinoESP32 сделать программное нажатие кнопки. При этом (в другое время) кнопку должен успешно нажимать пользователь. Идея простая - читаем с одного пина и тащим значение в другой. Но если чуток ошибиться во времени, программа "словит" неправильную кнопку.

Проблема: более устойчивое функционирование. В силу некоторых особенностей реализации прерываний ESP32 сделать через RAISING/FALLING IRQ не получилось (RAISING еще кое-как ловится, если GPIO пины удачно подобрать и разнести 2 кнопки по времени, а с FALLING уже никак). Поэтому сделал через отдельную задачу с опросом - см. ф-ю SchwinnResistButton::task  в https://github.com/ursoft/ANT_Libraries/blob/master/ANT_DLL/WROOM_esp32/...

Работает устойчиво в 90% случаев (иногда 5х повторов не хватает приходится повторять "нажатие", это не фатально - но очень редко, до 1%, таки срабатывает неправильная кнопка). Есть ощущение, что надо сделать совсем не так, и будет устойчиво работать в 100% случаев (речь в вопросе идет только о программных извращениях, паяльная часть на материнке завершена и транзисторы/кондесаторы/сопротивления/реле можно применять только те, что уже есть в ESP32). Кроме попытки сделать на прерываниях еще игрался с приоритетом задачи и типами пинов (INPUT/OUTPUT/PULLUP/PULLDOWN), но ничего понятного из этого не вышло. В двух предложениях алгоритм получился следующий:

1. Пока кнопкой не управляем, оба пина в состоянии INPUT (вход) /  INPUT_PULLDOWN (выход, тоже можно INPUT - но вроде чуть похуже процент успехов). Пользователь если мембрану нажимает, у него получается 100% успех.

2. Когда нужно нажать программно - ждем на входе начало меандра и переводим выходной пин в состояние OUT-HI, а через 8мс - обратно в INPUT_PULLDOWN. И так несколько раз. Понять, что меандр на входе закончился, не удается - мешает наша выдача OUT-HI (т.е. после нее и на входе уже висит 1,  ни FALLING, ни чтение входа не срабатывают).

Мысли по поводу

Можно начало меандра хватать при помощи RAISING и как-то отсекать те же 9 попугаев (мс) по времени (а не по задержке, как сейчас), но я пробовал и фактической точности это почему-то не прибавляет. Поймать осциллографом 1% неверных нажатий не получилось - предположительно, работая вслепую, вывалились за пределы меандра выборки (или возникают наводки по нашим проводам). Идеально было бы так программно настроить пины, чтобы и кнопку сымитировать, и FALLING входа не потерять.

b707
Offline
Зарегистрирован: 26.05.2017

а нельзя оригинальный сигнал с клавиатуры вообще не трогать - то есть соединить накоротко. А если надо эмулировать - подавать сигнал параллельно?

ursoft
Offline
Зарегистрирован: 08.02.2022

Прошу прощения, я об этом четко не написал: мои провода припаяны к разъёму шлейфа как раз в параллель с имеющимися - не в разрыв. Т.е. можно вообще не подключать ESP32 - и пользователь спокойно воспользуется кнопками, как и раньше (это важный сценарий). А вот если ESP32 подключить, то нет сценария держать его не запитанным от той же материнки (иначе возможно всякое, вплоть до высвечивания "ошибка клавиатуры" на дисплее).

Завести сигнал в другое место также не получится - слишком мелкая пайка там и залито лаком. Удобоварим оказался только сам разъём.

b707
Offline
Зарегистрирован: 26.05.2017

ursoft пишет:

А вот если ESP32 подключить, то нет сценария держать его не запитанным от той же материнки (иначе возможно всякое, вплоть до высвечивания "ошибка клавиатуры" на дисплее).

а "земли" у материнки и ЕСП обьединены? И в чем проблема запитать его от материнки? На любой матплате есть питание 5в

судя по тому. как много внимания вы уделяете вопросам пайки - вы, видимо, не очень уверенно себя чувствуете в этом? Совет - найдите какого-то грамотного "паяльщика" и поручите это ему, решайте только программные вопросы.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ursoft пишет:

...меандр 3.3В 10мс каждые 50мс.

...

...ждем на входе начало меандра и переводим выходной пин в состояние OUT-HI, а через 8мс - обратно в INPUT_PULLDOWN.

Во-первых, почему в одном случае 10 мс, а в другом - 8?

А во-вторых, почему сами формируем импульс желаемой ширины, а не транслируем его со входа?

ursoft
Offline
Зарегистрирован: 08.02.2022

b707 пишет:
а "земли" у материнки и ЕСП обьединены? И в чем проблема запитать его от материнки? На любой матплате есть питание 5в

Да, он с изделия и запитан - проблем нет (если не считать проблемой, что для перепрограммирования нужно подключать ноутбук со своими уровнями и отключать изделие). Упомянул чтобы не предполагали, что у меня уровни совсем кривые, отсюда и помехи.

b707 пишет:
судя по тому. как много внимания вы уделяете вопросам пайки - вы, видимо, не очень уверенно себя чувствуете в этом? Совет - найдите какого-то грамотного "паяльщика" и поручите это ему, решайте только программные вопросы

Будете смеяться - так и сделал. Подкатил с ведром лести к сынуле, он и припаял )))
А сам паяю как последний лузер, пожег бы только плату. С программированием же у нас наоборот - он ни в какую, а я кое-что могу.
Нам бы еще электронщика, но вот нет пока. Поэтому сюда и написал.

ursoft
Offline
Зарегистрирован: 08.02.2022

andriano пишет:
Во-первых, почему в одном случае 10 мс, а в другом - 8?

Потому что 10 - это с точки зрения прошивки материнской платы и её кварцевого генератора. А у ESP свой генератор и 8мс - это уже от него (чуть меньше не страшно, а вот чуть больше - уже смертельно, резко растет процент случаев "сработала не та кнопка"). Разница между ними не 20%, конечно. Я предполагаю, сформированный нами импульс имеет еще на конце небольшую переходную зону, и подобранное экспериментально уменьшение закрывает случаи, когда эта зона окажется за пределами 10мс и материнка словит чужую клавишу. Посмотреть на эту переходную кривую глазами цепочки доставки информации в PIC-процессор материнки я не могу, у меня щупы осциллографа не настолько мелкие (на выходе же с ESP32 она еще не сильно страшная).

andriano пишет:
А во-вторых, почему сами формируем импульс желаемой ширины, а не транслируем его со входа?

Сначала так и сделал: в глухом цикле отдельного высокоприоритетного потока - что прочитал, то и сразу же наружу выдал. И в лучшем алгоритме (когда перед чтением выход опять становится INPUT) получил примерно в 30% случаев неправильную кнопку с точки зрения материнки (то ли виноват вышеупомянутый переходный процесс, то ли дело в том, что контроллером в других потоках активно выполняется множество другой работы по Bluetooth, которую тоже надо делать очень вовремя, т.е. моё "тут же выдал" получает вредную задержку). А текущий алгоритм даёт сильно меньше (навскидку до 1%) ошибок. При этом ему требуется 5 циклов по 10+40мс для срабатывания, и в 9 случаях из 10 кнопка успешно "нажимается" (у нажатия есть четкий побочный эффект - писк на материнке, но не только - пока не будем вдаваться в детали реализации Zwift BLE FTMS Controllable -> Schwinn 570u). А в оставшемся одном случае материнка отфильтровывает мои потуги. Если увеличить количество циклов до 6, то начинает срабатывать в 10/10, но иногда уже распознаются двойные нажатия (что куда хуже, чем 9/10 - т.к. непрожатие и отсутствующий побочный эффект довольно быстро приведут ESP к повтору итерации и результат таки будет достигнут).

А в худшем алгоритме (тупое копирование входа на выход) получил, что моя выдача HIGH (без последующего переключения входа на INPUT) так влияет на вход, что с него тоже читается HIGH (даже далеко за пределами меандра) -> получаем вредный множественный автоповтор своей и чужих кнопок: материнка сперва несколько раз пищит, а потом даже может сказать "запала кнопка в состояние нажата всегда/надолго и давайте чините изделие, а я пока клавиатуру отключу до перезагрузки".

UPD: https://github.com/ursoft/ANT_Libraries/blob/master/ANT_DLL/WROOM_esp32/WROOM_esp32.ino
повторил ссылку для тех, кто порчу не сможет из стартового сообщения убрать

rkit
Offline
Зарегистрирован: 23.11.2016

Если у тебя нет осциллографа реально посмотреть и измерить что происходит, то поставь оптопары и не мучься.

ursoft
Offline
Зарегистрирован: 08.02.2022

Вот так ?

ursoft
Offline
Зарегистрирован: 08.02.2022

rkit пишет:
Если у тебя нет осциллографа реально посмотреть и измерить что происходит, то поставь оптопары и не мучься.

Осциллограф есть, но мучения будут попасть его щупами в ногу контроллера или другую микруху, что на плате.
Большое спасибо за наводку про оптопары - поставил как на схеме сверху, ограничив ток c GPIO резистором. Работает идеально, программа сильно упростилась:

https://github.com/ursoft/ANT_Libraries/commit/abdc2ecc0fac9a9de20f8dbf3...

Материнка изделия все равно как-то понимает, что её "взломали" - зажигает красный светодиод, если от нее запитаны ESP32 с джойстиком. Но в ошибку не уходит, работает как надо. Возможно, этот светодиод просто отражает факт подключения потребителя (которым штатно выступает, например, тестовый стенд ОТК производителя материнки). В инструкции сказано, что к изделию по USB снаружи вообще можно подключать потребителей до 1А - так что я, хоть и подключился изнутри, проблем не вижу.