Нет, кнопка не рассыпалась в прах, как пророчествовал один из комментаторов. И вообще никто из присутствующих не угадал судьбы многострадальной мышки, хотя, как я сейчас понимаю, она была чуть ли не очевидной.
По наводке уважаемого ploop я открыл для себя программу xev, которая в числе прочего показывает, какие кнопки нажаты. Нажимаю я правую кнопку и вижу:
ButtonPress event, serial 56, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 3959640285, (43,112), root:(1109,578), state 0x10, button 1, same_screen YES ButtonPress event, serial 56, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 3959640285, (43,112), root:(1109,578), state 0x110, button 3, same_screen YES ButtonRelease event, serial 56, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 3959640436, (43,112), root:(1109,578), state 0x510, button 3, same_screen YES ButtonRelease event, serial 56, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 3959640452, (43,112), root:(1109,578), state 0x110, button 1, same_screen YES
То есть всякий раз, когда я нажимаю правую кнопку (3), мышь думает, что нажата ещё и левая кнопка (1)! На этом месте я вспомнил, что после переделки этой мышью стало невозможно вызвать контекстное меню в заголовке окна Хрома. Тогда я не придал этому значения, ибо приблизительно в тот же период времени отвалилось и перемещение по истории кнопками «вперёд-назад», причём только на Хабре/ГТ и только у второй мышки, с которой я (мамой клянусь) ничего не делал.
Выпаяв конденсатор, я убедился — действительно, в нажатии лишней кнопки виновен именно он. А это ставило крест на всей идее панацеи от дребезга из предыдущего поста. Поскольку выбирать между хабрасуицидом и сделкой с совестью не хотелось, пришлось думать, как побороть сей пренеприятнейший побочный эффект. Так что снова разбираем мышь, врубаем осциллограф и попытаемся достичь того самого понимания, которого нам так не хватило в прошлый раз.
Мышь оказалась основана на известном в народе микроконтроллере nRF24LE1.
Путём прозвонки было установлено, что все выводы выключателей идут прямиком к ногам процессора, причём каждая такая нога связана более чем с одним выключателем. Если точнее, то схема вырисовывается такая:
(Кнопка со звёздочкой означает кнопку смены dpi, которая на выход мыши не проходит.)
Это позволяет заподозрить авторов в применении приёма под названием «матричная клавиатура». На сканирующие ноги поочерёдно подаётся сигнал и смотрится, на каких считывающих ногах он появился. Это позволяет экономить ноги — ведь кнопок таким образом можно поставить пропорционально квадрату числа используемых ног. (В данном случае у нас 6 кнопок и 5 выводов — то есть экономится целая одна нога. Впрочем, колесо я прозвонить забыл, так что не исключено, что эта же схема обслуживает и колесо, тогда получается экономия ажно двух ног.)
Но пока что это лишь предположение, надо его проверить.
На P0 подаётся импульс длительностью 20 микросекунд (отмечен стрелочкой), который по замкнутому выключателю приходит на ногу A. Здесь этого не видно, но промежуток между импульсами составляет около 10-15 миллисекунд. А значит, программная защита от дребезга всё же присутствует, и становится непонятно, как так получается, что она не помогает. Но вернёмся к нашим баранам и отпустим кнопку:
Как мы и ожидали, сканирующий сигнал на считывающей ноге пропадает. А теперь нажмём левую и правую кнопки одновременно:
И снова в полном соответствии с ожиданиями у нас на выходе появляется два сигнала с двух ног, разделённые во времени. Если теперь нажать и среднюю кнопку, то будет три сигнала, которые сольются в одну большую чёрточку.
А как же получается, что при двух нажатых кнопках сканирующие ноги не закорачиваются друг с другом и не портят друг другу сигнал? В упомянутой статье для этого предлагается использовать диоды. Здесь же всё проще — когда нога неактивна, она переводится в режим Hi-Z (высокого сопротивления), то есть фактически отключается от цепи, и тока по ней не идёт. Как свидетельство в пользу этого — если при разомкнутых кнопках неосторожно коснуться сканирующего порта, то осциллограф покажет характерную «шерсть» (то есть помехи из радиоэфира, принятые нашим телом):
Чтобы окончательно подтвердить нашу догадку, поставим эксперимент. Если нажатие кнопок регистрируется по повышению напряжения, то если замкнуть сканирующий порт на питание, мышь это должна воспринять как нажатие всех кнопок, находящихся на этом порту.
ButtonPress event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940208, (547,509), root:(1297,734), state 0x10, button 6, same_screen YES ButtonRelease event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940208, (547,509), root:(1297,734), state 0x10, button 6, same_screen YES ButtonPress event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940208, (547,509), root:(1297,734), state 0x10, button 1, same_screen YES ButtonPress event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940208, (547,509), root:(1297,734), state 0x110, button 3, same_screen YES ButtonPress event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940208, (547,509), root:(1297,734), state 0x510, button 2, same_screen YES ButtonRelease event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940253, (547,509), root:(1297,734), state 0x710, button 2, same_screen YES ButtonRelease event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940268, (547,509), root:(1297,734), state 0x510, button 1, same_screen YES ButtonRelease event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059940268, (547,509), root:(1297,734), state 0x410, button 3, same_screen YES
ButtonPress event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059977818, (172,409), root:(922,634), state 0x10, button 7, same_screen YES ButtonRelease event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059977818, (172,409), root:(922,634), state 0x10, button 7, same_screen YES ButtonPress event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059977818, (172,409), root:(922,634), state 0x10, button 8, same_screen YES ButtonPress event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059977818, (172,409), root:(922,634), state 0x10, button 9, same_screen YES ButtonRelease event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059977950, (172,409), root:(922,634), state 0x10, button 8, same_screen YES ButtonRelease event, serial 166, synthetic NO, window 0xb200001, root 0x274, subw 0x0, time 4059977950, (172,409), root:(922,634), state 0x10, button 9, same_screen YES
Снова всё так, как мы предполагали, плюс обнаружились «пасхальные» кнопки 6 и 7, которых физически на мыши нет (колесо соответствует кнопкам 4 и 5).
Итак, мы познали истину о мыши и её кнопках. Но как это нам поможет справиться с нашей изначальной напастью? Для этого нам надо понять ещё две вещи — почему конденсатор задерживает отпускание кнопки и почему он способствует её нажатию при нажатии другой кнопки.
Когда мы замыкаем кнопку 1, конденсатор мгновенно разряжается, и напряжение на нём становится равным нулю. Пока кнопка нажата, конденсатор закорочен, так что мышь воспринимает нажатие кнопки так, как если бы конденсатора не было.
Теперь отпустим кнопку. Поскольку конденсатор обладает ёмкостью, напряжение на нём всё ещё равно нулю. А значит, если подать на P0 сканирующее напряжение (2,5 В питания), то и на входе A также будет 2,5 вольта, что соответствует нажатой кнопке.
Однако с каждым таким импульсом конденсатор понемногу будет заряжаться (через сопротивление R1). И в один прекрасный момент он зарядится, скажем, до 2 вольт, и на входе A будет уже 0,5 вольт, что недостаточно для появления на этом входе единицы. Стало быть, некоторое время после отпускания кнопки мышь будет думать, что кнопка ещё нажата, а затем «поймёт», что её отпустили.
Можно даже приблизительно оценить это время. Наша RC-цепочка состоит из сопротивления в 13 кОм и конденсатора, например, 0,1 мкФ. Перемножаем эти две величины и находим характерное время 1,3 миллисекунды. Но поскольку ток течёт не всё время, а лишь 20 микросекунд каждые 10 миллисекунд, это время растягивается до 0,65 секунды — как мы и намеряли в прошлый раз.
Можно было бы обрадоваться такому точному совпадению расчёта с экспериментом, но надо внести ещё ложку дёгтя. Дело всё в том, что характерное время — это время, за которое напряжение падает в число e, то есть в 2,7 раз. Но даташит на nRF24LE1 говорит нам, что Input high voltage равен 0,7 VDD, а Input low voltage 0,3 VDD. То есть входы нашего процессора работают как триггер Шмитта, и чтобы они восприняли единицу, нам надо поднять напряжение до 0,7 напряжения питания. Почему мы взяли 0,7, а не 0,3, спросите вы? Очень просто — поскольку основную часть времени на входе A чистый ноль, то в момент импульса нам надо поднять напряжение до 0,7 питания, иначе триггер Шмитта не переключится на единицу. Так что расчёт даёт время
ln(0,7) / ln(1/e) * 0,65 = 0,23 секунды.
А фактически у нас 0,6 секунды! Если вычесть время, когда кнопка замкнута — это 0,5 секунды, что всё равно много. Чтобы это объяснить, можно предположить, что в режиме Hi-Z сопротивление ноги P0 всё же не бесконечно, и «втихаря» подразряжает конденсатор в промежутке между измерительными импульсами. Очень грубо из наших данных можно оценить его величину — поскольку оно за 10 мс разряжает конденсатор на величину, сопоставимую с той, на которую он заряжается за 20 мкс, это сопротивление более 6,5 мегаом.
И здесь надо вспомнить ещё один факт, которому я не придал значения. А именно, если напаять конденсатор меньший, чем 2 нФ, то мышь будет думать, что кнопка нажата всегда. И теперь сей факт получает объяснение — за 10 миллисекунд конденсатор успевает разрядиться (2 нФ * 6,5 МОм = 13 мс), так что при импульсе триггер Шмитта срабатывает, а пока этот импульс идёт, конденсатор заряжается (2 нФ * 13 кОм = 26 мкс), но не успевает зарядиться до такой степени, чтобы преодолеть порог в 0,3 напряжения питания.
Теперь посмотрим, что будет, когда мы пожмём не левую, а правую кнопку.
В состоянии покоя на конденсаторе у нас 2,5 вольта. Замкнём выключатель 3, и на проводник A пойдут 20-микросекундные импульсы с порта P2. Но если на A 2,5 вольта плюс на конденсаторе 2,5 вольта, то на ноге P0 должно быть уже 5 вольт! А контроллер рассчитан не более чем на 3,6 вольт. Специально для таких случаев в микросхемах предусматривают защитные диоды, чтобы напряжение на входах не превышало напряжения питания:
Стало быть, как только на P2 появится напряжение питания, конденсатор разрядится через этот диод, и на нём будет уже 0,7 вольта, а то и меньше. А затем он ещё дополнительно разрядится через 6,5 мегаом. А когда настанет пора измеряющего импульса на ноге P0, напряжение на конденсаторе будет настолько мало, что на входе A будет почти полное напряжение питания и как следствие чёткая единица. Вот мы и получили нажатие левой кнопки при нажатии правой.
Теперь, наконец, мы ответили на все вопросы из разряда «кто виноват», осталась только самая малость — что делать? Поскольку корень нашей неприятности в разрядке конденсатора, поставим на пути этого тока преграду в виде диода:
Я нашёл первый попавшийся диод, припаял — и действительно, несанкционированные нажатия кнопки более не происходят. Вот только и задержка после отпускания левой кнопки исчезла. Как же так? А очень просто — как мы уже знаем, для срабатывания на входе A должно быть не менее 0,7 напряжения питания, то есть на всей связке «конденсатор+диод» должно быть не более 0,75 вольта. А на диоде, как известно, падает около 0,7 вольта, плюс ещё конденсатор — вот и не хватает напряжения.
Нам поможет диод Шоттки, прямое падение напряжение на котором заметно меньше, чем на обычном диоде.
К сожалению, я не смог найти у себя диодов Шоттки, поэтому я нашёл диод с наименьшим падением напряжения (мультиметр показывал 0,44 В) и напаял его чисто чтобы убедиться, что предложенное решение работает. Можете его поискать на КДПВ (подсказка — он чёрно-розовый). Пришлось также поднять напряжение питания до 3,3 В, но всё же желаемый эффект был достигнут! Задержка отпускания кнопки — целых 0,4 секунды, при этом ни одна кнопка не нажимается «за компанию». Правда, по очевидным причинам сию конструкцию пришлось разобрать, но главный вывод был сделан — диоды Шоттки спасут отца русской демократии.
Вот, собственно, и сказке конец.
УПД: Оказывается, и это не конец. В каментах справедливо указывают, что приведённая схема с диодом работать не может, ибо конденсатор не сможет разрядиться при замыкании кнопки. А работала она, видимо, только потому, что оный конденсатор разряжался через сопротивление щупа осциллографа, равное одному мегаому. Истинно правильной на сегодняшний день объявляется следующая схема:
То есть надо разрезать дорожку на плате, ведущую от выключателя к «сканирующей» ноге и впаивать диод в полученный разрез. Ну или не обязательно к сканирующей, главное — чтобы ток не мог течь к нашей сканирующей ноге ни от одной другой сканирующей ноги.
Наверное, писать третью статью по этой теме — это уже чересчур, так что ежели я соберусь эту схему экспериментально проверить, то здесь же допишу.
Комментарии (20)
ploop
28.08.2015 23:33Круто! Теперь осталось только переписать прошивку чипа, выделив каждой кнопке по ноге, и забыть про проблемы :)
KhodeN
29.08.2015 08:33+1Инженерный подход… Я бы сходил в магазин и купил нового грызуна
radiolok
29.08.2015 12:21+1ИМХО не дело это, когда из-за элемента за 1 условный рубль (энкодер, кнопка и т.п.) приходится выбрасывать целое ремонтопригодное устройство за 100 условных рублей.
Я на своей a4tech G10, например, механический энкодер разбирал и контакты подгибал, когда он аналогично глючить начал.KhodeN
29.08.2015 12:45Я понимаю, сам сто раз подгибал или перепаивал кнопку от донора. Но проводить такое исследование дороже мышки просто из расчета потраченного времени.
Понятно, что автор так делал больше по фану и ради интереса.wormball
29.08.2015 13:49+5Ну, собственно, исследование не так много времени заняло. На написание статьи я больше времени потратил. Ну и ежели статья поможет, например, 10 или 100 мышек вылечить — то тогда затраченное время окупится, по крайней мере с точки зрения «блага для человечества». Собственно, так любые научные исследования работают — кто-то тратит время на то, на что остальным тратить время жалко, а в результате получается информация, которая полезна заметно более, нежели затраченное на неё время.
Foreglance
31.08.2015 00:40+1Моя «исправленная» конденсатором мышка неделю работает и в Windows и в Linux — обе кнопки и колесо. Еще раз спасибо за прошлую статью.
Новое исследование тоже интерено было прочесть.
svd71
29.08.2015 14:33к указанным расчетам добавьте еще стоимость потраченного электричества. Ну и свое затраченное время во сколько вы оцениваете?
Хотя оценка своего времени просто «инженерного расчета» произведенных затрат. Ведь потраченное время принесло самое главное — головоломку для развития мозга, успешное решение и логически правильные выводы.
googol
29.08.2015 17:40+1Стоит добавить получение знаний как цель.
Одно дело бездумно пользоваться вещью, например летать на самолете. А другое дело разбираться в деталях как он работает для того чтобы этот самолет построить/отремонтировать.
DanilinS
29.08.2015 15:26К сожалению, я не смог найти у себя диодов Шоттки, поэтому я нашёл диод с наименьшим падением напряжения (мультиметр показывал 0,44 В)
Скорее всего это германий с падением напряжения около 0,4V,
AEP
29.08.2015 15:32+1Как это вообще может работать?
Конденсатор просто зарядится через диод до максимальной разности потенциалов, которая вообще бывает между контактами. И все. После этого диод просто никогда не откроется, и мы возвращаемся, по сути, к схеме, где конденсатора и диода нет вообще.wormball
29.08.2015 16:21Вашей закостенелой официальной науке этого никогда не понятьСейчас посмотрел, подумал — действительно, не должно вроде работать. Однако ж работало как-то.
Есть такая версия — диод немного пропускает в обратную сторону. Либо конденсатор сам разряжается. Хотя вроде сейчас померял — и у того, и у другого сопротивление более 2 МОм. Тогда, возможно, сыграли остатки флюса (что вряд ли) или осциллограф (у него ровно мегаом сопротивление).
Тогда вырисовывается исправление к предложенной схеме — надо параллельно диоду Шоттки напаять ещё сопротивление эдак в несколько сотен килоом. А ещё лучше — ставить диод не к конденсатору, а последовательно с выключателем-конденсатором, правда, тогда дороги на плате придётся резать.
ploop
30.08.2015 19:03Там на схеме есть сопротивление 13к (R1), через него кондёр заряжается. Разряжается через кнопку.
Упс… это уже новая схема.
kasperos
31.08.2015 11:46Все конденсаторы в типовых условиях имеют ток утечки, которого могло хватить на перезарядку для подавления дребезга.
Что касается непосредственно причины дребезга, то вероятней всего причина все-же сама кнопка, т.к. донором была другая но уже «списанная», которая изначально находилась в неопределенной ситуации.
В военную бытность приходилось заниматься ремонтом мышек, самое больное место это хвост (был один экземпляр с 50 см хвостом, благо системный блок на столе стоял), что касается кнопок то брали кнопку обычно с правой или средней (колесо) кнопки, так как они менее всего страдали в процессе эксплуатации (если конечно хозяин не левша).
Volutar
01.09.2015 10:11Ещё со времён самопальных джойстиков для Спектрума познал, как устранять дребезг на микриках ПМ24-2 — сошкрябать тонкой наждачкой окисл с контактных пластинок.
У меня мышь уже 8 лет живёт безо всяких перепаек и танцев с бубнами, проходя подобную процедуру примерно каждые год-два. Правда, там уже сами контактные пластины скоро поломаются, но дребезга-то нету!..
Когда мышь хорошая, и новые подобного уровня стоят под 10к — этот вопрос ремонта становится очень актуальным.
DeeZ
07.09.2015 13:32Вы серьзно потратили столько времени на кнопку? когда у меня начинается дребезг — я просто перепаиваю микрик (совет: берите правую кнопку с мышки донора. она менее изношена). даже не думал что про это можно 2 статьи написать :)))
За старание коненоч плюсик.
(картинка про батон и троллейбус)
dkukushkin
А не спасет ли отца русской демократии полевой транзистор?
wormball
Я так отчего-то не думаю. Куда затвор цеплять? Ежели на землю — то он всегда будет открыт, а ежели на питание — то он закроется при достижении порогового напряжения, а я сомневаюсь, что бывают транзисторы с оным напряжением менее 0,7 В. Конечно, не исключено, что можно изобрести такую извращённую схему, которая бы открывала его ровно тогда, когда надо, но это уже будет ситуация «овчинка выделки не стоит».