Выключатель Gira + Z-Wave. 4-х кнопочный радио выключатель на базе Z-Uno

2783f9c517a540e3b6e75aa189ebbec8.png

Какие задачи решает радио выключатель:

  • В комнате с готовым ремонтом переместили мебель, шкафом закрыли выключатель
  • На этапе ремонта не продумали удобный выключатель около кровати
  • В доме из бруса не эстетично тянуть наружную проводку, требуются радио выключатели, но с конкретным дизайном
  • Интеграция с существующей системой автоматизации


На данный момент существуют Z-Wave выключатели на батарейках, например Z-Wave.Me Wall Controller, но эти выключатели идут с определенным дизайном клавиш. Если вы хотите использовать выключатели Legrand, Gira и др., то тут на помощь приходит Z-Wave плата Z-Uno.
Я покажу как из обычно выключателя Gira сделать радио выключатель на батарейках, который можно установить в любое удобное место. Видео работы выключателя в конце статьи.
Я использую механизм выключателя Gira для жалюзи с 4 кнопками и фиксацией в середине. Дизайн клавиш и рамки выбрал из серии System 55 только потому, что в линейке Z-Wave выключателей на батарейках есть рамки в таком же дизайне.
d9d263efc0104bd2853b521cbbdaf0bc.gif
Добавление новых функций к Z-Uno происходит постоянно, и в последнем релизе был добавлен KeyScanner, который позволяет обрабатывать нажатия от 112 кнопок одновременно, я ограничусь считыванием 4 кнопок от выключателя.
В приведенном ниже скетче Z-Uno в спящем режиме ожидает нажатия одной из кнопок, после нажатия Z-Uno просыпается и отправляет радио команду, после чего сразу же засыпает, чтобы не расходовать заряд батареи.
01d9b780d134467db676c55004f9bdd5.png

Скетч 4-х кнопочный радио выключатель на базе Z-Uno
// KeyPad 1x4
#include 
// Count of rows
#define ROWS  1
// Count of columns
#define COLS  4

// Set rows pins
BYTE rowPins[1] = {17};
// Set columns pins
BYTE columnPins[4] = {9, 10, 11, 12};

// Create object KeyPad
ZMEKeypad kpd = ZMEKeypad(columnPins, COLS, rowPins, ROWS);

#define CONTROL_GROUP1 1  // number of Association Group 
#define CONTROL_GROUP2 2  // number of Association Group
#define SWITCH_ON 0xff
#define SWITCH_OFF 0

// Start holding flags for 4 buttons
byte button_0_start_holding = TRUE;
byte button_1_start_holding = TRUE;
byte button_2_start_holding = TRUE;
byte button_3_start_holding = TRUE;

ZUNO_SETUP_ASSOCIATIONS(ZUNO_ASSOCIATION_GROUP_SET_VALUE_AND_DIM, ZUNO_ASSOCIATION_GROUP_SET_VALUE_AND_DIM); // Send Turn On/Off and Dim commands to associated devices
ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_SLEEPING); // SLEEPING MODE

void setup() {
  zunoSetupKeyScannerWU(4); // turn INT1 wakeup into Key Scanner mode with two columns: pins 9 and 10
  // can also be called in any other place before zunoSendDeviceToSleep()
  kpd.begin();
  kpd.setHoldTime(50); // 100 ms for detect hold button, 10 = 100 ms
  kpd.setDebounceTime(2); // 20 ms debounce, 2 = 20 ms
}

void loop() {
  byte actions[4]; // Array that return all actions from keypad (hold, release, press, double press, etc.)
  byte go_to_sleep = FALSE; // go to sleep after button released;
  
  // Default value for buttons - inactive, then read real states
  byte button_0_active = FALSE;
  byte button_1_active = FALSE;
  byte button_2_active = FALSE;
  byte button_3_active = FALSE;

  byte num_touched_keys = kpd.scanKeys(actions);
  if (num_touched_keys) {
    bool hold = KEYPAD_IS_HOLDING(actions[0]);
    switch (KEYPAD_KEYINDEX(actions[0])) {
      case 0: // Button Left Down
        button_0_active = TRUE;
        if (hold && button_0_start_holding) { // If button 0 start holding
          button_0_start_holding = FALSE;
          zunoSendToGroupDimmingCommand(CONTROL_GROUP1, TRUE, TRUE); // start dimming down (group, direction, start_stop)
        }
        if (!hold) { // If button 0 not holding
          go_to_sleep = TRUE;
          zunoSendToGroupSetValueCommand(CONTROL_GROUP1, SWITCH_OFF);  
        }
        break;
      case 1: // Button Left Up
        button_1_active = TRUE;
        if (hold && button_1_start_holding) { // If button 1 start holding
          button_1_start_holding = FALSE;
          zunoSendToGroupDimmingCommand(CONTROL_GROUP1, FALSE, TRUE); // start dimming up (group, direction, start_stop)
        }
        if (!hold) { // If button 1 not holding
          go_to_sleep = TRUE;
          zunoSendToGroupSetValueCommand(CONTROL_GROUP1, SWITCH_ON);
        }
        break;
      case 2: // Button Right Down
        button_2_active = TRUE;
        if (hold && button_2_start_holding) { // If button 2 start holding
          button_2_start_holding = FALSE;
          zunoSendToGroupDimmingCommand(CONTROL_GROUP2, TRUE, TRUE); // start dimming down (group, direction, start_stop)
        }
        if (!hold) { // If button 2 not holding
          go_to_sleep = TRUE;
          zunoSendToGroupSetValueCommand(CONTROL_GROUP2, SWITCH_OFF);
        }
        break;
      case 3: // Button Right Up
        button_3_active = TRUE;
        if (hold && button_3_start_holding) { // If button 3 start holding
          button_3_start_holding = FALSE;
          zunoSendToGroupDimmingCommand(CONTROL_GROUP2, FALSE, TRUE); // start dimming down (group, direction, start_stop)
        }
        if (!hold) { // If button 3 not holding
          go_to_sleep = TRUE;
          zunoSendToGroupSetValueCommand(CONTROL_GROUP2, SWITCH_ON);
        }
        break;
    }
  }

  if(!button_0_start_holding && !button_0_active) { // If button 0 release holding
    button_0_start_holding = TRUE;
    zunoSendToGroupDimmingCommand(CONTROL_GROUP1, TRUE, FALSE); // stop dimming down (group, direction, start_stop)
  }
   if(!button_1_start_holding && !button_1_active) { // If button 1 release holding
    button_1_start_holding = TRUE;
    zunoSendToGroupDimmingCommand(CONTROL_GROUP1, FALSE, FALSE); // stop dimming up (group, direction, start_stop)
  }
   if(!button_2_start_holding && !button_2_active) { // If button 2 release holding
    button_2_start_holding = TRUE;
    zunoSendToGroupDimmingCommand(CONTROL_GROUP2, TRUE, FALSE); // stop dimming down (group, direction, start_stop)
  }
   if(!button_3_start_holding && !button_3_active) { // If button 3 release holding
    button_3_start_holding = TRUE;
    zunoSendToGroupDimmingCommand(CONTROL_GROUP2, FALSE, FALSE); // stop dimming up (group, direction, start_stop)
  }

  // if all buttons released
  if (kpd.isIdled()) {
    go_to_sleep = TRUE;
  }

  if (go_to_sleep) {
    zunoSendDeviceToSleep();  
  }
}
// Для правильной работы этого скетча на версии Z-Uno 2.0.6 требуется в файле /Volumes/Files/user/Library/Arduino15/packages/Z-Uno/hardware/zw8051/2.0.6/libraries/ZMEKeypad/ZMEKeypad.h добавить "BYTE isIdled(){return mon_keys == 0;};" после строки 55 



На каждую из 4-х кнопок с помощью ассоциаций настраивается получатель радио команды, это может быть реле, диммер, RGBW лента, LED лампа или другое исполнительное устройство. В скетче я создаю 2 группы ассоциаций для управления 2-мя устройствами, верхние кнопки отправляют команды включения, нижние кнопки отправляют команды выключения.
f511cdfafd374a05ac4ca1c90d1fb294.png

К пинам Z-Uno 1,2,3,4 подключаем механизм выключателя GIRA. В комплекте с Z-Uno идет штекер, его я припаял к батарейному отсеку ½ AA и подключил в разъем для аккумулятора. Батарейка 1/2AA (ER14250) компактная, емкая, 3.6 В, но можно использовать и 2 батарейки AA, они тоже отлично влезают в подрозетник. Кстати, подрозетники рекомендую 60 мм глубиной, с ними удобнее работать, в 40 мм подрозетник затолкать Z-Uno с батарейкой, проводами и самим выключателем сложно, но можно!
f6218f5b70ee483b8fb33f947a0f7643.jpg
1e3ba74d2bac4c46a683262aed4d7095.jpg
2 правые кнопки управляют розеткой, отправляют команды ВКЛ и ВЫКЛ на розетка Z-Wave.Me.

2 левые кнопки управляют диммером, при коротком нажатии отправляются команды ВКЛ и ВЫКЛ, при долгом удержании ВВЕРХ или ВНИЗ отправляются команды диммирования на диммер Z-Wave.Me.

Как видите батареечное устройство считывающее состояние кнопок с помощью Z-Uno делается очень просто, и таким способ можно к Z-Uno подключить целую клавиатуру, где каждая кнопка будет выполнять полезную функцию вашего умного дома.


Видео работы батареечного выключателя на базе Z-Uno. Управление диммером и реле.

© Geektimes