/* ======   DEKLARASI LIBRARY MFRC522 BESERTA KONSTANTA TERKAIT ====== */
#include <MFRC522.h> //Library MFRC522
#include <SPI.h>     //Library SPI
#define SS1 8    //pin SS1 modul-1 RFID terhubung ke pin 10 Arduino
#define SS2 9     //pin SS2 modul-2 RFID terhubung ke pin 10 Arduino
#define RST 10    //pin RST modul-1 RFID terhubung ke pin 9 Arduino
MFRC522 rfid1(SS1, RST); //Deklarasi nama objek 'rfid' utk modul-1
MFRC522 rfid2(SS2, RST); //Deklarasi nama objek 'rfid' utk modul-2
//=======================================================================
/* ==== Deklarasi Library Modul SD-card beserta konstanta terkait ==== */
#include <SD.h>     //deklarasi library SD 
String fileName= "parkir.txt"; //variabel nama file utk membuat file
String uid = "";    //variabel tipe string dibuat kosong
String dataKartu;   //variabel penyimpan dataKartu (uid) sbg tipe String
File myFile;        //deklarasi variabel myFile sebagai tipe File
File root;          //deklarasi variabel root sebagai tipe File
//======================================================================
//====== Deklarasi Library-variabel-konstanta terkait Library RTC ======
#include <DS3231.h> //deklarasi library utk modul RTC
#include <Wire.h>   //deklarasi protokol I2C
DS3231 myRTC;       //deklarasi nama objek myRTC utk modul RTC
int second, minute, hour;  //deklarasi variabel detik, menit dan jam
String namaHari, tanggal, jam; 
bool CenturyBit=false;//penanda overflow thn 2099 ke 2100 tdk digunakan
bool h12Flag, pmFlag; //deklarasi variabel boolean utk mode 12h/24h 
//-----------------------------------------------------------------------
#define Buz 6        //deklarasi buzzer terhubung ke pin 6 Arduino
#define transistor 7 //deklarasi transistor terhubung ke pin 7 Arduino
//=======================================================================
void setup() {
  Serial.begin(9600);         //inisiasi komunikasi serial
  pinMode(Buz, OUTPUT);       //set pin 7 sebagai output digital
  pinMode(transistor, OUTPUT);//set pin 7 sebagai output digital
  digitalWrite(transistor,LOW);//blokir MISO dari SD-card
  //---------------------------------------------------------------------
  Wire.begin(); //mengaktifkan protokol Two Wire Interface (TWI) / I2C
  myRTC.setClockMode(false);  //set mode 24h pada RTC
  //---------------------------------------------------------------------
  SPI.begin();             //inisiasi SPI bus
  rfid1.PCD_Init();       //inisiasi objek rfid1 utk modul MFRC522 input 
  rfid2.PCD_Init();       //inisiasi objek rfid2 utk modul MFRC522 output
  //---------------------------------------------------------------------
  digitalWrite(transistor,HIGH);//buka MISO dari SD-card
  if (!SD.begin(4)) {     //inisialisasi library SD dg Chip Select (CS)=4 
    Serial.println("initialization failed!"); //jika SD.begin(4)=0 maka
    digitalWrite(transistor,LOW);//blokir MISO dari SD-card
    while (1);                   //berhenti
  }
  //---------------------------------------------------------------------
  Serial.println("initialization done."); //kartu SD-card dikenali
  digitalWrite(transistor, LOW);          //blokir MISO dari SD-card
  Serial.println(
    F("Dekatkan Kartu Anda ke Reader 'in' atau Reader 'out' "));
  Serial.println(""); //beri satu baris kosong
  Serial.println(F(" HARI   TANGGAL    JAM    TAP-MASUK  TAP-KELUAR"));
  Serial.println(F("-----------------------------------------------"));
}
//=======================================================================
void tulis_data() {
  tone(Buz, 400); delay(100); noTone(Buz);
  digitalWrite(transistor, HIGH);//buka hubungan MISO SD-card ke Arduino
  myFile = SD.open(fileName, FILE_WRITE); //jika belum, buat file & open
  namaHari.concat(" ");          //beri spasi kosong sebelum namaHari
  myFile.print(namaHari);        //simpan namaHari ke SD-card
  tanggal=myRTC.getDate(); tanggal.concat("-");//salin 'Date' ke tanggal
  tanggal.concat(myRTC.getMonth(CenturyBit)); tanggal.concat("-"); 
  tanggal.concat(myRTC.getYear()); tanggal.concat("|");
  myFile.print(tanggal);         //simpan data tanggal

  jam = myRTC.getHour(h12Flag, pmFlag); jam.concat(":");
  jam.concat(myRTC.getMinute()); jam.concat(":");
  jam.concat(myRTC.getSecond()); jam.concat("|");
  myFile.print(jam);             //simpan data jam ke SD-card
  
  myFile.println(dataKartu);     //tulis data kartu (uid)
  myFile.close();                //close file
  digitalWrite(transistor, LOW); //blokir MISO dari SD-card
}
//-----------------------------------------------------------------------
void time_Stamp() {
  int DoW;   //variabel lokal utk menyimpan pembacaan DoW dari RTC
  hour = myRTC.getHour(h12Flag, pmFlag); //baca angka jam dari RTC
  minute = myRTC.getMinute();            //baca angka menit dari RTC
  second = myRTC.getSecond();            //baca angka detik dari RTC
  DoW = myRTC.getDoW();         //baca angka kode nama hari dari RTC
  switch (DoW) {     //simpan data nama hari ke dalam var namaHari
    case 1: namaHari="Senin";  break;
    case 2: namaHari="Selasa"; break;
    case 3: namaHari="Rabu";   break;
    case 4: namaHari="Kamis";  break;
    case 5: namaHari="Jumat";  break;
    case 6: namaHari="Sabtu";  break;
    case 7: namaHari="Minggu"; break; }  
  //menyusun data dicetak ke Serial Monitor
  Serial.print(namaHari);  Serial.print("   ");
  Serial.print(myRTC.getDate()); Serial.print("-");
  Serial.print(myRTC.getMonth(CenturyBit)); Serial.print("-"); 
  Serial.print(myRTC.getYear()); Serial.print("  ");
  //menambahkan angka 0 jika angka jam, menit & detik < 2 digit
  if (hour<10)   { Serial.print("0"); } //jika <10 tambahkan 0 didepannya
  Serial.print(hour); Serial.print(":"); 
  if (minute<10) { Serial.print("0"); }
  Serial.print(minute); Serial.print(".");
  if (second<10) { Serial.print("0"); }
  Serial.print(second); Serial.print("  ");
}
//-----------------------------------------------------------------------
void reader_in() {
  if(!rfid1.PICC_IsNewCardPresent()) { //menunggu kartu didekatkan
    return;                            //keluar dari fungsi ini
  }
  if(!rfid1.PICC_ReadCardSerial()) {   //menunggu adanya data dari kartu
    return; //jika kartu tidak merespon, maka keluar dari fungsi ini
  }
  time_Stamp(); //menyusun & menampilkan data nama hari,tgl,bulan,tahun 
  for(int i=0;i<rfid1.uid.size;i++) {  //loop sebanyak ukuran UID
    //jika data <10 tambahkan 0 didepan
    Serial.print(rfid1.uid.uidByte[i]<0x10 ? "0" : ""); 
    Serial.print(rfid1.uid.uidByte[i],HEX); //menampilkan 4 Byte UID
    //jika data <10 tambahkan 0 didepan
    uid.concat(String(rfid1.uid.uidByte[i]<0x10 ? "0" : "")); 
    //susun UID dg langsung konversi ke String
    uid.concat(String(rfid1.uid.uidByte[i],HEX)); 
  }
  Serial.println("");     //kosongkan satu baris
  uid.toUpperCase();      //konversi UID ke huruf besar 
  dataKartu= uid + " -"; //utk reader-in, ada tanda ' -' disisi kanan uid
  uid="";                 //kosongkan variabel uid
  tulis_data();           //simpan data ke dalam SD-card
  rfid1.PICC_HaltA();     //halt PICC modul RFID-1  
}
//-----------------------------------------------------------------------
void reader_out() {
  if(!rfid2.PICC_IsNewCardPresent()) { //menunggu kartu didekatkan
    return; //jika kartu tidak dekat, maka keluar dari fungsi ini
  }
  if(!rfid2.PICC_ReadCardSerial()) {   //menunggu adanya data dari kartu
    return; //jika kartu tidak merespon, maka keluar dari fungsi ini
  }
  time_Stamp(); //menyusun & menampilkan data nama hari,tgl,bulan,tahun
  Serial.print("           ");         //beri spasi
  for(int i=0;i<rfid2.uid.size;i++) {  //loop sebanyak ukuran UID
    //jika data <10 tambahkan 0 didepan
    Serial.print(rfid2.uid.uidByte[i]<0x10 ? "0" : ""); 
    Serial.print(rfid2.uid.uidByte[i],HEX);   //menampilkan 4 Byte UID
    //jika data <10 tambahkan 0 didepan
    uid.concat(String(rfid2.uid.uidByte[i]<0x10 ? "0" : "")); 
    //susun UID dg langsung konversi ke String
    uid.concat(String(rfid2.uid.uidByte[i],HEX)); 
  }
  Serial.println("");     //kosongkan satu baris
  uid.toUpperCase();      //konversi UID ke huruf besar 
  dataKartu= "- " + uid; //utk reader-out, ada tanda '- ' disisi kiri uid
  uid="";                 //kosongkan uid
  tulis_data();           //simpan data ke dalam SD-card
  rfid2.PICC_HaltA();     //halt PICC modul RFID-2
}
//=======================================================================
void loop() {
  reader_in();  //baca modul Reader-1
  reader_out(); //baca modul Reader-2  
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5