У меня есть холодильник с очень крутой «фичей»: он пищит, если дверца открыта дольше, чем 60 секунд. В 95% случаев это больше раздражает, чем помогает. На мой взгляд, он просто должен заткнуться и считать, что мне виднее.

Чтобы поменять его поведение, я сначала попытался добраться до пьезодинамика, чтобы вырвать его с корнем. Оказалось, что это довольно бесплодное занятие, потому что основная плата встроена глубоко в холодильник. Я не особо готов отодвигать его от стены, чтобы добраться до платы, хоть и попробовал проползти к ней через панель управления, но без особого успеха:

Однако мне удалось добраться до дочерней платы, используемой в качестве панели управления холодильником.

Хакаем панель

Чтобы понять поверхность атаки и разобраться, можно ли как-то отключить сигнал, я выполнил реверс-инжиниринг панели управления. По сути, она имеет две функции:

  • Считывание кнопок (в том числе электромагнитный переключатель для определения состояния дверцы).

  • Управление светом.

Эти функции реализуются при помощи шестиконтактного разъёма на дочерней плате:

Этот разъём — последовательный интерфейс, позволяющий управлять двумя восьмибитными сдвиговыми регистрами (74HC595) на материнской плате:

Такая система позволяет холодильнику контролировать до 16 бит на дочерней плате; часть этих битов привязана к конкретным светодиодам на плате, другая часть используется для считывания состояния кнопок.

Каждая кнопка напрямую соединена с контактом OUT. Сначала это сбило меня с толку, потому что холодильник как будто не сможет определить, какая кнопка нажата в конкретный момент времени. Но здесь на помощь приходят сдвиговые регистры: кнопка не создаёт сигнала на OUT, если её бит в текущий момент не включен в сдвиговом регистре:

Таким образом, последовательность считывания кнопки имеет следующий вид:

  • Нажатие кнопок включает бит сдвигового регистра.

  • Считываем состояние контакта OUT.

  • Повторяем для каждой кнопки.

Мне удалось доказать это при помощи Raspberry Pi, притворившейся холодильником: я смог управлять светом:

И распознавать состояние кнопок:

Создание модчипа

После изучения панели управления я придумал пару способов потенциального отключения сигнала:

  • Автоматическое нажатие на отключение сигнала при его включении.

  • Убедить электромагнитный датчик, что холодильник закрыт.

Управление кнопкой отключения сигнала завело бы меня в тупик по следующим причинам:

  • Кнопка отключения сигнала не работает, пока не зазвучит сигнал.

  • При нажатии кнопка издаёт собственный звук, то есть если бы мы нажимали её по таймеру, то просто поменяли бы один шум на другой.

  • У панели управления нет обратной связи о том, когда звучит сигнал, поэтому мы не можем распознать его и нажимать на кнопку.

Перехват электромагнитного датчика выглядел более перспективно, но один из недостатков такого способа заключается в том, что когда холодильник находится в состоянии «дверца закрыта», его внутреннее освещение отключается.

Чтобы обойти эту проблему, я решил ждать максимально долго (примерно 59 секунд), а затем просто примерно 100 мс сообщать холодильнику, что дверцу закрыли.

Изначально я хотел использовать для модчипа микроконтроллер, но описанная выше система — это, по сути, цепь таймера. Поэтому нужную нам функциональность можно реализовать на простом таймере 555.

Таймер 555

Таймер 555 в автоколебательном режиме — это именно то, что нам нужно. Под «автоколебательностью» подразумевается, что 555 колеблется в цикле между включенным и отключенным состоянием. Временем, проводимым во включенном и отключенном состоянии, можно управлять при помощи пары резисторов (r_1​ и r_2​) и конденсатора (c).

Для вычисления времени в отключенном состоянии (t_0​) можно использовать формулу:

t_0​=0.694⋅r_2​⋅c

Время во включенном состоянии (t_1​) вычисляется так:

t_1​=0.694⋅(r_1​+r_2​)⋅c

В идеале нам нужно следующее:

t_0​=59000 ms, t_1​=100 ms

Но приведённые выше вычисления демонстрируют проблему: по умолчанию схема позволяет выбирать рабочий цикл в интервале 50% - 100%. Даже если сделать r_1​ минимальным (220 Ом), то мы получим рабочий цикл примерно 50%:

Решить эту проблему можно, добавив параллельно r_2​ диод, который позволит нам достичь рабочего режима в интервале от 0% до 50%:

 

Добавление диода меняет формулу вычисления t_0​ и t_1​:

t_0​=0.694⋅r_2​⋅c, t_1​=0.694⋅r_1​⋅c

Обратите внимание, что теперь t_1​ больше не зависит от значения r_2​.

Я остановился на следующих значениях резисторов и конденсатора:

r_1​=220 Ω, r_2​=300 kΩ, c=220 μF

Подставив эти значения в формулу, мы получим:

t_0​=0.694⋅300000⋅220⋅10−6=45804 mst_1​=0.694⋅220⋅220⋅10−6=48 ms

Это достаточно близко к тому, что нам нужно, поэтому я изготовил модчип с теми же значениями r_1​, r_2​ и c:

Затем я написал короткий скрипт time-delta.py для определения реального времени в отключенном состоянии в тестовой цепи. На самом деле, получилось даже ближе к нужному нам времени (около 59 секунд):

> python3 time-delta.py
avg=56.970      min=55.283      max=58.160

Идеально! Осталось только хорошенько обернуть всё это каптоновой лентой и снова засунуть в холодильник:

Вот видео того, как модчип на короткий промежуток времени подаёт высокий сигнал на электромагнитный датчик:

Победа! Мы научились общаться с холодильником и приказали ему перестать выполнять одну задачу.

Дополнительные ресурсы

Скрипты на Python