Содержание

Замок, открывающийся по стуку

assembled.jpg

Что это такое?

Что нам понадобится?

  1. Arduino Uno
  2. Troyka-шилд
  3. Troyka-микрофон
  4. Troyka-потенциометр
  5. Troyka-зуммер
  6. Сервопривод FS5109M
  7. Импульсный блок питания

Как это собрать?

Исходный код

knocklock.ino
#include <Servo.h>
 
#define KNOCK_PIN A0
#define BTN_PIN 3
#define BUZZER_PIN 9
#define LED_PIN 8
 
#define KNOCK_HIGH 300
#define KNOCK_TIMEOUT 1000
 
#define BTN_SHORT_MIN 100
#define BTN_SHORT_MAX 2000
#define BTN_LONG_MIN 3000 
#define BTN_LONG_MAX 10000
 
#define OPEN 107
#define OPEN2 103
#define CLOSE 85
#define CLOSE2 88
#define CODE_LEN 5
 
 
enum State
{
    OPENED,
    CLOSED,
    SETPWD,
    CNFPWD,
    INIT
};
 
 
bool code[CODE_LEN] = { 1, 0, 1, 0, 1 };
bool input[CODE_LEN] = { 0, 0, 0, 0, 0 };
unsigned int knockLevel = 0;
State state;
Servo srv;
 
void setup()
{
    Serial.begin(115200);
 
    pinMode(BTN_PIN, INPUT);
    pinMode(LED_PIN, OUTPUT);
 
    digitalWrite(LED_PIN, LOW);
 
    state = INIT;
    Serial.println("Started.");
}
 
bool btn(void)
{
    return digitalRead(BTN_PIN);
}
 
bool getknk(void)
{
    bool b1, b2;
 
    while(1)
    {
        b1 = analogRead(KNOCK_PIN) > knockLevel;
        delay(1);
        b2 = analogRead(KNOCK_PIN) > knockLevel;
 
        if(b1 == b2) return b1;
        delay(1);
    }
 
    return false;
}
 
char getch_knk(void)
{
    unsigned long tm = millis();
 
    while(!getknk() and millis()-tm < KNOCK_TIMEOUT);
 
    if(millis()-tm >= KNOCK_TIMEOUT) return -1;
 
    tm = millis();
 
    while(getknk());
 
    while(!getknk() and millis()-tm < KNOCK_HIGH);
 
    tm = millis()-tm;
 
    while(getknk());
 
    if(tm < KNOCK_HIGH) return 0;
 
    return 1;
}
 
char readCode(void)
{
    int i;
    char ch;
 
    for(i = 0; i < CODE_LEN; i++)
    {
        ch = getch_knk();
 
        if(ch < 0) return -1;
 
        input[i] = ch;
        Serial.print((int)ch);
    }
 
    Serial.println("");
 
    for(i = 0; i < CODE_LEN; i++)
    {
        if(input[i] != code[i]) return 0;
    }
 
 
    return 1;
}
 
void readPwd(void)
{
    int i;
    char ch;
 
    for(i = 0; i < CODE_LEN; i++)
    {
        while((ch = getch_knk()) < 0);
        input[i] = ch;
 
        Serial.print((int)ch);
    }
}
 
void ledOn(void) { digitalWrite(LED_PIN, HIGH); }
void ledOff(void) { digitalWrite(LED_PIN, LOW); }
 
void open(void)
{
 
    srv.attach(5);
    srv.write(OPEN);
    delay(500);
    srv.write(OPEN2);
    delay(100);
    srv.detach();
 
    state = OPENED;
    Serial.println("Opened.");
}
 
void close(void)
{
 
    srv.attach(5);
    srv.write(CLOSE);
    delay(500);
    srv.write(CLOSE2);
    delay(100);
    srv.detach();
 
    state = CLOSED;
    Serial.println("Closed.");
}
 
 
void loop()
{
    int i;
    char ch;
    unsigned long tm;
 
    knockLevel = analogRead(A1);
 
    switch(state)
    {
    case OPENED:
        while(btn());
        tm = millis();
        while(!btn());
        tm = millis()-tm;
 
        if(tm > BTN_SHORT_MIN and tm < BTN_SHORT_MAX) close();
        else if(tm > BTN_LONG_MIN and tm < BTN_LONG_MAX) state = SETPWD, ledOn();
        break;
 
    case CLOSED:
        ch = readCode();
 
        if(ch < 0)
        {
            Serial.println("FAIL");
            break;
        }
 
        if(ch == 1) open();
        else
        {
            tone(BUZZER_PIN, 500, 200);
            delay(200);
            tone(BUZZER_PIN, 500, 200);
            delay(200);
            tone(BUZZER_PIN, 500, 200);
            delay(200);
        }
        break;
 
    case SETPWD:
        Serial.print("Input code:");
        readPwd();
 
        for(i = 0; i < CODE_LEN; i++) code[i] = input[i];
 
        Serial.println("");
        state = CNFPWD;
        break;
 
    case CNFPWD:
        Serial.print("Confirm code:");
        readPwd();
 
        for(i = 0; i < CODE_LEN; i++) if(code[i] != input[i]) break;
 
        Serial.println("");
        if(i == CODE_LEN) ledOff(), state = OPENED;
        else state = SETPWD;
 
        break;
 
    case INIT: open(); break;
    }
}

Демонстрация работы устройства

Что можно сделать ещё?