ardumotivejohn_vslks
Published © CC BY-NC-SA

Arduino RFID System Based on RS485

In this DIY guide, I will show you how to make your own security check system based on Arduino!

AdvancedFull instructions provided3,924
Arduino RFID System Based on RS485

Things used in this project

Hardware components

Master PCB
×1
Slave PCB
×1
ATmega328
Microchip ATmega328
×2
28 dip socket
×2
16 MHz Crystal
16 MHz Crystal
×2
Capacitor 22 pF
Capacitor 22 pF
×4
Capacitor 100 nF
Capacitor 100 nF
×2
Capacitor 10 µF
Capacitor 10 µF
×2
Resistor 10k ohm
Resistor 10k ohm
×2
Single Turn Potentiometer- 10k ohms
Single Turn Potentiometer- 10k ohms
×2
Screw terminal 2P 2.54mm
×2
Pin Header 1x5 Female 2.54mm​
×4
Transceiver RS422, RS485
Transceiver RS422, RS485
×2
RGB LCD Shield Kit, 16x2 Character Display
RGB LCD Shield Kit, 16x2 Character Display
×2
RFID MFRC-522 Module
×2
Real Time Clock (RTC)
Real Time Clock (RTC)
×2
32.768 kHz Crystal
32.768 kHz Crystal
×1
Coin Cell Battery CR2032
Coin Cell Battery CR2032
×1
Arduino USB 2 Serial micro
Arduino USB 2 Serial micro
×1
Arduino UNO
Arduino UNO
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Breadboard, 270 Pin
Breadboard, 270 Pin

Story

Read more

Custom parts and enclosures

PCB Schematic

Schematics

Circuit Schematic

Code

Master

C/C++
Code for the master station unit. The "Master Station" is responsible for the communication between "Slave stations" via RS485 data bus. It also communicate via serial port with the software that is running to "control room" computer.
#include <SPI.h>
#include <SoftwareSerial.h>
#include <MFRC522.h>
#include <Wire.h>
//Buzzer
#define buzzer 8
//RS485
#define rs485_RX A0
#define rs485_TX A1
#define rs485_DE A2
#define rs485_RE A3
SoftwareSerial rs485(rs485_RX, rs485_TX); // RX, TX
String MASTER_PORT = "FF";
String newCard="";
//RFID
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

char incomingByte;
String command;
boolean messageCompleted = false;
boolean newMessage = false;

void setup() {
  pinMode(rs485_RE, OUTPUT);
  pinMode(rs485_DE, OUTPUT);
  digitalWrite(rs485_RE, LOW);
  digitalWrite(rs485_DE, LOW);
  Serial.begin(9600);
  rs485.begin(19200);
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
}

void loop() {
  serialCommunication();
  readCard();
  rs485Communication();
}
void readCard() {
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  //Show UID on serial monitor
  String card = "";
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    card.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    card.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  card.toUpperCase();
  card = card.substring(1);
  card.replace(" ", "");
  newCard = card;
  tone(buzzer,500,300);
}
void serialCommunication() {
  if (rs485.available()) {
    incomingByte = rs485.read();
    if (incomingByte == '>') {
      messageCompleted = true;
      newMessage = false;
    }
    else if (incomingByte == '<') {
      newMessage = true;
    }

    if (newMessage) {
      command.concat(incomingByte);
    }
  }

  if (messageCompleted) {
    if (command.substring(1, 3) == MASTER_PORT) {
      if (command.charAt(3) == 't') {
        Serial.println(command.substring(4));
      }
      else if (command.charAt(3) == 'c') {
        String index = command.substring(4,5);
        String card = command.substring(5);
        card.replace("xxxxxxxx","NOT SET");
        Serial.println(index+": "+card);
      }
      //Report last check to master - time and card id
      else if (command.charAt(3) == 'r') {
        Serial.println(command.substring(4));
      }
    }
    command = "";
    messageCompleted = false;
  }
}
void rs485Communication(){
  if (Serial.available()) {
    incomingByte = Serial.read();
    if (incomingByte == '>') {
      messageCompleted = true;
      newMessage = false;
    }
    else if (incomingByte == '<') {
      newMessage = true;
    }

    if (newMessage) {
      command.concat(incomingByte);
    }
  }
  if (messageCompleted) {
    if (command.substring(1, 3) != MASTER_PORT) {
      digitalWrite(rs485_DE,HIGH);
      rs485.print(command+">");
    }   
    else{
      Serial.println(newCard);
      newCard="";
    }
    command = "";
    messageCompleted = false;
  }
  digitalWrite(rs485_DE,LOW);
}

Slave

C/C++
Code for the slave station units. Every "Slave Station" - check point unit has a unique address. Edit the variable "PORT" (line 25) with hex value of unit address - value from 01 to FE (total of 254 stations). Also change the "name" of the current station by editing the variable "point" at line 24. Every check point can store to EEPROM memory up to 10 card IDs. If the security card exist, the ID and time-stamp will be saved to EEPROM memory.
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include "RTClib.h"
#include <SoftwareSerial.h>
#include <EEPROM.h>

#define rs485_RX A0
#define rs485_TX A1
#define rs485_DE A2
#define rs485_RE A3
SoftwareSerial rs485(rs485_RX, rs485_TX); // RX, TX


//RFID
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
String cards[10] = {"", "", "", "", "", "", "", "", "", ""};
String check;
String check_card;
String check_time;
String point = "Point A"; //Point B, Point C
String PORT = "01"; //FROM 01,02,03 TO FE - Total of 254 Slave stations
String MASTER_PORT = "FF";

//Time
RTC_DS1307 rtc;
String currentTime, DD, MM, YYYY, hh, mm;

//LCD
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

//Buzzer
#define buzzer 8

//Serial Communication
char incomingByte;
String command;
boolean messageCompleted = false;
boolean newMessage = false;

void setup() {
  pinMode(rs485_RE, OUTPUT);
  pinMode(rs485_DE, OUTPUT);
  digitalWrite(rs485_RE, LOW);
  digitalWrite(rs485_DE, LOW);
  Serial.begin(9600);   // Initiate a serial communication
  rs485.begin(19200);
  //RFID
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522

  //RTC
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
  }

  //LCD
  lcd.begin(16, 2);

  //Buzzer
  pinMode(buzzer, OUTPUT);
  //Read last check from EEPROM memory (card id and timestamp)
  delay(10);
  check_card = readFromMemory(0, 8);
  delay(10);
  check_time = readFromMemory(10, 16);
  delay(10);
  //Read Card id list from memory
  for (int i = 0; i < 10; i++) {
    cards[i] = readFromMemory(30 + (i * 10), 8);
    //storeInMemory(30 + (i*10), "xxxxxxxx");
    delay(10);
    Serial.println(cards[i]);
  }
  Serial.println("System is up and running");
}


void setTime(int YYYY, int MM, int DD, int hh, int mm) {
  rtc.adjust(DateTime(YYYY, MM, DD, hh, mm, 0));
}

void readTime() {
  //DAY
  DateTime now = rtc.now();
  if (now.day() <= 9) {
    DD = "0" + String(now.day());
  }
  else {
    DD = String(now.day());
  }

  //MONTH
  if (now.month() <= 9) {
    MM = "0" + String(now.month());
  }
  else {
    MM = String(now.month());
  }

  //HOUR
  if (now.hour() <= 9) {
    hh = "0" + String(now.hour());
  }
  else {
    hh = String(now.hour());
  }

  //MINUTE
  if (now.minute() <= 9) {
    mm = "0" + String(now.minute());
  }
  else {
    mm = String(now.minute());
  }

  //YEAR
  if (now.year()) {
    YYYY = String(now.year());
  }
  currentTime = DD + "/" + MM + "/" + YYYY + " " + hh + ":" + mm;
}

void checkCard() {
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    check = "";
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    check = "";
    return;
  }
  //Show UID on serial monitor
  String card = "";
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    card.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    card.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  card.toUpperCase();
  card = card.substring(1);
  card.replace(" ", "");
  for (int i = 0; i < 10; i++) {
    if (card == cards[i]) {
      check = "VALID: " + String(card);
      check_card = String(card);
      check_time = currentTime;
      storeInMemory(0, check_card); //Start store card id from memory addr 0
      storeInMemory(10, check_time); //Start store time stamp from memory addr 10
      return;
    }
    else {
      check = "Card Not found...";
    }
  }
}

void printLCD(String line1, String line2) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(line1);
  lcd.setCursor(0, 1);
  lcd.print(line2);
}

void buzzerTone() {
  tone(buzzer, 1000); // Send 1KHz sound signal...
  delay(1000);        // ...for 1 sec
  noTone(buzzer);     // Stop sound...
}

void storeInMemory(char addr, String data) {
  int _size = data.length();
  int i;
  for (i = 0; i < _size; i++)
  {
    EEPROM.write(addr + i, data[i]);
  }
  EEPROM.write(addr + _size, '\0'); //Add termination null character for String Data
}
String readFromMemory(char addr, int size)
{
  int i;
  char data[size + 1];
  int len = 0;
  unsigned char k;
  k = EEPROM.read(addr);
  while (len < size) //Read until null character
  {
    k = EEPROM.read(addr + len);
    data[len] = k;
    len++;
  }
  data[len] = '\0';
  return String(data);
}

void serialCommunication() {
  if (rs485.available()) {
    incomingByte = rs485.read();
    if (incomingByte == '>') {
      messageCompleted = true;
      newMessage = false;
    }
    else if (incomingByte == '<') {
      newMessage = true;
    }

    if (newMessage) {
      command.concat(incomingByte);
    }
  }

  if (messageCompleted) {
    if (command.substring(1, 3) == PORT || command.substring(1, 3) == "00" ) {
      //Set time
      if (command.charAt(3) == 'T') {
        int YYYY = (command.substring(4, 8)).toInt();
        int MM = (command.substring(8, 10)).toInt();
        int DD = (command.substring(10, 12)).toInt();
        int hh = (command.substring(12, 14)).toInt();
        int mm = (command.substring(14)).toInt();
        setTime(YYYY, MM, DD, hh, mm);
      }
      //Set cards ids
      else if (command.charAt(3) == 'C') {
        int index = (command.substring(4, 5)).toInt();
        String id = command.substring(5);
        cards[index] = id;
        //Store in memory!
        storeInMemory(30 + (index * 10), id); //Start store card id from memory addr 30
      }
    }
    if (command.substring(1, 3) == PORT) {
      //Report time of this slave station to master
      if (command.charAt(3) == 't') {
        digitalWrite(rs485_DE, HIGH);
        rs485.println("<" + MASTER_PORT + "t" + currentTime + ">");
        digitalWrite(rs485_DE, LOW);
      }
      //Report card ids of this slave station to master
      else if (command.charAt(3) == 'c') {
        int index = (command.substring(4,5)).toInt();
        String MSG = "<" + MASTER_PORT + "c"+String(index);
        MSG += cards[index] + ">";
        digitalWrite(rs485_DE, HIGH);
        rs485.println(MSG);
        digitalWrite(rs485_DE, LOW);
      }
      //Report last check to master - time and card id
      else if (command.charAt(3) == 'r') {
        digitalWrite(rs485_DE, HIGH);
        rs485.println("<" + MASTER_PORT + "r" + check_card + " " + check_time + ">");
        digitalWrite(rs485_DE, LOW);
      }
    }
    command = "";
    messageCompleted = false;
  }
}
void loop() {
  serialCommunication();
  checkCard();
  printLCD("Waiting for Card", point);
  readTime();
  if (check != "") {
    printLCD(currentTime, check);
    buzzerTone();
    delay(2000);
  }
}

Credits

ardumotive

ardumotive

1 project • 4 followers
john_vslks

john_vslks

0 projects • 1 follower

Comments