Устройство которое сможет надежно сохранить ваши ценности. Для открытия кодового замка необходимо ввести правильную последовательность чисел.
Описание работы:
Для начала работы подключите питание к Arduino. Загорится светодиод сигнализирующий об открытии сейфа, сервопривод повернут на 90 градусов. а на экране высветятся цифры от 0 до 99.
Для закрытия сейфа необходимо ввести кодовую последовательность, для этого вращайте потенциометры влево или вправо. Индикатор условно поделен пополам. Левую сторону индикатора регулирует потенциометр во 2 посадочной площадке. Правую сторону индикатора регулирует потенциометр в 6 посадочной площадке. Потенциометры регулируются в диапазоне от 0 до 99. После того, как вы выставили нужную последовательность, запомните ее и нажмите на кнопку. Светодиод погаснет, сервопривод повернется в 0 градусов, а сейф закроется. Установленная кодовая последователь на индикаторе мигнет три раза и высветятся другие числа.
Для того, чтобы открыть сейф необходимо ввести ту же самую последовательность и нажать кнопку. Устройство автоматически будет выключать экран когда вы закрыли сейф и ничего не будете настраивать (не крутите потенциометры и не нажимаете кнопку). Если вы введете неправильную последовательность индикатор мигнет три раза. Как только вы ввели правильную комбинацию, светодиод на кнопке опять загорится, а сервопривод повернется в 0 градусов, указывая но то, что замок открыт.
Закрыть замок -> установить код -> нажать кнопку -> светодиод погаснет.
Открыть замок -> установить код -> нажать кнопку -> светодиод зажжется.
Нам понадобится:
- Arduino Uno х 1шт.
- Trema Set Shield х 1шт.
- Trema-модуль потенциометр х 2шт.
- Trema-модуль кнопка со светодиодом, синяя х 1шт.
- Штыревой соединитель х 1шт.
- Сервопривод х 1шт.
Для реализации проекта нам необходимо установить следующие библиотеки:
- Библиотека iarduino_4LED для работы с Trema-модуль четырехразрядным LED индикатором.
- Библиотека Servo для работы с сервоприводами (библиотека входит в стандартный набор Arduino IDE).
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.
Схема сборки:
- Устанавливаем Trema Set Shield в Arduino Uno.
- Устанавливаем Trema-модуль Четырехразрядный LED индикатор в 4 посадочную площадку.
- Устанавливаем Trema-модуль кнопка с синем светодиодом в 1 посадочную площадку.
- Устанавливаем Trema-модуль потенциометр в 6 посадочную площадку.
- Устанавливаем Trema-модуль потенциометр во 2 посадочную площадку.
- Устанавливаем Сервопривод в 6 посадочную площадку, воспользуясь Штыревым соединителем.
- Полученный результат представлен на рисунке ниже.
Код программы:
#include <Servo.h> // Подключаем библиотеку Servo.
Servo servo; // Объявляем объект для работы с сервоприводом.
//
#include <iarduino_4LED.h> // Подключаем библиотеку iarduino_4LED.
iarduino_4LED dispLED(A2, 2); // Объявляем объект для работы с функциями библиотеки iarduino_4LED, с указанием выводов дисплея ( CLK , DIO ).
//
const uint8_t pinKeyPotLeft = A0; // Объявляем пин для работы с левым потенциометром.
const uint8_t pinKeyPotRight = A3; // Объявляем пин для работы с правым потенциометром.
//
const uint8_t pinKeyLedBlue = 10; // Объявляем пин для работы со светодиодом синей кнопки.
const uint8_t pinKeyBlue = 6; // Объявляем пин для работы с синей кнопкой.
const uint8_t pinServo = 11; // Определяем № вывода к которому подключён сервопривод.
//
const uint8_t dreb = 10; // Константа для подавления дребезга потенциометра.
//
int menu; // Переменная меню событий.
int Left; // Переменная значений левого потенциометра.
int Right; // Переменная значений правого потенциометра.
//
String LeftChar; // Переменная значений левого потенциометра в строковом формате.
String RightChar; // Переменная значений правого потенциометра в строковом формате.
String times; // Переменная значений потенциометров для вывода на индикатор.
//
uint8_t codeLeft; // Переменная для хранения кода с левого потенциометра.
uint8_t codeRight; // Переменная для хранения кода с правого потенциометра.
//
int prevLeft; // Переменная предыдущего значения левого потенциометра.
int prevRight; // Переменная предыдущего значения правого потенциометра.
//
int prevLeftDat; // Переменная предыдущего значения левого потенциометра без масштабирования.
int prevRightDat; // Переменная предыдущего значения правого потенциометра без масштабирования.
//
int i, k; // Переменные счета.
//
bool around = true; // Переменная события разрешает/запрещает изменение вывода значений потенциометров на индикаторе.
bool event = true; // Переменная события разрешает/запрещает нажатие кнопки.
long prevMicros; // Переменная предыдущих значений счетчика.
//
void ReadingValues(); // Функция чтения значения с потенциометров.
void ShowTime(); // Функция вывода значений на индикатор.
//
void setup() //
{ //
servo.attach(pinServo); // Присоединяем сервопривод к выводу pinServo.
pinMode(pinKeyBlue, INPUT); // Переводим вывод pinKeyBlue в режим входа.
pinMode(pinKeyLedBlue, INPUT); // Переводим вывод pinKeyLedBlue в режим входа.
dispLED.begin(); // Инициируем LED дисплей.
dispLED.light(7); // Устанавливаем максимальную яркость свечения LED индикатора.
menu = 1; // Задаем событие 1.
} //
//
void loop() //
{ //
switch(menu) // Переменная меню события.
{ //
case 1: // Событие 1.
ReadingValues(); // Функция чтения значения с потенциометров.
ShowTime(); // Функция вывода значений на индикатор.
if (digitalRead(pinKeyBlue) && event) // Если нажата кнопка и событие нажатие кнопки разрешено.
{ //
codeLeft = Left; // Сохраняем значения левого потенциометра.
codeRight = Right; // Сохраняем значения правого потенциометра.
menu = 2; // Разрешаем переход к событию 2.
around = !around; // Изменили событие.
} //
//
servo.write(90); // Устанавливаем сервопривод на 90 градусов.
digitalWrite(pinKeyLedBlue, HIGH); // Включаем светодиод на кнопке.
if (micros() - prevMicros > 1000000) {event = true;} // Если прошла секунда, разрешаем событие нажатие кнопки.
break; // Выходим из оператора case.
//
case 2: // Событие 2.
for (k = 0; k <= 3; k++) // В цикле осуществляем мигание.
{ //
dispLED.clear(); // Очищаем дисплей.
digitalWrite(pinKeyLedBlue, LOW); // Гасим светодиод на кнопке.
delay(500); // Задержка 500 мс.
//
ShowTime(); // Функция вывода значений на индикатор.
digitalWrite(pinKeyLedBlue, HIGH); // Зажигаем светодиод на кнопке.
delay(500); // Задержка 500 мс.
} //
digitalWrite(pinKeyLedBlue, LOW); // Гасим светодиод на кнопке.
servo.write(0); // Устанавливаем сервопривод на 0 градусов.
menu = 3; // Разрешаем переход к событию 3.
prevLeftDat = 0; // Обнуляем переменную значений с левого потенциометра без масштабирования.
prevRightDat = 0; // Обнуляем переменную значений с правого потенциометра без масштабирования.
break; // Выходим из оператора case.
//
case 3: // Событие 3.
ReadingValues(); // Функция чтения значения с потенциометров.
ShowTime(); // Функция вывода значений на индикатор.
if (Right == prevRight && Left == prevLeft){i++;} // Если предыдущее значение потенциометра равно новому, то увеличиваем переменную счета.
else{i = 0;} // Если не равно, обнуляем переменную счета.
prevLeft = Left; // Сохраняем новое значение левого потенциометра в предыдущую переменную.
prevRight = Right; // Сохраняем новое значение правого потенциометра в предыдущую переменную.
if (i > 500){menu = 4;} // Если переменная счета превысило значение 500, то разрешаем переход к событию 4.
//
if (digitalRead(pinKeyBlue)) // Если нажата синяя кнопка.
{ //
if (codeLeft == Left && codeRight == Right) // Сравниваем сохраненные значения коды и установленные заново. Если совпадают.
{ //
digitalWrite(pinKeyLedBlue, HIGH); // Зажигаем светодиод.
servo.write(90); // Устанавливаем сервопривод на 90 градусов.
menu = 1; // Разрешаем переход событию 1.
event = false; // Запрещаем событие нажатия кнопки.
prevMicros = micros(); // Сохраняем предыдущее значение таймера.
} //
else // Если не совпадают, то мигаем индикатором.
{ //
for (k = 0; k <= 3; k++) // В цикле осуществляем мигание.
{ //
dispLED.light(1); // Устанавливаем небольшую яркость свечения LED индикатора.
delay(500); // Задержка 500 мс.
dispLED.light(7); // Устанавливаем максимальную яркость свечения LED индикатора.
delay(500); // Задержка 500 мс.
} //
} //
} //
break; // Выходим из оператора case.
//
case 4: // Событие 4.
dispLED.clear(); // Очищаем индикатор.
i = 0; // Обнуляем переменную счета.
ReadingValues(); // Функция чтения значения с потенциометров.
if (Right != prevRight || Left != prevLeft){menu = 3;} // Если предыдущее значения потенциометров не равны новым, то разрешаем переход к событию 3.
prevLeft = Left; // Сохраняем новое значение левого потенциометра в предыдущую переменную.
prevRight = Right; // Сохраняем новое значение правого потенциометра в предыдущую переменную.
if (digitalRead(pinKeyBlue)){menu = 3;} // Если нажата кнопка, то разрешаем переход к Событию 3.
break; // Выходим из оператора case.
} //
} //
//
void ReadingValues() // Функция чтения значения с потенциометров.
{ //
if ( analogRead(pinKeyPotLeft) - prevLeftDat > dreb || // Если разность между новым значением левого потенциометра и предыдущим значением левого потенциометра больше переменной дребезга левого потенциометра.
analogRead(pinKeyPotLeft) - prevLeftDat < -dreb || // Если разность между новым значением левого потенциометра и предыдущим значением левого потенциометра меньше переменной дребезга левого потенциометра.
analogRead(pinKeyPotRight) - prevRightDat > dreb || // Если разность между новым значением правого потенциометра и предыдущим значением правого потенциометра больше переменной дребезга правого потенциометра.
analogRead(pinKeyPotRight) - prevRightDat < -dreb ) // Если разность между новым значением правого потенциометра и предыдущим значением правого потенциометра меньше переменной дребезга правого потенциометра.
{ //
prevLeftDat = analogRead(pinKeyPotLeft); // Сохраняем новое значение левого потенциометра в предыдущую переменную.
prevRightDat = analogRead(pinKeyPotRight); // Сохраняем новое значение правого потенциометра в предыдущую переменную.
if (around) // Если событие изменения вывода значений на индикатор разрешено.
{ //
Left = map(analogRead(pinKeyPotLeft), 0, 1015, 0, 99); // Считываем значения левого потенциометра, масштабируя в диапазон от 0 до 99.
Right = map(analogRead(pinKeyPotRight), 0, 1015, 0, 99); // Считываем значения правого потенциометра, масштабируя в диапазон от 0 до 99.
} //
else // Если событие изменения вывода значений на индикатор неразрешено.
{ //
Left = map(analogRead(pinKeyPotLeft), 0, 1015, 99, 0); // Считываем значения левого потенциометра, масштабируя в диапазон от 99 до 0.
Right = map(analogRead(pinKeyPotRight), 0, 1015, 99, 0); // Считываем значения правого потенциометра, масштабируя в диапазон от 99 до 0.
} //
} //
} //
//
void ShowTime() // Функция показа времени.
{ //
if (Left>=0 && Left<10) // Если количество времени у левого игрока от 0 до 9.
{LeftChar = (String) "0" + Left;} // Добавляем спереди ноль и переводим в строковое значение.
else{LeftChar = (String) Left;} // Иначе просто переводим количество времени в строковое значение.
//
if (Right>=0 && Right<10) // Если количество времени у правого игрока от 0 до 9.
{RightChar = (String) "0" + Right;} // Добавляем спереди ноль и переводим в строковое значение.
else{RightChar = (String) Right;} // Иначе просто переводим количество времени в строковое значение.
//
times = LeftChar + RightChar; // Присваиваем общей переменной количество времени левого и правого игрока.
dispLED.print(times); // Выводим значение на индикатор.
} //
Алгоритм работы:
В начале скетча (до кода setup) выполняются следующие действия:
- Подключаем библиотеку iarduino_4LED для работы с Trema-модуль Четырехразрядным LED индикатором.
- Объявляем объект dispLED, с указанием выводов дисплея.
- Подключаем библиотеку Servo, для работы с Сервоприводом.
- Объявляем объект servo.
- Объявляем пины для работы с левым и правым Trema-модуль потенциометром, Сервоприводом, Trema-модуль кнопкой со светодиодом, синяя, а так же пины для работы с самими светодиодами.
- Объявляем переменные и константы, которые задействованы в программе.
- Объявляем функции.
В коде setup выполняются следующие действия:
- Присоединяем сервопривод к выводу pinServo.
- Переводим вывод pinKeyBlue, pinKeyLedBlue в режим входа.
- Инициируем LED дисплей.
- Устанавливаем максимальную яркость свечения LED индикатора.
- Разрешаем переход к событию 1.
В коде loop выполняются следующие действия:
- Событие 1.
- Считываем значение с потенциометров с помощью функции "ReadingValues()".
- Выводим значения потенциометров с помощью функции "ShowTime()".
- Если нажата кнопка, то сохраняем кодовую последовательность, разрешаем переход к событию 2 и изменяем событие вывода значений потенциометра в другом диапазоне на противоположное .
- Устанавливаем сервопривод на 180 градусов.
- Включаем светодиод на кнопке.
- Разрешаем событие нажатия кнопки, если прошла одна секунда с момента начала этого события.
- Событие 2.
- Осуществляем мигание с помощью цикла, в котором сначала очищаем дисплей, гасим светодиод и ждем 500 мс, затем выводим на дисплей значения потенциометров, зажигаем светодиод, ждем 500 мс и так три раза.
- Гасим светодиод, устанавливаем на сервопривод 0 градусов, разрешаем переход к событию 3 и обнуляем переменные значений с левого и правого потенциометра без масштабирования.
- Событие 3.
- Считываем значение с потенциометров с помощью функции "ReadingValues()".
- Выводим значения потенциометров с помощью функции "ShowTime()".
- Если оба предыдущих значения потенциометра равно новому, то увеличиваем переменную счета. А если не равно, обнуляем переменную счета.
- Сохраняем новые значения левого и правого потенциометров в предыдущие переменные.
- Если переменная счета больше 500, то разрешаем переход к событию 4.
- Если нажата кнопка, то сравниваем кодовую последовательность с новыми установленными значениями потенциометров. Если совпадают, то зажигаем светодиод, устанавливаем сервопривод а 180 градусов., разрешаем переход к событию 1, запрещаем события нажатия кнопки, сохраняем нынешнее значение счетчика. Если не равны, тогда три раза мигаем экраном, в цикле убавляя и прибавляя яркость подсветки, через каждый 500 мс.
- Событие 4.
- Очищаем индикатор.
- Обнуляем переменную счета.
- Считываем значение с потенциометров с помощью функции "ReadingValues()".
- Если значения изменились, то разрешаем переход к события 3.
- Сохраняем новые значения левого и правого потенциометров в предыдущие переменные.
- Если нажата кнопка, то разрешаем переход в событие 3.
- функции "ReadingValues()". В ней убираем дребезг потенциометров, а именно значения на потенциометрах не в масштабе должны быть больше или меньше предыдущих значений на 10 единиц. Тогда сохраняем текущие значения потенциометров не в масштабе и сохраняем текущие значения потенциометров масштабе в зависимости от диапазона.
- Функция "ShowTime()". В ней преобразуем время целочисленного значения в строковое, добавляя ноль, где это необходимо. А так же выводим раз в пол секунды общее время и мигающую точку по центру, для событий 1 и 7. Для остальных событий выводим время и точку постоянно.

Обсуждение