Espruino:Примеры/Однокнопочный замок

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Однокнопочный замок[1]

Очевидно, что для создания электронного замка идеально подходит кнопочная панель. Но что если вам не хочется возиться с проводами, вы ограничены в пространстве или вообще хотите спрятать дверь. В этом случае можно воспользоваться всего одной кнопкой и с её помощью ввести код по принципу, схожему с азбукой Морзе. Этим мы в этой статье и займёмся.

Нам понадобится

Подсоединение

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

Код

Первый шаг – это создание ответа на нажатие на кнопку. Подключитесь к Espruino и вставьте код ниже в левую часть Web IDE:

function buttonWatcher(e) {
  console.log(e.time);
}
setWatch(buttonWatcher, BTN, {edge:"falling", repeat:true});

Нажмите на кнопку (на ту, что находится вдали от USB-коннектора, потому что та, что ближе к нему, выполняет сброс платы). Когда вы её отпустите, Espruino должна напечатать время (согласно Espruino) того, когда была нажата кнопка. Иногда время будет печататься несколько раз – из-за дребезга контактов. Дело в том, что сама кнопка механическая, и иногда её контакты «дребезжат» после нажатия или отпускания кнопки, в результате чего она несколько раз очень быстро включается и выключается. Нам нужно определять этот дребезг и избавляться от него.

Вставьте в Web IDE код ниже. Он изменяет функцию, вызываемую при нажатии на кнопку – теперь она не печатает время в консоли, а измеряет время между нажатиями, и если это время больше 0.1 секунд, то печатает в консоли сообщение «Зарегистрировано нажатие!»

var lastPress = 0;
function buttonWatcher(e) {
  var timeDiff = e.time - lastPress;
  lastPress = e.time;
  console.log(timeDiff);
  if (timeDiff>0.1) console.log("Зарегистрировано нажатие!");
}

Теперь давайте создадим функцию onPress(), которая будет вызываться при нажатии на кнопку. Она считает количество нажатий, но если с момента последнего нажатия пройдёт больше одной секунды, она этот счётчик нажатий обнулит.

var lastPress = 0;
// Количество нажатий на кнопку:
var pressCount = 0;
// Таймаут, срабатывающий спустя секунду после нажатия:
var timeout;

function onTimeout() {
  timeout = undefined;
  pressCount = 0;
  console.log("Таймаут!");
}

function onPress(timeDiff) {
  pressCount++;
  console.log(pressCount);

  // Если у нас остался таймаут от другого нажатия, удаляем его:
  if (timeout) clearTimeout(timeout);
  // Спустя одну секунду после текущего нажатия запускаем onTimeout():
  timeout = setTimeout(onTimeout, 1000);
}

function buttonWatcher(e) {
  var timeDiff = e.time - lastPress;
  lastPress = e.time;
  if (timeDiff>0.1) onPress(timeDiff);
}

setWatch(buttonWatcher, BTN, {edge:"falling", repeat:true});

Теперь нажимаем на кнопку несколько раз. Код начнёт отсчитывать количество нажатий, но если вы в течение одной секунды не будете нажимать на кнопку, в консоли будет напечатано сообщение «Таймаут!», и счётчик будет сброшен. Теперь давайте сделаем кодовый замок, изменив код в функции onTimeout().

var code = [3,1,2]; // код, который надо ввести, чтобы открыть замок
var digit = 0;      // то, на какой цифре кода мы находимся

function setLocked(isLocked) {
  // Включаем красный или зелёный светодиод
  // в зависимости от того, правильный ли введён код или нет:
  digitalWrite([LED1,LED2,LED3], isLocked ? 0b100 : 0b010);
  // Спустя две секунды выключаем светодиод:
  setTimeout(function() {
    digitalWrite([LED1,LED2,LED3], 0);
  }, 2000);
}

function onTimeout() {
  timeout = undefined;
  // Проверяем вводимый код:
  if (pressCount == code[digit]) {
    digit++; // переходим к следующей цифре
    if (digit >= code.length) {
      console.log("Вот и конец кода – открываем!");
      setLocked(false);
      // Снова переходим в начало кода:
      digit = 0;
    } else {
      console.log("Правильная цифра – переходим к следующей!");
    }
  } else {
    console.log("Неправильно! Возвращаемся в начало");
    setLocked(true);
    digit = 0;
  }
  pressCount = 0;
}

Вот и всё! Теперь, если вы введёте с помощью кнопки код вроде...

[нажатие] ... [нажатие] ... [нажатие], ждём секунду, [нажатие], ждём секунду, [нажатие] ... [нажатие]

...на плате на 2 секунды загорится зелёный светодиод, что будет означать, что код верный. Если вы ошибётесь, загорится красный светодиод.

Вы можете без труда поменять (замковый) код в (программном) коде и даже его размер, просто отредактировав строчку с массивом code[]. Например, вот так:

code = [5,1,3,4];

Итоговый код

Если вы просто хотите ввести код в правую часть IDE, так целиком он выглядит вот так:

var lastPress = 0;
var pressCount = 0;
var timeout;
var code = [3,1,2];
var digit = 0;

function setLocked(isLocked) {
  // Включаем красный или зелёный светодиод
  // в зависимости от того, правильный ли был введён код или нет: 
  digitalWrite([LED1,LED2,LED3], isLocked ? 0b100 : 0b010);
  // Спустя две секунды выключаем светодиод:
  setTimeout(function() {
    digitalWrite([LED1,LED2,LED3], 0);
  }, 2000);
}

function onTimeout() {
  timeout = undefined;
  // Проверяем вводимый код:
  if (pressCount == code[digit]) {
    digit++; // переходим к следующей цифре
    if (digit >= code.length) {
      console.log("Вот и конец кода – открываем!");
      setLocked(false);
      // Снова переходим в начало кода:
      digit = 0;
    } else {
      console.log("Правильная цифра – переходим к следующей!");
    }
  } else {
    console.log("Неправильно! Возвращаемся в начало");
    setLocked(true);
    digit = 0;
  }
  pressCount = 0;
}

function onPress(timeDiff) {
  pressCount++;
  console.log(pressCount);
  // Если у нас остался таймаут от другого нажатия, удаляем его:
  if (timeout) clearTimeout(timeout);
  // Спустя одну секунду после текущего нажатия запускаем onTimeout():
  timeout = setTimeout(onTimeout, 1000);
}

function buttonWatcher(e) {
  var timeDiff = e.time - lastPress;
  lastPress = e.time;
  if (timeDiff>0.1) onPress(timeDiff);
}

setWatch(buttonWatcher, B12, { repeat:true, edge:'falling' });

Что дальше

Далее можно запрограммировать то, что будет делать замок после того, как вы введёте правильный код. Для этого нужно отредактировать функцию setLocked(). Например, вы можете подключить к контакту B13 серводвигатель и написать в коде следующее:

function setLocked(isLocked) {
  // Включаем красный или зелёный светодиод
  // в зависимости от того, правильный ли был введён код или нет: 
  digitalWrite([LED1,LED2,LED3], isLocked ? 0b100 : 0b010);
  // Спустя две секунды выключаем светодиод:
  setTimeout(function() {
    digitalWrite([LED1,LED2,LED3], 0);
  }, 2000);
  // Теперь управляем серводвигателем.
  // Передаём ему импульсы в течение одной секунды (50 х 20 мс),
  // чтобы переместить его на новое место: 
  var servoPos = isLocked ? 0 : 1;
  var servoPulses = 0;
  var interval = setInterval(function() {
    digitalPulse(B13, 1, 1+servoPos);
    servoPulses++;
    if (servoPulses>50) clearInterval(interval);
  }, 20);
}

См.также

Внешние ссылки