Zum Hauptinhalt springen Zur Suche springen Zur Hauptnavigation springen
Menü

Digitale Zeiterfassung mit Arduino


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 TIMETRACKERPQQMQh97MkH7l
  10. Eine SD Karte

Produktgalerie überspringen
UNO R3 ATMega328P CH340G UNO R3 Mega328P CH340G

Durchschnittliche Bewertung von 4.83 von 5 Sternen

(35)
UNO R3 ATMega328P CH340G
RBS10053

Sofort verfügbar

Regulärer Preis: 4,95 €
20
Data Logger Shield für Arduino mit RTC Data Logger Shield für Arduino mit RTC

Durchschnittliche Bewertung von 4.5 von 5 Sternen

(5)
Datalogger Shield für Arduino mit RTC
RBS10357

Sofort verfügbar

Verkaufspreis: Ab 2,36 € Regulärer Preis: 2,95 €
RFID Set MFRC522 - Kartenleser + Mifare Transponder/Karte RFID Set MFRC522 - Kartenleser + Mifare Transponder/Karte

Durchschnittliche Bewertung von 5 von 5 Sternen

(6)
RFID Set MFRC522 - Kartenleser + Mifare Transponder/Karte
RBS10027

Derzeit nicht verfügbar

Regulärer Preis: Ab 2,49 €
OLED Display I2C/IIC/TWI 128x64 Pixel für Arduino OLED Display I2C/IIC/TWI 128x64 Pixel für Arduino

Durchschnittliche Bewertung von 4.93 von 5 Sternen

(7)
1.3" OLED Display I2C/IIC/TWI 128x64 Pixel für Arduino
RBS11084

Sofort verfügbar

Regulärer Preis: Ab 6,85 €
10 Stück Aktiver Buzzer 3,3V-5V 10 Stück Aktiver Buzzer 3,3V-5V

Durchschnittliche Bewertung von 5 von 5 Sternen

(23)
10 Stück Aktiver Buzzer 3,3V-5V
RBS12914

Sofort verfügbar

Inhalt: 10 Stück (0,26 € / 1 Stück)

Regulärer Preis: Ab 2,55 €
Drucktaster Button Schalter Rot 12mm 250V 1A Drucktaster Button Schalter Rot 12mm 250V 1A

Durchschnittliche Bewertung von 4.75 von 5 Sternen

(6)
Drucktaster Button Schalter Rot 12mm 250V 1A
RBS13866

Sofort verfügbar

Regulärer Preis: Ab 0,65 €
Drucktaster Button Schalter Grün 12mm 250V 1A Drucktaster Button Schalter Grün 12mm 250V 1A

Durchschnittliche Bewertung von 5 von 5 Sternen

(1)
Drucktaster Button Schalter Grün 12mm 250V 1A
RBS13869

Sofort verfügbar

Regulärer Preis: Ab 0,65 €
Tipp
40 Pin Dupont / Jumper Kabel Buchse-Buchse 20 cm

Durchschnittliche Bewertung von 4.97 von 5 Sternen

(35)
40 Pin Dupont / Jumper Kabel Buchse-Buchse 20 cm
RBS10136

Sofort verfügbar

Regulärer Preis: Ab 0,69 €

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


Drucktaster:

  • Roter Taster (gehen) -> Pin 3 und GND
  • Grüner Taster (kommen) -> Pin 2 und GND

zum Vergrößern auf Bilder klicken

Programmierung

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

Code anzeigen / einklappen
#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!"));
}

#include #include
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}