My RFID Time Clock Adventure with Arduino and FileMaker: Learning from My Mistakes

A few months ago, I decided to build a custom RFID time clock system using Arduino and FileMaker. It seemed like a fun and useful project. I thought it would be ready in just a few days. But like many DIY projects, things didn’t go as planned.

Here’s the story of what went wrong, what I learned, and how—with the help of ChatGPT—I finally got everything working.

Problem #1: The Metal Box

I started by placing everything into a solid, professional-looking metal box. It seemed like a good idea… until the RFID reader stopped working. I quickly discovered that the metal was blocking the RFID signal, so badges couldn’t be read at all.

Solution: I replaced it with a plastic box, and now the RFID reader works perfectly!

Problem #2: Messy Wiring

In the beginning, I connected all the wires quickly without proper connectors. Some wires were loose, and the system would randomly stop working.

Solution: I redid all the wiring using quality connectors and terminals. Now everything is clean, safe, and reliable.

Problem #3: The Display Struggles

I wanted to add a touchscreen display to show the current time and the last badge scans. But I ran into many problems: the screen was flickering, sometimes it didn’t turn on, and the touch function didn’t work properly.

The issues were caused by:

  • An unshielded cable
  • A cheap, unofficial power supply
  • And problems with the Arduino display libraries

Solution: With ChatGPT’s help, I:

  • Found and installed the correct display libraries
  • Replaced the cable with a shielded one
  • Switched to an official and reliable power supply

Now the display works beautifully!

How the System Works

Today, the system is almost complete. When a badge is scanned, Arduino sends the data via Wi-Fi to a small server I built. The server uses a REST API to send the data directly into FileMaker.

To make the system more reliable and clear, I decided to use two separate RFID antennas: one for entry and one for exit. This way, the system knows exactly what type of punch it is, without needing to alternate or guess.

I’m currently working on the FileMaker side of the software, where all the badge data will be stored, showing exactly who entered and who exited.

Also, I’m planning to add a second display, separate from the main one. This new screen will show a list of people who recently clocked in. I’m still exploring the best solution for this second screen, but I want something simple and easy to read—maybe placed at the entrance of the workshop.

What I Learned

This project wasn’t easy, and I made a lot of mistakes. But I also learned a lot:

  • Metal boxes and RFID don’t mix
  • Good wiring really matters
  • Official power supplies are worth it
  • Choosing the right Arduino libraries can take time
  • And… asking for help is okay! ChatGPT helped me solve many of the problems I couldn’t figure out on my own.

Now I’m really happy with how the system works, and I’m excited to finish the FileMaker part and add the second display.

Final Thoughts

If you’re thinking of starting a similar project, I hope my story helps you avoid some of these mistakes. Or at least reminds you that problems are part of the process—and learning from them is the most valuable part of all.

IMG 2756 Edited Scaled

Example Code for My RFID Time Clock with Arduino and FileMaker

In this article, I’ll share a simplified version of the code I used to create my RFID time clock system. It’s based on an Arduino Uno R4 WiFi, a MFRC522 RFID reader, and a LiquidCrystal I2C display. The system sends data via Wi-Fi to a PHP script, which then stores the information in FileMaker using the REST API.

🔌 Arduino Code

This code connects to Wi-Fi, gets the current time via NTP, reads the badge, shows the info on the display, and sends the data to a server using an HTTP GET request.

// Arduino sketch
#include <WiFiS3.h>
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
#include <WiFiUdp.h>
#include <NTPClient.h>

#define SS_PIN 10
#define RST_PIN 9
#define BUZZER_PIN 8
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27, 20, 4);

const char* ssid = "CNC_3";
const char* password = "WiFi@Rimec20160526";
const char* host = "192.168.1.61";
const char* endpoint = "/filemaker_rfid_entrata.php";
WiFiClient client;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 60000);

void setup() {
  Serial.begin(115200);
  lcd.begin();
  lcd.backlight();
  lcd.print("WiFi connecting...");

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  lcd.clear();
  lcd.print("WiFi ON");

  timeClient.begin();
  SPI.begin();
  mfrc522.PCD_Init();
  pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
  timeClient.update();
  String ora = timeClient.getFormattedTime();

  lcd.setCursor(0, 1);
  lcd.print("Reader ON ");
  lcd.setCursor(0, 2);
  lcd.print("Time: " + ora);

  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    delay(500);
    return;
  }

  String uid = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    uid += String(mfrc522.uid.uidByte[i], HEX);
  }

  lcd.setCursor(0, 3);
  lcd.print("Sending UID...");
  digitalWrite(BUZZER_PIN, HIGH);
  delay(100);
  digitalWrite(BUZZER_PIN, LOW);

  if (client.connect(host, 80)) {
    client.print(String("GET ") + endpoint + "?code=" + uid + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n\r\n");
    delay(1000);
    while (client.available()) {
      String line = client.readStringUntil('\n');
      Serial.println(line);
    }
    client.stop();
  }

  lcd.setCursor(0, 3);
  lcd.print("Data sent       ");
  delay(2000);
}
  

🌐 PHP Script (filemaker_rfid_entrata.php)

This PHP file receives the RFID UID via GET and sends it to FileMaker using the REST Data API.

<?php
$code = $_GET['code'] ?? '';

if ($code == '') {
    echo json_encode(['error' => 'No code provided']);
    exit;
}

$server = "http://localhost";
$database = "timbrature";
$user = "api_user";
$password = "secret";

$url = "$server/fmi/data/v1/databases/$database/layouts/Timbrature/records";

$data = [
    'fieldData' => [
        'Codice_Badge' => $code,
        'Timestamp' => date("Y-m-d H:i:s")
    ]
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_POST, true);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
  

📂 FileMaker Configuration

In FileMaker, I created a table named Timbrature with the following fields:

  • Codice_Badge (text)
  • Timestamp (date/time)

Additional logic, such as identifying the user or alternating between “entry” and “exit”, is managed in FileMaker scripts or calculated fields.

🛠 Final Notes

This is a simplified version of my real system. I’m still improving it—for example, I’m planning to add a second display to show the list of users who recently clocked in. Stay tuned!


Categories:

,

Tags:


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *