Adicionar botão em cod RFID

Olá Pessoal!!!

Estou quebrando a cabeça já tem uns 5 dias, revirei o google e o forum e nada! :confused: para conseguir fazer uma alteração no código do "RFID Access Control". Na verdade, já alterei algumas coisas, porém, empaquei na adição de um botão no meio do processo. Não tenho o domínio da linguagem de programação e isso me dificulta esta alteração/criação.

Ao aproximar o cartão cadastrado, ele permite o acesso e liga os relés dos pins 3 e 4 e os deixa ligado. (até aqui, esta tudo ok)

O que preciso criar e peço a ajuda de vocês, é isto:
Criar um botão ligado ao pin 6, que ao ser acionado, o sistema comece a contar por exemplo: 50 seg e a cada 10 seg, emita um som. E ao término do tempo, que desligue os 2 relés. Porém, caso eu queira cancelar esse desarme, basta aproximar o cartão cadastrado ao leitor de rfid. Acredito que a função getID() chame a leitura do cartão
Detalhe, o tempo não pode ser reiniciado caso ele já esteja correndo.

Não faço a menor idéia de onde colocaria as instruções do botão (talvez no loop) e tampouco de como fazê-lo.

Se alguém puder me ajudar, ficarei imensamente grato!

Godoy

#include <EEPROM.h>
#include <SPI.h>
#include <MFRC522.h>


#define BUZZER 8
#define botao 6    // botao
#define wipeB 5

#define relay_2 4      // rele
#define relay_1 3     // rele

boolean match = false;
boolean programMode = false;
boolean replaceMaster = false;

int successRead;

byte storedCard[4];
byte readCard[4];
byte masterCard[4];

#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

// Setup //
void setup() {
  pinMode(wipeB, INPUT_PULLUP);
  pinMode(botao, INPUT_PULLUP);
  pinMode(relay_1, OUTPUT);
  pinMode(relay_2, OUTPUT);
  digitalWrite(relay_1, LOW);
  digitalWrite(relay_2, LOW);
 
  
  Serial.begin(9600); 
  SPI.begin();
  mfrc522.PCD_Init();

  Serial.println(F("Access Control v3.4"));
  ShowReaderDetails();

  
  if (digitalRead(wipeB) == LOW) { 
    Serial.println(F("Botao de limpeza pressionado"));
    Serial.println(F("Voce tem 5 segundos para cancelar"));
    Serial.println(F("Isso removera todos os registros sem volta!"));
    delay(5000);
    if (digitalRead(wipeB) == LOW) {
      Serial.println(F("Iniciando Limpeza da EEPROM"));
      for (int x = 0; x < EEPROM.length(); x = x + 1) {
        if (EEPROM.read(x) == 0) {
        }
        else {
          EEPROM.write(x, 0);
        }
      }
      Serial.println(F("EEPROM limpa com sucesso!!!"));
     tone(8, 600, 50);
     delay(150);
     }
    else {
      Serial.println(F("Limpeza Cancelada"));
     tone(8, 900, 100);
         
    }
  }
  if (EEPROM.read(1) != 143) {
    Serial.println(F("Nenhum cartao Master foi definido"));
    Serial.println(F("Digitalize um Cartao para Definir como Master"));
    do {
      successRead = getID();
    tone(8, 1600, 250);
    delay(300);
    tone(8, 1600, 250);

    }
    while (!successRead);
    for ( int j = 0; j < 4; j++ ) {
      EEPROM.write( 2 + j, readCard[j] );
    }
    EEPROM.write(1, 143);
    Serial.println(F("Cartao master Definido"));
  }
  Serial.println(F("-------------------"));
  Serial.println(F("UID do Cartao master"));
  for ( int i = 0; i < 4; i++ ) {
    masterCard[i] = EEPROM.read(2 + i);
    Serial.print(masterCard[i], HEX);
  }
  Serial.println("");
  Serial.println(F("-----------"));
  Serial.println(F("Tudo pronto"));
  Serial.println(F("Aguarnando cartoes para serem escaneados...."));
  cycleLeds();
}


// Main Loop
void loop () {
  do {
    successRead = getID();
    if (digitalRead(wipeB) == LOW) {
      Serial.println(F("Botao de limpeza pressionado"));
      Serial.println(F("Cartao Master sera deletado em 5 segundos"));
      delay(5000);
      if (digitalRead(wipeB) == LOW) {
        EEPROM.write(1, 0);
        Serial.println(F("Reinicie o dispositivo para reprogramar o Cartao Master"));
        while (1);
      }
    }
    if (programMode) {
      cycleLeds_2();
    }
    else {
      normalModeOn();
    }
  }
  while (!successRead);
  if (programMode) {
    if ( isMaster(readCard) ) {
      Serial.println(F("Cartao Master Escaneado"));
      Serial.println(F("Saindo do modo ADM"));
      Serial.println(F("------"));
      programMode = false;
      return;
    }
    else {
      if ( findID(readCard) ) {
        Serial.println(F("Conheco este Cartao, removendo ..."));
        deleteID(readCard);
        Serial.println("------");
        Serial.println(F("Escaneie um Cartao para ADICIONAR ou REMOVER da EEPROM"));
      }
      else {
        Serial.println(F("Nao conheco este Cartao, adicionando..."));
        writeID(readCard);
        Serial.println(F("------"));
        Serial.println(F("Escaneie um Cartao para ADICIONAR ou REMOVER da EEPROM"));
      }
    }
  }
  else {
    if ( isMaster(readCard)) {
      programMode = true;
      Serial.println(F("Ola Cartao Master - Acessando modo ADM"));
      int count = EEPROM.read(0);
      Serial.print(F("Eu tenho "));
      Serial.print(count);
      Serial.print(F(" Registro(s) na EEPROM"));
      Serial.println("");
      Serial.println(F("Escaneie um Cartao para ADICIONAR ou REMOVER da EEPROM"));
      Serial.println(F("Escaneie o Cartao master para sair do modo ADM"));
      Serial.println(F("------"));
    }
    else {
      if ( findID(readCard) ) {
        Serial.println(F("Bem vindo, voce pode passar"));
        granted();
      }
      else {
        Serial.println(F("Acesso negado!"));
        denied();
      }
    }
  }
}

///  Access Granted
void granted () {
  digitalWrite(relay_1, HIGH);
  digitalWrite(relay_2, HIGH);
  tone(8, 1600, 250);
  delay(250);
  tone(8, 1600, 250);
}

// Access Denied
void denied() {
  tone(8, 1400, 400);
  delay(1000);
}

/// Get PICC's UID
int getID() {

  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return 0;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return 0;
  }
  Serial.println(F("Cartao Escaneado UID:"));
  for (int i = 0; i < 4; i++) {
    readCard[i] = mfrc522.uid.uidByte[i];
    Serial.print(readCard[i], HEX);
  }
  Serial.println("");
  mfrc522.PICC_HaltA();
  return 1;
}

void ShowReaderDetails() {
 
  byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
  Serial.print(F("MFRC522 Software Version: 0x"));
  Serial.print(v, HEX);
  if (v == 0x91)
    Serial.print(F(" = v1.0"));
  else if (v == 0x92)
    Serial.print(F(" = v2.0"));
  else
    Serial.print(F(" (Desconhecido),Provavel copia chinesa?"));
  Serial.println("");
  if ((v == 0x00) || (v == 0xFF)) {
    Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
    Serial.println(F("SYSTEM HALTED: Check connections."));
    while (true);
  }
}

/// Cycle Leds (Program Mode)
void cycleLeds() {
tone(8, 1800, 200);
delay(100);
tone(8, 1800, 200);
}

/// Cycle Leds (Program Mode)
void cycleLeds_2() {
tone(8, 1200, 200);
delay(100);
}

/// Normal Mode Led
void normalModeOn () {

}

/// Read an ID from EEPROM
void readID( int number ) {
  int start = (number * 4 ) + 2;
  for ( int i = 0; i < 4; i++ ) {
    storedCard[i] = EEPROM.read(start + i);
  }
}

void writeID( byte a[] ) {
  if ( !findID( a ) ) {
    int num = EEPROM.read(0);
    int start = ( num * 4 ) + 6;
    num++;
    EEPROM.write( 0, num );
    for ( int j = 0; j < 4; j++ ) {
      EEPROM.write( start + j, a[j] );
    }
    successWrite();
    Serial.println(F("Registro adicionado na EEPROM"));
  }
  else {
    failedWrite();
    Serial.println(F("Erro! Ha algo de errado com ID ou problemas na EEPROM"));
  }
}

void deleteID( byte a[] ) {
  if ( !findID( a ) ) {
    failedWrite();
    Serial.println(F("Failed! There is something wrong with ID or bad EEPROM"));
  }
  else {
    int num = EEPROM.read(0);
    int slot;
    int start;
    int looping;
    int j;
    int count = EEPROM.read(0); 
    slot = findIDSLOT( a );
    start = (slot * 4) + 2;
    looping = ((num - slot) * 4);
    num--;
    EEPROM.write( 0, num );
    for ( j = 0; j < looping; j++ ) {
      EEPROM.write( start + j, EEPROM.read(start + 4 + j));
    }
    for ( int k = 0; k < 4; k++ ) {
      EEPROM.write( start + j + k, 0);
    }
    successDelete();
    Serial.println(F("Sucesso, removido da EEPROM"));
  }
}

boolean checkTwo ( byte a[], byte b[] ) {
  if ( a[0] != NULL )
    match = true;
  for ( int k = 0; k < 4; k++ ) {
    if ( a[k] != b[k] )
      match = false;
  }
  if ( match ) {
    return true;
  }
  else  {
    return false;
  }
}

int findIDSLOT( byte find[] ) {
  int count = EEPROM.read(0);
  for ( int i = 1; i <= count; i++ ) {
    readID(i);
    if ( checkTwo( find, storedCard ) ) {
      return i;
      break;
    }
  }
}

boolean findID( byte find[] ) {
  int count = EEPROM.read(0);
  for ( int i = 1; i <= count; i++ ) {
    readID(i);
    if ( checkTwo( find, storedCard ) ) {
      return true;
      break;
    }
    else {
    }
  }
  return false;
}

/// Write Success to EEPROM
void successWrite() {
tone(8, 1500, 200);
delay(150);
tone(8, 1500, 200);
delay(200);
}

/// Write Failed to EEPROM
void failedWrite() {
tone(8, 1400, 200);
delay(200);
tone(8, 1400, 200);
}
// Success Remove UID From EEPROM
void successDelete() {
delay(200);
tone(8, 1900, 100);
delay(200);
}

boolean isMaster( byte test[] ) {
  if ( checkTwo( test, masterCard ) )
    return true;
  else
    return false;
}

Precisas de ver como usar a função millis().

Não tenho tempo para ver o código todo, mas isto deve fazer mais ou menos o que pretendes:

unsigned long cnt_tempo = 0; // isto vai guardar tempos.
const unsigned int botao = 6; //botao. 
unsigned char porta_aberta = 0; //flag para guardar o estado da porta.
unsigned char tempo_cont = 0; //isto indica que o tempo está a contar. 
unsigned char vezes_beeps = 0; //numero de beeps emitidos.  


///  Access Granted
void granted () {
  digitalWrite(relay_1, HIGH);
  digitalWrite(relay_2, HIGH);
  tone(8, 1600, 250);
  delay(250);
  tone(8, 1600, 250);
  // ADICIONADO 
  porta_aberta = 1; // esta variável tem de ser mantida com o estado dos relés. 
}

if (digitalRead(botao) == HIGH && porta_aberta == 1) { //porta está aberta e o botao foi pressionado.
   cnt_tempo = millis(); 
   tempo_cont = 1; 
}

if (tempo_cont == 1 && (millis() - cnt_tempo > 10000)) {
  
  
  tone(8, 1600, 250);
  delay(250);
  tone(8, 1600, 250);
  vezes_beeps++; 
  cnt_tempo = millis();  
  if (vezes_beeps == 6) { //passou 60 segundos. desligar tudo. 
     tempo_cont = 0; 
     cnt_tempo = 0;
     porta_aberta = 0;
     digitalWrite(relay_1, LOW);
     digitalWrite(relay_2, LOW);
  }
  
 
}

Duvido que funcione à primeira e certamente que há uma maneira melhor de fazer isto, mas deve dar para perceber uma maneira de conseguir o que queres.

Boas Bubulindo!!!

Acabei de inserir esse código no sketch, apresentou alguns erros, fiz alterações e sumiram os tais erros. Porém, nada aconteceu :frowning: Nem sequer os beeps se pronunciaram :smiley:

Mas foi de grande ajuda ter me dado o norte como direção (leia-se função millis()). Vou continuar tentando.

Obrigado,

Godoy

Como disse, o código não foi testado e estava um pouco à pressa. Mas a lógica é:

Se os relés são activados, a variável porta_aberta passa para 1.

Se o botão que referiste for pressionado quando a porta está aberta, a variável tempo_cont passa a 1 e a temporização de 10 segundos começa.

Se passarem 10 segundos, uma variável é incrementada e um beep é emitido. Quando a variável chegar a 6, as variáveis são postas a zero e a porta fecha.

Uma coisa a ter em conta é que as variáveis que defini tem de ser globais ou seja definidas fora das funções.

Boas Bubulindo,

Para falar a verdade, metade do que você disse, é russo para mim. :confused: Estou estudando arduino e muitas das coisas, simplesmente não entram na minha cabeça. Em certas partes do código eu paro para olhar e fico pensando.. Que diabos quer dizer esse monte de sinais. :frowning:

Mas fico agradecido por sua ajuda. Vou continuar tentando e ver se sai algo daqui.

Godoy