RFID выключатель

varvik85
Offline
Зарегистрирован: 28.01.2013

Добрый вечер. Решил собрать выключатель с использованием RFID карточки.Задача такая,пока карточка лежит на RFID считывателе горит лампа, карточку убираем - лампа гаснет.

из примеров состряпал нечто

#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long uidDec, uidDecTemp;  // для храниения номера метки в десятичном формате
boolean switchOn = false;
void setup() {
  Serial.begin(9600);
  Serial.println("Waiting for card...");
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.
  
}
void loop() {
  // Поиск новой метки
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  // Выбор метки
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  uidDec = 0;
  // Выдача серийного номера метки.
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    uidDecTemp = mfrc522.uid.uidByte[i];
    uidDec = uidDec * 256 + uidDecTemp;
  }
  //Serial.println("Card UID: ");
  //Serial.println(uidDec); // Выводим UID метки в консоль.
  if (uidDec == 3763966293) // Сравниваем Uid метки.
  {
    switchOn = true;
    Serial.println("Switched On");
  }
  else
  {
    Serial.println("Switched Off");
    switchOn = false;
  }
}

но работает не так как нужно,выключение лампы (в данном случае пока просто вывод состояния в консоль) происходит не тогда кагда я убираю карту,а тогда когда подношу карту с другим UID ,понимаю что нужно как то в цикле сделать опрос состояния "есть ли карта", а не так как у меня сделано "есть ли карта с таким uid",вот,подскажите как сделать,описание библиотеки на русском не нашел,а в английском описаниии чет никак не разберусь

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

https://www.youtube.com/watch?v=TR4mf4wa4nA&index=21&list=PLfDmj22jP9S759DT250VVzfZs_4VnJqLa

Если такой.... 

Хотя и с другими принцип тот же. И про цикл и про сравнение и всё там --- там 2 видео...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
rfid.PICC_IsNewCardPresent() // 1 есть карта 0 нет карты.

 

varvik85
Offline
Зарегистрирован: 28.01.2013

аналогичные примеры я находил, там как бы один раз происходит опрос,а мне нужно постоянно опрашивать есть ли карта с таким uid и если ее нет выключать лампу,есть включать.

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

qwone пишет:

rfid.PICC_IsNewCardPresent() // 1 есть карта 0 нет карты.

Пусть человек посмотрит. А то ему напишешь, он ничего не поймет и снова придет.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
rfid.PICC_IsNewCardPresent() // 1 есть карта 0 нет карты.

Задача такая,пока карточка лежит на RFID считывателе горит лампа, карточку убираем - лампа гаснет.

если есть карта и лампа не горит - то вкл лампу.

если карты нет и лампа  горит - то выкл лампу.

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

varvik85 пишет:

аналогичные примеры я находил, там как бы один раз происходит опрос,а мне нужно постоянно опрашивать есть ли карта с таким uid и если ее нет выключать лампу,есть включать.

 



void loop()
{
        while()  
        {
                // твой код опроса меток

                // Если метка правильная - идем дальше, иначе в начало кода

                // твой код на какое то действие
        }

        while()  
        {
                // твой код опроса меток
                // Если метка правильная - идем дальше, иначе в начало кода
                     // твой код на какое то действие

         } 

 }
varvik85
Offline
Зарегистрирован: 28.01.2013

так?

if (  mfrc522.PICC_IsNewCardPresent()) {
  if ((uidDec == 3763966293) && (switchOn == false)) {
    switchOn = true;
    Serial.println("Switched On");
  }
  else
  {

    Serial.println("Switched Off");
    switchOn = false;
 

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

В конце только скобку поставь.  И получился цикл.

varvik85
Offline
Зарегистрирован: 28.01.2013

p.masyukov мы наверно друг друга не понимаем,вернее я Вас не понимаю,что Вы хотели эти показать мне?

01

  void loop()
02 {
03         while() 
04         {
05                 // твой код опроса меток
06  
07                 // Если метка правильная - идем дальше, иначе в начало кода
08  
09                 // твой код на какое то действие
10         }
11  
12         while() 
13         {
14                 // твой код опроса меток
15                 // Если метка правильная - идем дальше, иначе в начало кода
16                      // твой код на какое то действие
17  
18          }
19  
20  }

 

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

varvik85 пишет:

p.masyukov мы наверно друг друга не понимаем,вернее я Вас не понимаю,что Вы хотели эти показать мне?

01

   

Задача твоя решается не считыванием постоянно карты, а проверкой что она всё еще лежит - каждые n миллисекунд...

В твоем варианте она будет циклично переключаться.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
if (  mfrc522.PICC_IsNewCardPresent()  && ! switchOn ){
    switchOn = 1;
    Serial.println("Switched On");
  }
if ( !  mfrc522.PICC_IsNewCardPresent()  && switchOn ) {
     switchOn = 0;
  Serial.println("Switched Off");
 }


 

 

varvik85
Offline
Зарегистрирован: 28.01.2013

опробовал вышеизложенное

#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long uidDec, uidDecTemp;  // для храниения номера метки в десятичном формате
boolean switchOn = false;
void setup() {
  Serial.begin(9600);
  Serial.println("Waiting for card...");
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.
  
}
void loop() {
  // Поиск новой метки
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  // Выбор метки
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  uidDec = 0;
  // Выдача серийного номера метки.
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    uidDecTemp = mfrc522.uid.uidByte[i];
    uidDec = uidDec * 256 + uidDecTemp;
  }
  //Serial.println("Card UID: ");
  //Serial.println(uidDec); // Выводим UID метки в консоль.
  
if ( ! mfrc522.PICC_IsNewCardPresent()) {
  if ((uidDec == 1435947877) && (switchOn == false)) {
    switchOn = true;
    Serial.println("Switched On");
  }
  else
  {

    Serial.println("Switched Off");
    switchOn = false;
    }
}
}

В консоль сыпет

Switched On
Switched Off
Switched On
Switched Off
Switched On
Switched Off
Switched On
Switched Off

 постоянно как только подношу карту, я расчитывал что если карта всегда поднесена то будет один раз on как только уберу один раз of

varvik85
Offline
Зарегистрирован: 28.01.2013

qwone пишет:

if (  mfrc522.PICC_IsNewCardPresent()  && ! switchOn ){
    switchOn = 1;
    Serial.println("Switched On");
  }
if ( !  mfrc522.PICC_IsNewCardPresent()  && switchOn ) {
     switchOn = 0;
  Serial.println("Switched Off");
 }

попробовал,не работает

varvik85
Offline
Зарегистрирован: 28.01.2013
  p.masyukov

Да Вы правы,пологаю так и происходит (выше в коде),вот с опросом через какой то интервал времини не разберусь самостоятельно

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
boolean switchOn = 0;
void setup() {
  Serial.begin(9600);
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.

}
void loop() {
  if (  mfrc522.PICC_IsNewCardPresent()  && ! switchOn ) {
    switchOn = 1;
    Serial.println("Switched On");
  }
  if ( !  mfrc522.PICC_IsNewCardPresent()  && switchOn ) {
    switchOn = 0;
    Serial.println("Switched Off");
  }
}

 

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

varvik85 пишет:

опробовал вышеизложенное............

 постоянно как только подношу карту, я расчитывал что если карта всегда поднесена то будет один раз on как только уберу один раз of

 

#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long uidDec, uidDecTemp;  // для храниения номера метки в десятичном формате
boolean switchOn = false;
void setup() {
  Serial.begin(9600);
  Serial.println("Waiting for card...");
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.

}
void loop() 
{
  while(1)
  {
    // Поиск новой метки
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
      return;
    }
    // Выбор метки
    if ( ! mfrc522.PICC_ReadCardSerial()) {
      return;
    }
    uidDec = 0;
    // Выдача серийного номера метки.
    for (byte i = 0; i < mfrc522.uid.size; i++)
    {
      uidDecTemp = mfrc522.uid.uidByte[i];
      uidDec = uidDec * 256 + uidDecTemp;
    }
    //Serial.println("Card UID: ");
    //Serial.println(uidDec); // Выводим UID метки в консоль.

    if ( ! mfrc522.PICC_IsNewCardPresent())
    {
      if ((uidDec == 1435947877)) 
      {
        if(switchOn = !true)
        {
            switchOn = true
            Serial.println("Switched On");
            break;
        }
      }    
    }
    else
    {
        Serial.println("Switched Off");
        switchOn = false;
    }
  }
}

Я тебе писал --- вставь в цикл...

varvik85
Offline
Зарегистрирован: 28.01.2013

qwone пишет:

#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
boolean switchOn = 0;
void setup() {
  Serial.begin(9600);
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.

}
void loop() {
  if (  mfrc522.PICC_IsNewCardPresent()  && ! switchOn ) {
    switchOn = 1;
    Serial.println("Switched On");
  }
  if ( !  mfrc522.PICC_IsNewCardPresent()  && switchOn ) {
    switchOn = 0;
    Serial.println("Switched Off");
  }
}

 

Спасибо,попробовал,но к сожалению не работает,если подношу карточку то постоянно сыпет

Switched Off
Switched On
Switched Off
Switched On
Switched Off
Switched On
Switched Off
 

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

http://arduino.ru/forum/programmirovanie/rfid-vyklyuchatel#comment-231898

задержку какой нибудь delay(10); поставь в конце цикла while...

varvik85
Offline
Зарегистрирован: 28.01.2013

Вообще ничего не происходит

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015
#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long uidDec, uidDecTemp;  // для храниения номера метки в десятичном формате
boolean switchOn = false;
void setup() {
  Serial.begin(9600);
  Serial.println("Waiting for card...");
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.

}
void loop() 
{
  while(1)
  {
    // Поиск новой метки
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
      return;
    }
    // Выбор метки
    if ( ! mfrc522.PICC_ReadCardSerial()) {
      return;
    }
    uidDec = 0;
    // Выдача серийного номера метки.
    for (byte i = 0; i < mfrc522.uid.size; i++)
    {
      uidDecTemp = mfrc522.uid.uidByte[i];
      uidDec = uidDec * 256 + uidDecTemp;
    }
    //Serial.println("Card UID: ");
    //Serial.println(uidDec); // Выводим UID метки в консоль.

    if ( ! mfrc522.PICC_IsNewCardPresent())
    {
      if ((uidDec == 1435947877)) 
      {
        if(switchOn == !true)
        {
            switchOn = true
            Serial.println("Switched On");
            break;
        }
      }    
    }
    else
    {
        Serial.println("Switched Off");
        switchOn = false;
    }
  }
}

Там знак присваивания был а не сравнения.....

varvik85
Offline
Зарегистрирован: 28.01.2013

Теперь при подношении карточки в порт пишет один раз on,карту убираю off не пишет и ничего дальше не происходит

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

там не учитываются ошибки чтения.... тоесть любая помеха может отрубить...

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

varvik85 пишет:

Теперь при подношении карточки в порт пишет один раз on,карту убираю off не пишет и ничего дальше не происходит

А надо то ЧТО!!!

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015
#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long uidDec, uidDecTemp;  // для храниения номера метки в десятичном формате
boolean switchOn = false;
void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.begin(9600);
  Serial.println("Waiting for card...");
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.
  
}
void loop() 
{
  while(1)
  {
    // Поиск новой метки
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
Serial.println("Switched Off");
        digitalWrite(13, LOW);
        switchOn = false;

      return;
    }
    // Выбор метки
    if ( ! mfrc522.PICC_ReadCardSerial()) {
      return;
    }
    uidDec = 0;
    // Выдача серийного номера метки.
    for (byte i = 0; i < mfrc522.uid.size; i++)
    {
      uidDecTemp = mfrc522.uid.uidByte[i];
      uidDec = uidDec * 256 + uidDecTemp;
    }
    //Serial.println("Card UID: ");
    //Serial.println(uidDec); // Выводим UID метки в консоль.

    if ( ! mfrc522.PICC_IsNewCardPresent())
    {
      if ((uidDec == 1435947877)) 
      {
        if(switchOn == !true)
        {
            switchOn = true
            Serial.println("Switched On");
            digitalWrite(13, HIGH);
            break;
        }
      }    
    }
    else
    {
        Serial.println("Switched Off");
        digitalWrite(13, LOW);
        switchOn = false;
    }
  }
}

 

varvik85
Offline
Зарегистрирован: 28.01.2013

Мне надо так, если карта с определенным uid ПОСТОЯННО поднесена к рфид считывателю то горит лампа,карту убираю лампа гаснет,на другие рфид карты чтоб вообще не реагировала ,пока вместо лампы пробую эти два состояния лампа горит и не горит выводить в порт,вот сейчас с Вашим кодом получается что лампа включается но не выключается когда я убираю карту.

я так понимаю что после else в 49 строке после или перед ней нужно еще раз опросить есть ли карта

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

Поправил - выше

Там три строки  (23 -25 ) надо убрать и куда то вонзить ---- на выключение.

перед ретурном --- возможно при чтении карты. Возможно правильно сейчас всё.

только где - не соображу сходу... давно с этой ерундой не баловался.

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

Ну что? Где литр?

varvik85
Offline
Зарегистрирован: 28.01.2013

Да от литра уже почти ничего не осталось :) Надо кого нибудь послать за новой

varvik85
Offline
Зарегистрирован: 28.01.2013

Фот тут то что нужно https://www.youtube.com/watch?v=CEO-QDHKaY0 там и ссылка есть на статью,но скетч не рабочий,в консоль ничего не выводит

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

varvik85 пишет:

Да от литра уже почти ничего не осталось :) Надо кого нибудь послать за новой

Значит за коньяком иди. Заработало?

varvik85
Offline
Зарегистрирован: 28.01.2013

Да нет, не работает,светодиод я посадил на 2ю ножку,а то на 13 spi,код чуть подправил,пробовал разные варианты,то моргание получается, то просто горит и не выключается,то вообще не включается....какой коньяк то лучше взять?

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

varvik85 пишет:

Да нет, не работает,светодиод я посадил на 2ю ножку,а то на 13 spi,код чуть подправил,пробовал разные варианты,то моргание получается, то просто горит и не выключается,то вообще не включается....какой коньяк то лучше взять?

Да никакой я не пью.

 

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

Всё. затрахался... теперь будет отключать однозначно.

#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long uidDec, uidDecTemp;  // для храниения номера метки в десятичном формате
boolean switchOn = false;

int counter_error = 0;

void setup()
{
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  Serial.begin(9600);
  Serial.println("Waiting for card...");
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.

}

void loop()
{
    while (1)
    {
        // Поиск новой метки
        if ( ! mfrc522.PICC_IsNewCardPresent()) {
            break;
        }
        // Выбор метки
        if ( ! mfrc522.PICC_ReadCardSerial()) {
            break;
        }
        uidDec = 0;
        // Выдача серийного номера метки.
        for (byte i = 0; i < mfrc522.uid.size; i++)
        {
            uidDecTemp = mfrc522.uid.uidByte[i];
            uidDec = uidDec * 256 + uidDecTemp;
        }
        //Serial.println("Card UID: ");
        //Serial.println(uidDec); // Выводим UID метки в консоль.
        
        if ( ! mfrc522.PICC_IsNewCardPresent())
        {
            if ((uidDec == 1435947877))
            {
                if (switchOn == !true)
                {
                    switchOn = true
                    Serial.println("Switched On");
                    digitalWrite(2, HIGH);
                    break;
                }
            }
        }

        delay(10);
        
        if(counter_error == 5)
        {
            Serial.println("Switched Off");
            digitalWrite(2, LOW);
            switchOn = false;
            counter_error = 0;
        }
        else
        {
            counter_error++;
        }
    }
}

 

varvik85
Offline
Зарегистрирован: 28.01.2013

Не,не работает.Если подношу карту, то в порт постоянно шлет OFF и светодиод не горит

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

varvik85 пишет:

Не,не работает.Если подношу карту, то в порт постоянно шлет OFF и светодиод не горит

всё что после 58-й строки замени на таймер ожидания.

тоесть считывать карту по несколько раз за определенный промежуток времени.

и контроль ошибок чтения сделай.

так как у тебя всё обернуто в цикл while - в любом месте можешь воткнуть и программа начнется сначала по кругу.

нехочу я цеплять rfid, возьтися с проводами... .

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Лови код. Проверил. Поставишь код своей карточки.

/*
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

        Card UID: E6 38 FE 13  брелок
*/
//#1
byte uidCard[4] = {0xE6, 0x38, 0xFE, 0x13};
#include <SPI.h>
#include <MFRC522.h>
const int SDA_pin = 10;
const int RST_pin = 9;
uint8_t lamp_ON = 0; // лампа горит 1/ 0 нет
uint8_t rfid_OK = 0;// опознование успешно 1/ 0 нет

MFRC522 rfid(SDA_pin, RST_pin); // Instance of the class

void setup() {
  Serial.begin(9600);
  //#1
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522
}

void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  //#1
  if (! rfid_OK && lamp_ON) {
    lamp_ON = 0;
    Serial.println("lamp_OFF");
  }
  static uint32_t past_1_1 = 0 ; // время в течении которого идет сброс флага успеш опознования
  if (rfid_OK && (MILLIS -  past_1_1 >= 100)) rfid_OK = 0; //  если в течении 100 миллисек не было успешного опознования
  static uint32_t past_1 = 0 ;
  if (MILLIS - past_1 >= 20) { // опрос карточки идет каждые 20 миллисек
    past_1 = MILLIS ;
    if ( rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial() &&
         rfid.uid.uidByte[0] == uidCard[0] &&
         rfid.uid.uidByte[1] == uidCard[1] &&
         rfid.uid.uidByte[2] == uidCard[2] &&
         rfid.uid.uidByte[3] == uidCard[3] ) {
      rfid_OK = 1;
      past_1_1 = MILLIS ;
      if ( ! lamp_ON) {
        lamp_ON = 1;
        Serial.println("lamp_ON");
      }
    }
  }
}

 

varvik85
Offline
Зарегистрирован: 28.01.2013

СПАСИБО!!!!!!!!!!!!!!Действительно,все четко,все работает!Но,пожалуйста,расскажите логику работы,чет все так наворочено не пойму,хотелось бы разобраться.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Этот кусок 

  static uint32_t past_1 = 0 ;
  if (MILLIS - past_1 >= 20) { // опрос карточки идет каждые 20 миллисек
    past_1 = MILLIS ;

Вызывает опрос в цикле loop каждые 20 миллисек. Разумеется можно убрать, тогда процессор только этой хренью и будет заниматься

    if ( rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial() &&
         rfid.uid.uidByte[0] == uidCard[0] &&
         rfid.uid.uidByte[1] == uidCard[1] &&
         rfid.uid.uidByte[2] == uidCard[2] &&
         rfid.uid.uidByte[3] == uidCard[3] ) {
      rfid_OK = 1;
      past_1_1 = MILLIS ;

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

  static uint32_t past_1_1 = 0 ; // время в течении которого идет сброс флага успеш опознования
  if (rfid_OK && (MILLIS -  past_1_1 >= 100)) rfid_OK = 0; //  если в течении 100 миллисек не было успешного опознования

Этот кусок сбрасывает флаг по истечении определеного времени, если пошли неверные запросы. Смотри код выше.

      if ( ! lamp_ON) {
        lamp_ON = 1;
        Serial.println("lamp_ON");

Этот кусок включает лампу.

  if (! rfid_OK && lamp_ON) {
    lamp_ON = 0;
    Serial.println("lamp_OFF");
  }

Ну а этот выключает. Конечно он должен стоят вверху блока   //#1 в секции loop()

ПС: Да код плотный. Так как я использовал уже провереные куски. Но рабочим может быть код который проверен на практике. Так что пришлось не только собирать, но и тестировать ее. Что занимает больше времени чем написание. И самое главное отрабатывать кучу вариантов отсеивая не рабочие или не очень "надежные".

varvik85
Offline
Зарегистрирован: 28.01.2013

Спасибо!

shadow174
Offline
Зарегистрирован: 07.06.2021

Здравствуйте.

Возникла необходимость использовать ваш проект с несколькими картами Rfid, но что то ни как не могу сделать привязку второй карты. Либо не видит нижнюю часть кода, либо на первую карту отрабатывает без задержки, вторая работает как задумано автором кода. 

Подскажите как решить проблему.

byte uidCard1[4] = {0xBA, 0x6B, 0xFE, 0xBE};
byte uidCard2[4] = {0xCC, 0xB8, 0xC1, 0x38};

#include <SPI.h>
#include <MFRC522.h>
const int SDA_pin = 10;
const int RST_pin = 9;
const int LOCK = 6;   // подключаем электрозамок
uint8_t lamp_ON = 0; // лампа горит 1/ 0 нет
uint8_t rfid_OK = 0;// опознование успешно 1/ 0 нет
MFRC522 rfid(SDA_pin, RST_pin); // Instance of the class

void setup() {
Serial.begin(9600);
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
pinMode(LOCK, OUTPUT);    //объявляем пин как выход.
digitalWrite(LOCK, HIGH);  //Выключаем реле
Serial.println("Поднесите карту к считывателю");
}
void loop() {
static uint32_t MILLIS ;
MILLIS = millis() ;
if (! rfid_OK && lamp_ON) {
lamp_ON = 0;
Serial.println("Доступ запрещён");
digitalWrite(LOCK, HIGH);     // Выключаем реле
}
static uint32_t past_1_1 = 0 ; // время в течении которого идет сброс флага успеш опознования
if (rfid_OK && (MILLIS -  past_1_1 >= 100)) rfid_OK = 0; //  если в течении 100 миллисек не было успешного опознования
static uint32_t past_1 = 0 ;
if (MILLIS - past_1 >= 20) { // опрос карточки идет каждые 20 миллисек
past_1 = MILLIS ;
if ( rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()){
if (rfid.uid.uidByte[0] == uidCard1[0] ||
    rfid.uid.uidByte[0] == uidCard1[1] ||
    rfid.uid.uidByte[0] == uidCard1[2] ||
    rfid.uid.uidByte[0] == uidCard1[3] ) { 
rfid_OK = 1;
past_1_1 = MILLIS ;
if ( ! lamp_ON) 
lamp_ON = 1;
Serial.println("lamp_ON");
digitalWrite(LOCK, LOW);     // Включаем реле
}
if (rfid.uid.uidByte[0] == uidCard2[0] ||
rfid.uid.uidByte[0] == uidCard2[1] ||
rfid.uid.uidByte[0] == uidCard2[2] ||
rfid.uid.uidByte[0] == uidCard2[3] ) {
rfid_OK = 1;
past_1_1 = MILLIS ;
if ( ! lamp_ON) {
lamp_ON = 1;
Serial.println("lamp_ON2");
digitalWrite(LOCK, LOW);     // Включаем реле
}
}
}
}
}
b707
Offline
Зарегистрирован: 26.05.2017

отформатируйте код нормально

shadow174
Offline
Зарегистрирован: 07.06.2021

Извините, но я новичек.

Что значит - отформатировать?

b707
Offline
Зарегистрирован: 26.05.2017

выровнять отступы и убрать огромные пустые куски

ДЛя первого в ИДЕ есть кнопка CTRL_T, второе - вручную

shadow174
Offline
Зарегистрирован: 07.06.2021

Пробовал перейти на метки в десятичном формате, предварительно записав ключи в const char* keys[]={"204 184 193 56","240 222 56 27"} - но не смог сделать запрос, не нашел чем заменить команду uidCard.

Подскажите куда копать, 4 дня уже курю форумы и как понял каждый пишет по своему, нет какого либо эталона.

shadow174
Offline
Зарегистрирован: 07.06.2021

b707 пишет:

выровнять отступы и убрать огромные пустые куски

ДЛя первого в ИДЕ есть кнопка CTRL_T, второе - вручную

Поправил. Не подскажите как решить дилему?

b707
Offline
Зарегистрирован: 26.05.2017

shadow174 пишет:

b707 пишет:

выровнять отступы и убрать огромные пустые куски

Поправил.

ругаться неохота, но ничего вы не "поправили". Неужели трудно в Ардуино ИДЕ нахать одну кнопку???

Вот так оно должно выглядеть:

byte uidCard1[4] = {0xBA, 0x6B, 0xFE, 0xBE};
byte uidCard2[4] = {0xCC, 0xB8, 0xC1, 0x38};

#include <SPI.h>
#include <MFRC522.h>
const int SDA_pin = 10;
const int RST_pin = 9;
const int LOCK = 6;   // подключаем электрозамок
uint8_t lamp_ON = 0; // лампа горит 1/ 0 нет
uint8_t rfid_OK = 0;// опознование успешно 1/ 0 нет
MFRC522 rfid(SDA_pin, RST_pin); // Instance of the class

void setup() {
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522
  pinMode(LOCK, OUTPUT);    //объявляем пин как выход.
  digitalWrite(LOCK, HIGH);  //Выключаем реле
  Serial.println("Поднесите карту к считывателю");
}
void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  if (! rfid_OK && lamp_ON) {
    lamp_ON = 0;
    Serial.println("Доступ запрещён");
    digitalWrite(LOCK, HIGH);     // Выключаем реле
  }
  static uint32_t past_1_1 = 0 ; // время в течении которого идет сброс флага успеш опознования
  if (rfid_OK && (MILLIS -  past_1_1 >= 100)) rfid_OK = 0; //  если в течении 100 миллисек не было успешного опознования
  static uint32_t past_1 = 0 ;
  if (MILLIS - past_1 >= 20) { // опрос карточки идет каждые 20 миллисек
    past_1 = MILLIS ;
    if ( rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
      if (rfid.uid.uidByte[0] == uidCard1[0] ||
          rfid.uid.uidByte[1] == uidCard1[1] ||
          rfid.uid.uidByte[2] == uidCard1[2] ||
          rfid.uid.uidByte[3] == uidCard1[3] ) {
        rfid_OK = 1;
        past_1_1 = MILLIS ;
        if ( ! lamp_ON)
          lamp_ON = 1;
        Serial.println("lamp_ON");
        digitalWrite(LOCK, LOW);     // Включаем реле
      }
      if (rfid.uid.uidByte[0] == uidCard2[0] ||
          rfid.uid.uidByte[1] == uidCard2[1] ||
          rfid.uid.uidByte[2] == uidCard2[2] ||
          rfid.uid.uidByte[3] == uidCard2[3] ) {
        rfid_OK = 1;
        past_1_1 = MILLIS ;
        if ( ! lamp_ON) {
          lamp_ON = 1;
          Serial.println("lamp_ON2");
          digitalWrite(LOCK, LOW);     // Включаем реле
        }
      }
    }
  }
}

смысл в том, что отступ каждой строки соответвует уровню вложенности цикла или процедуры. Так сразу видно, где начало блока, а где конец и прослеживать логику программы в разы проще

По сути посмотрю попозже.

Могу только сразу сказать - переводить метки в char* - это глупость, не надо этого делать.

b707
Offline
Зарегистрирован: 26.05.2017

хотя сразу вижу косяк, сравнение карт неверное

в условии проверки карты:

 if (rfid.uid.uidByte[0] == uidCard1[0] ||
          rfid.uid.uidByte[1] == uidCard1[1] ||
          rfid.uid.uidByte[2] == uidCard1[2] ||
          rfid.uid.uidByte[3] == uidCard1[3] )

сравнения всех байт должны быть обьединены логическим оператором "И", а у вас "ИЛИ". И для второй карты тоже самое

shadow174
Offline
Зарегистрирован: 07.06.2021

b707 пишет:

хотя сразу вижу косяк, сравнение карт неверное

в условии проверки карты:

 if (rfid.uid.uidByte[0] == uidCard1[0] ||
          rfid.uid.uidByte[1] == uidCard1[1] ||
          rfid.uid.uidByte[2] == uidCard1[2] ||
          rfid.uid.uidByte[3] == uidCard1[3] )

сравнения всех байт должны быть обьединены логическим оператором "И", а у вас "ИЛИ". И для второй карты тоже самое

Изначально было так, остальная глупость от безысходности((

if (rfid.uid.uidByte[0] == uidCard1[0] ||
         rfid.uid.uidByte[0] == uidCard1[1] ||
         rfid.uid.uidByte[0] == uidCard1[2] ||
         rfid.uid.uidByte[0] == uidCard1[3] )
shadow174
Offline
Зарегистрирован: 07.06.2021

b707 пишет:

Могу только сразу сказать - переводить метки в char* - это глупость, не надо этого делать.

Вам виднее. У меня мнение относительно char сложилось из за имеющегося кода, в нем не нужно лишних блоков прописывать - достаточно только номера карт вписать. Но тот код только для замка, а мне нужно именно присутствие карт на считывателе.

 

// карта - 204 184 193 56
// брелок - 133 193 216 101

#include <SPI.h>
#include <MFRC522.h>
 
const int SS_PIN = 10;      // SS вывод модуля RC522
const int RST_PIN = 9;      // RST вывод модуля RC522

const int BUZZER = 2;       //Пин для Пищалки
const int LED_R = 3;        //Пин для Красного цвета
const int LED_G = 4;        //Пин для Зелёного цвета
const int LED_B = 5;        //Пин для Голубого цвета
const int LOCK = 6;         // подключаем электрозамок


const char* keys[]={"204 184 193 56","240 222 56 27"}; // ,"240 222 56 27","02 187 203 27"

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
 
void setup() 
{
  Serial.begin(9600);       // Initiate a serial communication
  SPI.begin();              // Initiate  SPI bus
  mfrc522.PCD_Init();       // Initiate MFRC522
  pinMode(LED_G, OUTPUT);   //объявляем пин как выход.
  pinMode(LED_R, OUTPUT);   //объявляем пин как выход.
  pinMode(LED_B, OUTPUT);   //объявляем пин как выход.
  pinMode(BUZZER, OUTPUT);  //объявляем пин как выход.
  pinMode(LOCK, OUTPUT);    //объявляем пин как выход.
  noTone(BUZZER);
  digitalWrite(LOCK, HIGH);  //Выключаем замок
  Serial.println("Поднесите карту к считывателю");
}
void loop() 
{
  if ( ! mfrc522.PICC_IsNewCardPresent()){
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()){
    return;
  }

  Serial.print("UID:");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], DEC);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], DEC));
  }
  Serial.println();
  content.toUpperCase();

int x=1;
  for (int i = 0; i < sizeof(keys) / sizeof(char *); i++){
  if (content.substring(1) == keys[i]){
    Serial.println("Доступ разрешён");
    digitalWrite(LOCK, LOW);     // Включаем Замок
    digitalWrite(LED_G, HIGH);    // Зажигаем Зелёный светодиод 
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_B, LOW);
    delay(5000);
    digitalWrite(LED_G, LOW);    // Гасим Зелёный светодиод
    digitalWrite(LOCK, HIGH);     // Выключаем Замок
    return;
  } 
  else  x=0;
}

 if(x==0){
    Serial.println("Доступ запрещён");
    digitalWrite(LED_R, HIGH);
    digitalWrite(LED_G, LOW);
    digitalWrite(LED_B, LOW);
    tone(BUZZER, 300);
    delay(1000);
    digitalWrite(LED_R, LOW);
}   noTone(BUZZER);
 
}

 

b707
Offline
Зарегистрирован: 26.05.2017

shadow174 пишет:

Изначально было так, остальная глупость от безысходности((

не понял, как было изначально, но сейчас неверно, исправляйте.

Правда, насколько я вижу, на чтение второй карты эта ошибка влиять не должна, значит есть и другие.