Помогите добавить вторую кнопку

Тема в разделе "Arduino & Shields", создана пользователем abubakar, 29 авг 2017.

  1. NikitOS

    NikitOS Король шутов Администратор

    А Вы можете схему дать,ведь код не универсален...
     
  2. abubakar

    abubakar Нерд

    Какую схему?
     
  3. IvanUA

    IvanUA Гуру

    Схему, куда и что вы подключали, я так понимаю)
     
  4. abubakar

    abubakar Нерд

    Код (C++):
    //
    /* MOSI: Pin 11 / ICSP-4
    * MISO: Pin 12 / ICSP-1
    * SCK: Pin 13 / ISCP-3
    * SS: Pin 10
    * RST: Pin 9
    */

    #define button 3
    #define BUTTON_PIN 2
    #include <SPI.h>
    #include <RFID.h>
    #include <Servo.h>
    #define SS_PIN 10
    #define RST_PIN 9
    #define RED_LED 4
    #define GREEN_LED 5
    Servo servo;



    // Часто модуль реле имеет неожиданную логику. На LOW - замыкается, на HIGH размыкается.
    // Укажите уровни пина RELAY1 для открытого и закрытого состояния.
    #define RCLOSE HIGH
    #define ROPEN LOW

    RFID rfid(SS_PIN, RST_PIN);

    const unsigned char master[][5]={
      {227,197,145,117,194},
      { 90, 63, 99, 3, 5},
      {90,132,142,3,83},
      {250,229,196,3,216},
      {10,101,141,4,230},
      {250,191,109,3,43},
      {10,88,184,4,238},
      {250,243,195,3,201},
      {74,151,2,4,219},
      {5,219,213,209,218,} // тут вы что то накосячили, я убрал число 10 и остаток кодов. проверьте список
    };// allowed card

    const int master_size = sizeof(master)/sizeof(master[0]);

    bool compare_nums(
      const unsigned char a[5],
      const unsigned char b[5]
    ) {
        for(char i = 5; 0 <= --i; )
        {
          if( a[i] != b[i] ) return false;
        }
        return true;
    }

    bool check_num(
      const unsigned char a[5]
    ){
      for( int i = master_size; 0 <= --i; ){
        if(compare_nums(a, master[i])) return true;
      }
      return false;
    }


    void allow();
    void denied();
    void setup()
    {
      Serial.begin(9600);
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      SPI.begin();
      rfid.init();
      pinMode(RED_LED, OUTPUT);
      pinMode(GREEN_LED, OUTPUT);
      servo.attach(6);
      servo.write(20);
      pinMode(button, INPUT_PULLUP);
    }


    void loop() {
     
    if (!digitalRead(BUTTON_PIN)==true)
    {
    servo.attach(6);
    servo.write(20);
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
    }
    if (!digitalRead(button)==true)
    {
    servo.attach(6);
    servo.write(90);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
    }
    //////////////////////////////////////////////////////
    /////////////////////////////////////////////////////

        if (rfid.isCard())
        {
            digitalWrite(GREEN_LED, LOW);
            if (rfid.readCardSerial())
            {
                    /* Reading card */
                    Serial.println(" ");
                    Serial.println("Card found");
                    Serial.println("Cardnumber:");
                    for (char i = 0; i < 5; i++)
                    {
                      Serial.print(rfid.serNum[i]);
                      Serial.print(" ");
                    }
                    Serial.println();
                    //verification
                    if(check_num(rfid.serNum))
                    {
                      allow();
                    }
                    else
                    {
                      denied();
                    }
             }
        }
        else
        {
          // tone(8, 5000, 20);
           digitalWrite(RED_LED, HIGH);
           delay(500);
           digitalWrite(RED_LED, LOW);
    delay(1000);
        }
    }

    void allow()
    {
       Serial.println("Access accept!"); //доступ получен
       servo.write(90);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);

        //////////////////////////////
       //////////////////////////////
      //////////////////////////////

    }

    void denied()
    {
       Serial.println("Access denied!"); //доступ закрыт
       digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
       digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
          digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
       digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
    }
     
     
  5. qwone

    qwone Гик

    Вот код. Но он от дверей для дома . С захлопом при закрытии двери.
    Код (C++):
    /*
      светодиод -> 8 (Led_pin) 0 горит/ 1 нет
           GND ->  GND
      серва  -> 5
      геркон -> 3  0 дверь закрыта / 1 нет
      кнопка -> 2  0 нажата/ 1 нет
           GND ->  GND

      RFID_RC522 RST -> 9 (RST_pin)
            SDA(SS)-> 10 (SDA_pin)
            MOSI   -> 11 (MOSI_pin)
            MISO   -> 12 (MISO_pin)
            SCK    -> 13 (SCK_pin)
            3,3В   -> 3,3В
            GND    -> GND
    */

    unsigned long mill;//переменная millis()
    //-------Cl_Lock---------------------------------------
    // класс Cl_Lock дверной замок - серво,геркон в дверях,светодиод индикация
    #include <Servo.h>
    const int servo_OFF = 0; // серва закрыта
    const int servo_ON = 90; // серва открыта
    class Cl_Lock {
        const byte servoPin;
        const byte gerconPin;
        const byte ledPin;
        unsigned long time, past;
        Servo myservo;
        bool doorOpen;// 1 дверь открыта
      public:
        /*конструктор Cl_Lock
          описание    создать объект
          ввод        _servoPin: нога на серве
                      _gerconPin: нога на герконе
          вывод       нет
        */

        Cl_Lock(byte _servoPin, byte _gerconPin, byte _ledPin, unsigned long _time)
          : servoPin(_servoPin), gerconPin(_gerconPin), ledPin(_ledPin), time(_time) {}
        /*функция     setup
          описание    иницилизация
          ввод        нет
          вывод       нет
        */

        void setup() {
          pinMode(ledPin, OUTPUT);
          digitalWrite(ledPin, 0);
          myservo.attach(servoPin);
          pinMode(gerconPin, INPUT_PULLUP);
          if (!digitalRead(gerconPin))myservo.write(servo_OFF);
          doorOpen = 1;
        }
        /*функция     loop
          описание    для нормальной работы вставить в тело loop()
          ввод        нет
          вывод       нет
        */

        void loop() {
          if (doorOpen && mill - past >= time && !digitalRead(gerconPin)) { // убеждаемся что дверь закрыта и подошло время закрывать на замок
            doorOpen = 0;
            digitalWrite(ledPin, 1);
            myservo.write(servo_OFF);  // закрываем
          }
        }
        /*функция     open
          описание    открыть дверь
          ввод        нет
          вывод       нет
        */

        void open() {
          doorOpen = 1;
          past = mill;
          digitalWrite(ledPin, 0);
          myservo.write(servo_ON);
        }
    };
    //---------Cl_Btn-------------------------------------------------
    // класс кнопка
    class Cl_Btn {
        const byte pin;
        void (*Do)();
        bool btn, oldBtn = 1;
        bool bounce = 0;
        unsigned long past;
      public:
        /*конструктор Cl_Btn
          описание    создать объект
          ввод        _pin: нога кнопки
                      _Do: обработчик кнопки
          вывод       нет
        */

        Cl_Btn(byte _pin, void (_Do)()): pin(_pin), Do(_Do) {}
        /*функция     setup
          описание    иницилизация
          ввод        нет
          вывод       нет
        */

        void setup() {
          pinMode(pin, INPUT);
          btn = digitalRead(pin);
        }
        /*функция     loop
          описание    для нормальной работы вставить в тело loop()
          ввод        нет
          вывод       нет
        */

        void loop() {
          bool newBtn = digitalRead(pin);
          if (bounce && newBtn != btn) {
            bounce = 1;
          }
          if (!bounce && mill - past >= 10) {
            past = mill;
            bounce = 0;
            oldBtn = btn;
            btn = newBtn;
            if (!btn && oldBtn) (*Do)();
          }
        }
    };
    //---------Cl_MFRC522-------------------------------------------------
    // класс MFRC522 кнопка на RFID
    #include <SPI.h>
    #include <MFRC522.h>
    struct sCard {
      struct sCard *next;
      unsigned long Card;
    };
    class Cl_MFRC522 {
        MFRC522 rfid;
        void (*Do)(); // обработчик кнопки
        unsigned long past;
        struct sCard *start = NULL;
      public:
        /*конструктор Cl_Btn
          описание    создать объект
          ввод        sdaPin: нога SDA
                      rstPin: нога RST
                      _Do: обработчик кнопки RFID
          вывод       нет
        */

        Cl_MFRC522(byte sdaPin, byte rstPin, void (_Do)())
          : rfid(sdaPin, rstPin), Do(_Do) {}
        /*функция     setup
          описание    иницилизация
          ввод        нет
          вывод       нет
        */

        void setup() {
          SPI.begin();
          rfid.PCD_Init();
        }
        /*функция     loop
          описание    для нормальной работы вставить в тело loop()
          ввод        нет
          вывод       нет
        */

        void loop() {
          if (mill - past >= 1000) {
            past = mill;
            if ( rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
              uint32_t Card = ((rfid.uid.uidByte[0] * 0x100 + rfid.uid.uidByte[1]) * 0x100 + rfid.uid.uidByte[2]) * 0x100 + rfid.uid.uidByte[3];
              Serial.println(Card);
              for (struct sCard *ii = start; ii != NULL; ii = ii->next) {
                if (Card == ii->Card) (*Do)();
              }
            }
          }
        }
        /*функция     AddCard
          описание    добавить новую карту
          ввод        _Card:код новой карты
          вывод       нет
        */

        void AddCard(uint32_t _Card) {
          struct sCard *newCard = new struct sCard;
          newCard->next = start;
          newCard->Card = _Card;
          start = newCard;
        }
    };
    //-----Компоновка-----------------------------------------
    const unsigned time_3s = 3000;
    Cl_Lock Lock(/*пин на серво*/5,/*пин на герконе*/3,/*пин индик*/8,/*врямя*/time_3s);
    void Do_Btn() {
      Lock.open();
    }
    Cl_Btn Btn(/*пин*/2,/*обработчик*/Do_Btn);
    Cl_MFRC522 MFRC522(/*пин SDA*/10,/*пин RST*/9,/*обработчик*/Do_Btn);
    //-----main()-----------------------------------------
    void setup() {
      Serial.begin(9600);
      Lock.setup();
      Btn.setup();
      MFRC522.setup();
      MFRC522.AddCard(4294966803);// добавить карту 4294966803
      MFRC522.AddCard(14805)     ;// добавить карту 14805
    }

    void loop() {
      mill = millis();
      Lock.loop();
      Btn.loop();
      MFRC522.loop();
    }
    /*Скетч использует 7062 байт (21%) памяти устройства. Всего доступно 32256 байт.
      Глобальные переменные используют 298 байт (14%) динамической памяти, оставляя 1750 байт для локальных переменных. Максимум: 2048 байт.
    */
     
  6. abubakar

    abubakar Нерд

    Спасибо но он слишком сложный). Я бы хотел чтобы когда дверь закрыта(кнопка зажата) и если нажать внутреннюю кнопку она открывалась. А то сейчас он не реагирует на внутреннюю кнопку когда геркон HIGH. Это со скетчем который мне дал BAR__MEN
     
  7. NikitOS

    NikitOS Король шутов Администратор

    Попробую еще пописать,с телефона пишу поэтому могу что нибудь пропустить
     
  8. abubakar

    abubakar Нерд

    Аа). Вкратце: Нужна аварийная кнопка если это возможно, шпингалет должен открывать в любом случае вне зависимости была ли нажата кнопка(концевик, геркон).
     
  9. IvanUA

    IvanUA Гуру

    Нннннда...
    Короче, вам нужен флаг открытия двери.

    Добавьте эти переменные до функции setup()

    void allow();
    void denied();

    int statDoor = 0; // Статус открытия дверного замка
    unsigned long int timeDoor = millis(); // Счетчик времени через которое можно закрыть замок

    void setup(){

    Далее в лупе в проверке геркона надо дополнить и проверку статуса вот так:

    if(!digitalRead(BUTTON_PIN)==true
    && statDoor == 1 && (timeDoor+5000)>millis()){
    servo.attach(6);
    servo.write(20);

    statDoor = 0; // сбрасываем статус в ноль что бы эта функция до открытия больше не срабатывала

    Во всех функция которые открывают замок нужно будет менять и статус замка и сбрасывать таймер открытого замка вот так:

    if (!digitalRead(button)==true){
    servo.attach(6);
    servo.write(90);

    statDoor = 1;
    timeDoor = millis();


    и вот тут:

    void allow(){
    Serial.println("Access accept!"); //доступ получен
    servo.write(90);

    statDoor = 1;
    timeDoor = millis();


    Наклонным шрифтом выделил часть вашего скейтча, жирным шрифтом - что надо добавить.
    Логика проста:
    1 - поднесли правильную карту замок открылся и если дверь не была открыта в течении 5 секунд то замок закроется.
    2 - если нажали вторую кнопку то замок откроется и если дверь закрыта то через 5 сек. закроется.
    3 - если замок открылся и дверь открыта (прошло более 5 секунд) то система ждет сигнал геркона. Как только дверь закрыть - замок сам закроется.


    Удачи Вам.
     
  10. abubakar

    abubakar Нерд

    Код (C++):
    // mcureen 4
    /* MOSI: Pin 11 / ICSP-4
    * MISO: Pin 12 / ICSP-1
    * SCK: Pin 13 / ISCP-3
    * SS: Pin 10
    * RST: Pin 9
    */

    #define button 3
    #define BUTTON_PIN 2
    #include <SPI.h>
    #include <RFID.h>
    #include <Servo.h>
    #define SS_PIN 10
    #define RST_PIN 9
    #define RED_LED 4
    #define GREEN_LED 5
    Servo servo;



    // Часто модуль реле имеет неожиданную логику. На LOW - замыкается, на HIGH размыкается.
    // Укажите уровни пина RELAY1 для открытого и закрытого состояния.


    RFID rfid(SS_PIN, RST_PIN);

    const unsigned char master[][5]={
      {227,197,145,117,194},
      { 90, 63, 99, 3, 5},
      {90,132,142,3,83},
      {250,229,196,3,216},
      {10,101,141,4,230},
      {250,191,109,3,43},
      {10,88,184,4,238},
      {250,243,195,3,201},
      {74,151,2,4,219},
      {5,219,213,209,218,} // тут вы что то накосячили, я убрал число 10 и остаток кодов. проверьте список
    };// allowed card

    const int master_size = sizeof(master)/sizeof(master[0]);

    bool compare_nums(
      const unsigned char a[5],
      const unsigned char b[5]
    ) {
        for(char i = 5; 0 <= --i; )
        {
          if( a[i] != b[i] ) return false;
        }
        return true;
    }

    bool check_num(
      const unsigned char a[5]
    ){
      for( int i = master_size; 0 <= --i; ){
        if(compare_nums(a, master[i])) return true;
      }
      return false;
    }


    void allow();
    void denied();
    int statDoor = 0; // Статус открытия дверного замка
    unsigned long int timeDoor = millis(); // Счетчик времени через которое можно закрыть замок
    void setup()
    {
      Serial.begin(9600);
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      SPI.begin();
      rfid.init();
      pinMode(RED_LED, OUTPUT);
      pinMode(GREEN_LED, OUTPUT);
      servo.attach(6);
      servo.write(20);
      pinMode(button, INPUT_PULLUP);
    }


    void loop() {
     
    if (!digitalRead(BUTTON_PIN)==true && statDoor == 0 && (timeDoor+5000)>millis())
    {
    servo.attach(6);
    servo.write(20);
    statDoor = 0; // сбрасываем статус в ноль что бы эта функция до открытия больше не срабатывала
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(RED_LED, HIGH);
       delay(200);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
    }
    if (!digitalRead(button)==true)
    {
    servo.attach(6);
    servo.write(90);
    statDoor = 1;
    timeDoor = millis();
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
    }
    //////////////////////////////////////////////////////
    /////////////////////////////////////////////////////

        if (rfid.isCard())
        {
            digitalWrite(GREEN_LED, LOW);
            if (rfid.readCardSerial())
            {
                    /* Reading card */
                    Serial.println(" ");
                    Serial.println("Card found");
                    Serial.println("Cardnumber:");
                    for (char i = 0; i < 5; i++)
                    {
                      Serial.print(rfid.serNum[i]);
                      Serial.print(" ");
                    }
                    Serial.println();
                    //verification
                    if(check_num(rfid.serNum))
                    {
                      allow();
                      statDoor = 1;
    timeDoor = millis();
                    }
                    else
                    {
                      denied();
                    }
             }
        }
        else
        {
          // tone(8, 5000, 20);
           digitalWrite(RED_LED, HIGH);
        /*   delay(500);
           digitalWrite(RED_LED, LOW);
    delay(1000);*/

        }
    }

    void allow()
    {
       Serial.println("Access accept!"); //доступ получен
       servo.write(90);
       statDoor = 1;
    timeDoor = millis();
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       digitalWrite(RED_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);
       delay(200);
       digitalWrite(GREEN_LED, HIGH);
       delay(200);
       digitalWrite(GREEN_LED, LOW);
       tone(8, 2500, 200);

        //////////////////////////////
       //////////////////////////////
      //////////////////////////////

    }

    void denied()
    {
       Serial.println("Access denied!"); //доступ закрыт
       digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
       digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
          digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
       digitalWrite(RED_LED, HIGH);
       tone(8, 550, 250);
       delay(300);
       digitalWrite(RED_LED, LOW);
       delay(300);
    }
     
    Спасибо тебе, но он теперь не реагирует ни на одну кнопку(
     
  11. IvanUA

    IvanUA Гуру

    if(!digitalRead(BUTTON_PIN)==true && statDoor == 1 && (timeDoor+5000)<millis())

    Поправьте эту строчку. Просто скопируйте
     
  12. abubakar

    abubakar Нерд

    Отлично теперь хоть и не открывается с внутренней стороны, но геркон на 5 выполняет свою работу. Может я его неправильно подключаю.Одна его нога подключена к земле (GND) другая подключена к 3 пину.
     
  13. IvanUA

    IvanUA Гуру

    Не открывается кнопкой?
    И еще вопрос. Вы пины к которым подлючали геркон и кнопку, подтягивали резистором на 10к к +5В? Лучше таки так сделать, это надежнее.
     
  14. IvanUA

    IvanUA Гуру

    Эээ. Я почему то решил что гренкон это у вас BUTTON_PIN и подключен он ко 2 ноге
     
  15. IvanUA

    IvanUA Гуру

    И еще по ходу вопрос, это не критично но почему
    !digitalRead(button)==true
    а не
    digitalRead(button)==false
    или на крайний случай
    digitalRead(button)!=true
     
  16. abubakar

    abubakar Нерд

    Урааа
     
  17. abubakar

    abubakar Нерд

    Оказывается дело не в скетче. Дело в ненадежной пайке. Вот китайцы((. Нога gnd к которому был подключен минус от кнопки была плохо припаяна, я попробовал поставить эту ножку на другой gnd. Вуаля, ррработает.
    Спасибо тебе огромное. Очень помог. Скажи номер киви кощелька или другой платежной системы.
     
  18. IvanUA

    IvanUA Гуру

    Работает? Что помогло?
    Кстати, у себя я реализовал следующую логику:
    когда открывается дверь (срабатывает геркон)
    то зажигается свет в коридоре и светит пока дверь не закроется,
    после закрытия двери свет можно выключить выключателем или он сам погаснет через 30 секунд.
    Ах да, еще в коридоре стоят датчики движения и счетчик на 30 секунд начнет считать когда
    в коридоре не будет движения, так что можно не выключать свет, сам погаснет))))
     
  19. IvanUA

    IvanUA Гуру

    Денег не надо. Пользуйся.
     
  20. abubakar

    abubakar Нерд

    Спасибо огромное.