Digitale Zeiterfassung mit Arduino

DIY-Projekt zur digitalen Zeiterfassung mit Arduino

Einleitung

In diesem DIY-Projekt werden wir ein digitales Zeiterfassungssystem bauen. Mit Hilfe eines Arduino-Boards und verschiedenen Komponenten wie einem RFID-Leser, einem OLED-Display und einem Datalogger-Shield mit RTC (Echtzeituhr) können wir die An- und Abwesenheitszeiten von Mitarbeitern erfassen und speichern.

Verwendete Bauteile

  1. yourDroid UNO R3 Entwicklungsboard ATMEGA328P-PU arduino kompatibel
  2. Datalogger Shield für Arduino mit RTC
  3. RFID Set MFRC522 - Kartenleser + Mifare Transponder/Karte
  4. 1.3" OLED Display I2C/IIC/TWI 128x64 Pixel für Arduino
  5. Aktiver Buzzer 3,3V-5V
  6. Drucktaster Button Schalter Rot 12mm 250V 1A
  7. Drucktaster Button Schalter Grün 12mm 250V 1A
  8. 40 Pin Dupont / Jumper Kabel Buchse-Stecker 10 cm
  9. Ein 3D-gedrucktes Gehäuse (die .stl-Datei wird bereitgestellt)
  10. Eine SD Karte

Aufbau

Verkabelung

  1. Arduino UNO R3: Verbinden Sie das Arduino-Board mit Ihrem Computer über ein USB-Kabel.
  2. Datalogger Shield: Stecken Sie das Datalogger Shield auf das Arduino-Board.
  3. RFID-Leser:
    • SDA -> Pin 7
    • SCK -> Pin 13
    • MOSI -> Pin 11
    • MISO -> Pin 12
    • IRQ -> Nicht verbunden
    • GND -> GND
    • RST -> Pin 9
    • 3.3V -> 3.3V
  4. OLED Display:
    • VCC -> 5V
    • GND -> GND
    • SDA -> A4
    • SCL -> A5
  5. Buzzer:
    • VCC -> Pin 4
    • GND -> GND
  6. Drucktaster:
    • Roter Taster (gehen) -> Pin 3 und GND
    • Grüner Taster (kommen) -> Pin 2 und GND

Gehäuse

Drucken Sie das Gehäuse mit einem 3D-Drucker. Die .stl-Datei können Sie hier herunterladen: TIMETRACKERPQQMQh97MkH7l

Programmierung

Laden Sie den folgenden Code auf Ihr Arduino-Board: TIMETRACKER.ino

/#include "MFRC522.h"

#include "SPI.h"

#include "SdFat.h"

#include "RTClib.h"

#include "SSD1306Ascii.h"

#include "SSD1306AsciiWire.h"

 

// Name des RTC-Moduls

RTC_DS3231 rtc;

 

// Adressierung des OLED-Displays

#define I2C_ADDRESS 0x3C

 

// Buttons definieren

#define greenButton 2

#define redButton 3

 

// RFID Anschlüsse definieren

#define SDA 7

#define RST 9

 

// Name des OLED-Displays

SSD1306AsciiWire oled;

 

// Bezeichnung der SD-Karte

SdFat SD;

 

// Bezeichnung der CSV-Datei

File Zeiterfassung;

 

// RFID-Empfänger benennen und Pins zuordnen

MFRC522 mfrc522(SDA, RST);

 

// Pin der SD-Karte

int DatenPin = 10;

 

// Pin des Buzzer

int buzzer = 4;

 

// Wert zum Auslesen der Aktivität

int ButtonValue = 0;

 

// Variable zum Verfolgen der RFID-Aktivität

bool rfidGelesen = false;

 

// Trennzeichen für die CSV-Datei

const String TrennZeichen = ",";

 

String Mitarbeiter;

 

void setup() {

    Serial.begin(9600);

    SPI.begin();

 

    // OLED mit 128x64 Pixeln starten

    Wire.begin();

    oled.begin(&Adafruit128x64, I2C_ADDRESS);

 

    // Schriftart festlegen

    oled.setFont(Arial14);

    oled.println(F(" kommen gehen"));

    oled.println(F(" "));

    oled.println(F(" Zur Zeiterfassung"));

    oled.println(F(" Taste druecken!"));

 

    // Initialisierung des RFID-Empfängers

    mfrc522.PCD_Init();

 

    // Buttons als Input deklarieren

    pinMode(greenButton, INPUT_PULLUP);

    pinMode(redButton, INPUT_PULLUP);

 

    // Buzzer als Output deklarieren

    pinMode(buzzer, OUTPUT);

 

    // RTC-Modul starten

    if (!rtc.begin()) {

        Serial.println(F("RTC Initialisierung fehlgeschlagen!"));

    } else if (rtc.lostPower()) {

        // Setze die Uhrzeit nur, wenn die RTC ihre Zeit verloren hat

        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

        Serial.println(F("RTC Uhrzeit eingestellt!"));

    } else {

        Serial.println(F("RTC bereit und Uhrzeit korrekt!"));

    }

 

    // SD-Karte starten

    if (!SD.begin(DatenPin)) {

        Serial.println(F("Initialisierung fehlgeschlagen!"));

    } else {

        Serial.println(F("SD-Karte gestartet!"));

    }

 

    // rtc.now() -> aktuelle Zeit holen

    DateTime aktuell = rtc.now();

 

    // Format des Datums festlegen

    char Datum[] = "DD.MM.YYYY";

 

    // Datum in String umwandeln und anzeigen

    Serial.print(aktuell.toString(Datum));

 

    // Format der Zeitangabe festlegen

    char Zeit[] = "hh:mm:ss";

 

    // Zeitangabe in String umwandeln und anzeigen

    Serial.print(aktuell.toString(Zeit));

}

 

void loop() {

    // Wenn grüner Button gedrückt wird

    if (digitalRead(greenButton) == LOW) {

        oled.clear();

        oled.println(F(" kommen"));

        oled.println(F(" "));

        oled.println(F(" Karte an das"));

        oled.println(F(" Lesegeraet halten!"));

        ButtonValue = 1; // Setze ButtonValue auf 1

        digitalWrite(buzzer, HIGH); // Ton an

        delay(100);

        digitalWrite(buzzer, LOW); // Ton aus

        delay(1000);

        rfidGelesen = true; // Erlaube das Lesen des RFID-Chips

    }

 

    // Wenn roter Button gedrückt wird

    if (digitalRead(redButton) == LOW) {

        oled.clear();

        oled.println(F(" gehen"));

        oled.println(F(" "));

        oled.println(F(" Karte an das"));

        oled.println(F(" Lesegeraet halten!"));

        ButtonValue = 2; // Setze ButtonValue auf 2

        digitalWrite(buzzer, HIGH); // Ton an

        delay(100);

        digitalWrite(buzzer, LOW); // Ton aus

        delay(1000);

        rfidGelesen = true; // Erlaube das Lesen des RFID-Chips

    }

 

    // Wenn RFID-Chip noch nicht gelesen wurde und einer der Buttons gedrückt wurde

    if (rfidGelesen == false) {

        return; // Warte auf Button-Druck

    }

 

    // vom RFID ermittelter Wert der Karte als Folge von Dezimalzahlen

    String WertDEZ;

 

    // String Mitarbeiter löschen, damit falsche Karte erkannt wird

    Mitarbeiter = "";

 

    // Wenn keine Karte in Reichweite ist

    if (!mfrc522.PICC_IsNewCardPresent()) {

        // wird die Abfrage wiederholt.

        return;

    }

 

    // Wenn kein RFID-Sender ausgewählt wurde

    if (!mfrc522.PICC_ReadCardSerial()) {

        // wird die Abfrage wiederholt.

        return;

    }

    Serial.println(F("Karte entdeckt!"));

    digitalWrite(buzzer, HIGH); // Ton an

    delay(100);

    digitalWrite(buzzer, LOW); // Ton aus

    delay(1000);

    // Dezimal-Werte in String WertDEZ schreiben

    for (byte i = 0; i < mfrc522.uid.size; i++) {

        WertDEZ = WertDEZ + String(mfrc522.uid.uidByte[i], DEC) + " ";

    }

 

    // dezimalen Wert anzeigen

    Serial.println("Wert in dezimal: " + WertDEZ);

 

    // Leerzeichen am Ende entfernen

    WertDEZ.trim();

 

    /*

    Karten abfragen und Namen der Mitarbeiter*innen zuordnen

    Dezimal-Werte durch Namen

    */

    if (WertDEZ == "227 211 219 29") Mitarbeiter = " Max Mustermann";

    if (WertDEZ == "147 50 48 28") Mitarbeiter = " Maxi Musterfrau";

 

    // Namen abfragen

    if (Mitarbeiter == " Max Mustermann" || Mitarbeiter == " Maxi Musterfrau") {

        // Daten in die Datei schreiben

        DatenSchreiben();

    }

 

    // bei falscher Karte

    else {

        Serial.println(F("Falsche Karte!"));

        oled.clear();

        oled.print(F(" Falsche Karte!"));

        delay(2000);

        oled.clear();

        oled.println(F(" kommen gehen"));

        oled.println(F(" "));

        oled.println(F(" Zur Zeiterfassung"));

        oled.println(F(" Taste druecken!"));

        ButtonValue = 0;

        rfidGelesen = false;

    }

 

    // Pause, damit die Daten nicht mehrfach geschrieben werden

    delay(2000);

}

 

void DatenSchreiben() {

    // Meldungen im Seriellen Monitor

    Serial.println(F("Schreibe Daten in Zeiterfassung.csv ... "));

 

    // Name der Mitarbeiter*in

    Serial.println("Mitarbeiter*in: " + Mitarbeiter);

    Serial.println(F("-----------------------------"));

 

    // rtc.now() -> aktuelle Zeit holen

    DateTime aktuell = rtc.now();

    char Datum[] = "DD.MM.YYYY ";

 

    // Datum in String umwandeln und anzeigen

    Serial.print(aktuell.toString(Datum));

 

    // Format der Zeitangabe festlegen

    char Zeit[] = "hh:mm:ss";

 

    // Zeitangabe in String umwandeln und anzeigen

    Serial.println(aktuell.toString(Zeit));

 

    // Ausgabe OLED

    oled.clear();

    oled.println(Mitarbeiter);

    oled.println(aktuell.toString(Datum));

    oled.println(aktuell.toString(Zeit));

    delay(2000);

    oled.clear();

    oled.print(F(" Gespeichert!"));

    delay(2000);

 

    // Reset für den nächsten Durchlauf

    rfidGelesen = false;

 

    /*

    FILE_WRITE - Datei zum Schreiben öffnen

    wenn die Datei noch nicht existiert, wird sie neu erstellt

    ansonsten werden neuen Daten ans Ende angehängt

    */

    Zeiterfassung = SD.open("Zeiterfassung.csv", FILE_WRITE);

    if (Zeiterfassung) {

        // Überschrift nach jedem Datensatz wiederholen

        Zeiterfassung.print(F("Mitarbeiter*in:"));

        Zeiterfassung.print(TrennZeichen);

        Zeiterfassung.print(F("Datum:"));

        Zeiterfassung.print(TrennZeichen);

        Zeiterfassung.print(F("Zeit"));

        Zeiterfassung.print(TrennZeichen);

        Zeiterfassung.print(F("Aktion"));

        Zeiterfassung.println();

 

        // Daten in die Datei schreiben: Mitarbeiter*in, Datum, Zeit und Aktion

        // Werte durch Trennzeichen (,) trennen

        Zeiterfassung.print(Mitarbeiter);

        Zeiterfassung.print(TrennZeichen);

        Zeiterfassung.print(Datum);

        Zeiterfassung.print(TrennZeichen);

        Zeiterfassung.print(Zeit);

        Zeiterfassung.print(TrennZeichen);

        if (ButtonValue == 1) {

            Zeiterfassung.print(F("kommen"));

        } else if (ButtonValue == 2) {

            Zeiterfassung.print(F("gehen"));

        }

        Zeiterfassung.println();

        Zeiterfassung.println();

    }

 

    // Datei schließen

    Zeiterfassung.close();

    Serial.println(F("Speichern abgeschlossen."));

    Serial.println();

    delay(200);

    // Reset für den nächsten Durchlauf

    ButtonValue = 0;

    oled.clear();

    oled.println(F(" kommen gehen"));

    oled.println(F(" "));

    oled.println(F(" Zur Zeiterfassung"));

    oled.println(F(" Taste druecken!"));

}

 

Anleitungsvideo mit Funktion

#include <Wire.h>#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {  Serial.begin(9600);  Wire.begin();    if (!rtc.begin()) {    Serial.println("RTC konnte nicht gefunden werden!");    while (1);  }
  // RTC auf das Kompilierdatum und -zeit einstellen  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));  Serial.println("RTC erfolgreich auf das Kompilierdatum und -zeit eingestellt!");}
void loop() {  // Hier können weitere Anweisungen eingefügt werden}

 

Schlagworte: DIY, Zeiterfassung, Arduino

Die mit einem * markierten Felder sind Pflichtfelder.