Как сделать пульт для умной сигнализации с помощью Arduino
Для проекта нам понадобятся:
- Arduino или аналог;
- радиопередатчик на частоте 433 МГц;
- осциллограф или логический анализатор;
- тактовые кнопки;
- резисторы номиналом 10 кОм;
- соединительные провода;
- компьютер со средой разработки Arduino IDE или иной.
1 Изучение работы домашней сигнализации
Вы приобрели «умную» сигнализацию для дома или гаража. Ей можно управлять по Wi-Fi или GPRS/3G/4G через специальное приложение, а также через пульт дистанционного управления. Но вот незадача: в комплекте всего один пульт (брелок) ДУ, а вам нужно несколько – для каждого члена семьи.
Что делать? Можно купить у продавца сигнализации ещё один пульт. Но не все продавцы идут на это. Кроме того, отдельно брелок будет стоить существенную сумму по сравнению со стоимостью самой сигнализации. Можно сделать такой пульт самому. Тем более что, как правило, работают они очень просто. Такие сигнализации существуют лишь для спокойствия хозяина, и доверять им охрану серьёзных объектов я бы не стал. В том, как легко можно самому собрать альтернативный пульт, мы сейчас убедимся.
Для начала необходимо, конечно же, вскрыть оригинальный пульт, чтобы увидеть, на каком принципе он работает, а также изучить систему его команд. В моём примере пульт ДУ имеет всего 4 кнопки, которые соответствуют 4-м командам: поставить на охрану, снять с охраны, экстренное срабатывание (SOS), охрана дома.
После вскрытия пульта обнаружим, что он работает по радио на частоте 433 МГц. Это понятно, например, по кварцевому резонатору R433. Необходимо снять осциллограммы всех управляющих сигналов вашей сигнализации. Для этого нужно найти вход антенны и подключить к нему осциллограф или логический анализатор. Далее, нажимая кнопки пульта, установить соответствие кнопок командам. В данном примере вот осциллограмма сигнала "SOS":
А вот осциллограмма сигнала "LOCK":
Бывает, что команда может периодически меняться, например, через определённое число нажатий на кнопку. Это добавляет системе устойчивости ко взлому злоумышленником. Но в простейших или бюджетных системах команды обычно не меняются.
В моём случае команда не меняется. При каждом нажатии на кнопку формируется 3 одинаковых пакета импульсов с паузами между ними в ~12 мс. Видно, что есть только 2 типа импульсов: длинные и короткие. Длительность короткого импульса ~0.5 мс, длинного ~1.5 мс. Передача одного бита (импульс + пауза после него) занимает около 2 мс.
Каждый пакет состоит из 25-ти импульсов. Предположим, что каждый импульс представляет собой один бит. И допустим, что короткий импульс – это "1", а длинный – "0". Тогда можно записать передаваемую команду в двоичном виде как 1_01010010_10001000_11111101 В шестнадцатеричном виде это будет 0x15288FD, которые можно представить массивом из 4-х байтов {0x01,0x52,0x88,0xFD}.
Если сравнить между собой все четыре команды, то можно заметить, что команды отличаются только последним байтом. Для нас это не имеет значения, просто наблюдение. В принципе, это всё, что нужно знать, чтобы сделать собственный «пультозаменитель».
2 Схема и скетч самодельного пульта для домашней сигнализации
Схема будет предельно простой: Arduino по одному проводу будет управлять радиопередатчиком, а ещё по четырём будет опрашивать нажатия тактовых кнопок. При обнаружении нажатия будет отправлять соответствующую команду на радиопередатчик. Кнопку мы уже много раз подключали. Напомню, что кнопка должна подключаться с подтяжкой через резистор к земле или к питанию, иначе будут непроизвольные срабатывания.
На всякий случай, вот ссылка на базовую статью про подключение кнопки к Arduino.
Также желательно обрабатывать нажатие кнопки специальным образом, чтобы избежать влияния т.н. дребезга контактов. В данном случае обойдёмся без него, т.к. повторные срабатывания тут не играют роли.
Итак, скетч у нас получится довольно простой и короткий.
Скетч управления пультом ДУ для сигнализации (разворачивается)
#define radioTX 10 // управление передатчиком // 4 кнопки пульта: #define btnLock 9 #define btnUnlock 8 #define btnHome 7 #define btnSos 6 // Команды управления: byte LOCK[4] = {0x01,0x52,0x88,0xEF}; byte UNLOCK[4] = {0x01,0x52,0x88,0xYY}; // вместо YY будут значения вашей сигнализации byte HOME[4] = {0x01,0x52,0x88,0xFB}; byte SOS[4] = {0x01,0x52,0x88,0xFD}; void setup() { pinMode(btnLock, INPUT); pinMode(btnUnlock, INPUT); pinMode(btnHome, INPUT); pinMode(btnSos, INPUT); pinMode(radioTX, OUTPUT); digitalWrite(radioTX, LOW); pinMode(LED_BUILTIN, OUTPUT); // для индикации передачи digitalWrite(LED_BUILTIN, LOW); Serial.begin(115200); } void loop() { if (digitalRead(btnLock) == HIGH) { sendMessage(LOCK); blinkNum(1); Serial.println("LOCK"); } else if (digitalRead(btnUnlock) == HIGH){ sendMessage(UNLOCK); blinkNum(2); Serial.println("UNLOCK"); } else if (digitalRead(btnHome) == HIGH) { sendMessage(HOME); blinkNum(3); Serial.println("HOME"); } else if (digitalRead(btnSos) == HIGH) { sendMessage(SOS); blinkNum(4); Serial.println("SOS"); } } // Мигает заданное число раз (для индикации). void blinkNum(int num){ for (int i=0;i<num;i++){ digitalWrite(LED_BUILTIN, HIGH); delay(50); digitalWrite(LED_BUILTIN, LOW); delay(50); } } // Отправляет заданное сообщение: void sendMessage(byte message[]) { for (int t=0; t<3; t++) // отправляем команду трижды { // отправляем 1-ый бит команды отдельно, т.к. он "лишний" //(число битов команды не кратно числу битов в байте): bool b0 = message[0] & 1; sendBit(b0); // а затем каждый байт команды for (int i=1; i<4; i++) { for (int j=7; j>=0; j--) // поразрядно { bool b = (message[i] >> j) & 1; sendBit(b); // отправляем } } delay(12); // делаем задержку м/у повторами пакета } } // Отправляет 1 бит. void sendBit(bool b) { if (!b) // длинный импульс { digitalWrite(radioTX, HIGH); delayMicroseconds(1500); digitalWrite(radioTX, LOW); delayMicroseconds(500); } else // короткий импульс { digitalWrite(radioTX, HIGH); delayMicroseconds(500); digitalWrite(radioTX, LOW); delayMicroseconds(1500); } }
Проверим, как работает наш самодельный пульт.
Видно, что пульт ставит сигнализацию на охрану и снимает с неё. Всё работает!