Système de pointage numérique avec Arduino
Dans ce projet DIY, nous allons construire un système de pointage numérique. À l'aide d'une carte Arduino et de divers composants tels qu'un lecteur RFID, un écran OLED et un shield de journalisation avec RTC (horloge temps réel), nous pouvons enregistrer et stocker les heures d'arrivée et de départ des employés.
Composants utilisés
- Carte yourDroid UNO R3 ATMEGA328P-PU compatible Arduino
- Shield Datalogger pour Arduino avec RTC
- Kit RFID MFRC522 - Lecteur de cartes + transpondeur/ carte Mifare
- Écran OLED 1,3" I2C/IIC/TWI 128x64 pixels pour Arduino
- Buzzer actif 3,3V-5V
- Bouton poussoir rouge 12 mm 250V 1A
- Bouton poussoir vert 12 mm 250V 1A
- Câbles Dupont / Jumper 40 broches femelle-mâle 10 cm
- Un boîtier imprimé en 3D TIMETRACKERPQQMQh97MkH7l
- Une carte SD
Montage
Câblage
1. Arduino UNO R3 : Connectez la carte Arduino à votre ordinateur via un câble USB.
2. Datalogger Shield : Insérez le Datalogger Shield sur la carte Arduino.
3. Lecteur RFID :
- SDA -> Broche 7
- SCK -> Broche 13
- MOSI -> Broche 11
- MISO -> Broche 12
- IRQ -> Non connecté
- GND -> GND
- RST -> Broche 9
- 3.3V -> 3.3V
4. Écran OLED :
- VCC -> 5V
- GND -> GND
- SDA -> A4
- SCL -> A5
- VCC -> Broche 4
- GND -> GND
Boutons-poussoirs :
- Bouton rouge (partir) -> Broche 3 et GND
- Bouton vert (venir) -> Broche 2 et GND
Programmation
Chargez le code suivant sur votre carte Arduino : TIMETRACKER.ino
Afficher/masquer les codes
1. Code principal : Pointage RFID
#include "MFRC522.h"
#include "SPI.h"
#include "SdFat.h"
#include "RTClib.h"
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
// Nom du module RTC
RTC_DS3231 rtc;
// Adressage de l'écran OLED
#define I2C_ADDRESS 0x3C
// Définition des boutons
#define greenButton 2
#define redButton 3
// Connexions RFID définies
#define SDA 7
#define RST 9
// Nom de l'écran OLED
SSD1306AsciiWire oled;
// Désignation de la carte SD
SdFat SD;
// Désignation du fichier CSV
File Zeiterfassung;
// Récepteur RFID nommé et broches attribuées
MFRC522 mfrc522(SDA, RST);
// Broche de la carte SD
int DatenPin = 10;
// Broche du buzzer
int buzzer = 4;
// Valeur pour lire l'activité
int ButtonValue = 0;
// Variable pour suivre l'activité RFID
bool rfidGelesen = false;
// Séparateur pour le fichier CSV
const String TrennZeichen = ",";
String Mitarbeiter;
void setup() {
Serial.begin(9600);
SPI.begin();
// Démarrer l'OLED avec 128x64 pixels
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
// Définir la police
oled.setFont(Arial14);
oled.println(F(" venir partir"));
oled.println(F(" "));
oled.println(F(" Pour le pointage"));
oled.println(F(" Appuyez sur un bouton !"));
// Initialisation du récepteur RFID
mfrc522.PCD_Init();
// Déclarer les boutons comme entrées
pinMode(greenButton, INPUT_PULLUP);
pinMode(redButton, INPUT_PULLUP);
// Déclarer le buzzer comme sortie
pinMode(buzzer, OUTPUT);
// Démarrer le module RTC
if (!rtc.begin()) {
Serial.println(F("Initialisation du RTC échouée !"));
while (1);
} else if (rtc.lostPower()) {
// Régler l'heure uniquement si le RTC a perdu son heure
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println(F("Heure du RTC réglée sur l'heure de compilation !"));
} else {
Serial.println(F("RTC prêt et heure correcte !"));
}
// Démarrer la carte SD
if (!SD.begin(DatenPin)) {
Serial.println(F("Initialisation de la carte SD échouée !"));
} else {
Serial.println(F("Carte SD démarrée !"));
}
// rtc.now() -> obtenir l'heure actuelle
DateTime aktuell = rtc.now();
// Définir le format de la date
char Datum[] = "DD.MM.YYYY";
// Convertir la date en chaîne et l'afficher
Serial.print(aktuell.toString(Datum));
// Définir le format de l'heure
char Zeit[] = "hh:mm:ss";
// Convertir l'heure en chaîne et l'afficher
Serial.print(aktuell.toString(Zeit));
}
void loop() {
// Si le bouton vert est enfoncé
if (digitalRead(greenButton) == LOW) {
oled.clear();
oled.println(F(" venir"));
oled.println(F(" "));
oled.println(F(" Placez la carte"));
oled.println(F(" sur le lecteur !"));
ButtonValue = 1; // Définir ButtonValue sur 1
digitalWrite(buzzer, HIGH); // Son activé
delay(100);
digitalWrite(buzzer, LOW); // Son désactivé
delay(1000);
rfidGelesen = true; // Autoriser la lecture de la puce RFID
}
// Si le bouton rouge est enfoncé
if (digitalRead(redButton) == LOW) {
oled.clear();
oled.println(F(" partir"));
oled.println(F(" "));
oled.println(F(" Placez la carte"));
oled.println(F(" sur le lecteur !"));
ButtonValue = 2; // Définir ButtonValue sur 2
digitalWrite(buzzer, HIGH); // Son activé
delay(100);
digitalWrite(buzzer, LOW); // Son désactivé
delay(1000);
rfidGelesen = true; // Autoriser la lecture de la puce RFID
}
// Si la puce RFID n'a pas encore été lue et qu'un des boutons a été enfoncé
if (rfidGelesen == false) {
return; // Attendre l'appui sur un bouton
}
// Valeur de la carte déterminée par le RFID sous forme de suite de nombres décimaux
String WertDEZ;
// Effacer la chaîne Mitarbeiter pour reconnaître une mauvaise carte
Mitarbeiter = "";
// Si aucune carte n'est à portée
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Si aucun émetteur RFID n'a été sélectionné
if (!mfrc522.PICC_ReadCardSerial()) {
return;
}
Serial.println(F("Carte détectée !"));
digitalWrite(buzzer, HIGH); // Son activé
delay(100);
digitalWrite(buzzer, LOW); // Son désactivé
delay(1000);
// Écrire les valeurs décimales dans la chaîne WertDEZ
for (byte i = 0; i < mfrc522.uid.size; i++) {
WertDEZ = WertDEZ + String(mfrc522.uid.uidByte[i], DEC) + " ";
}
// Afficher la valeur décimale
Serial.println("Valeur en décimal : " + WertDEZ);
// Supprimer l'espace à la fin
WertDEZ.trim();
/*
Interroger les cartes et attribuer les noms des employés
*/
if (WertDEZ == "227 211 219 29") Mitarbeiter = " Max Mustermann";
if (WertDEZ == "147 50 48 28") Mitarbeiter = " Maxi Musterfrau";
// Interroger les noms
if (Mitarbeiter == " Max Mustermann" || Mitarbeiter == " Maxi Musterfrau") {
// Écrire les données dans le fichier
DatenSchreiben();
}
// En cas de mauvaise carte
else {
Serial.println(F("Mauvaise carte !"));
oled.clear();
oled.print(F(" Mauvaise carte !"));
delay(2000);
oled.clear();
oled.println(F(" venir partir"));
oled.println(F(" "));
oled.println(F(" Pour le pointage"));
oled.println(F(" Appuyez sur un bouton !"));
ButtonValue = 0;
rfidGelesen = false;
}
// Pause pour éviter d'écrire les données plusieurs fois
delay(2000);
}
void DatenSchreiben() {
// Messages dans le moniteur série
Serial.println(F("Écriture des données dans Zeiterfassung.csv ... "));
// Nom de l'employé
Serial.println("Employé : " + Mitarbeiter);
Serial.println(F("-----------------------------"));
// rtc.now() -> obtenir l'heure actuelle
DateTime aktuell = rtc.now();
char Datum[] = "DD.MM.YYYY ";
// Convertir la date en chaîne et l'afficher
Serial.print(aktuell.toString(Datum));
// Définir le format de l'heure
char Zeit[] = "hh:mm:ss";
// Convertir l'heure en chaîne et l'afficher
Serial.println(aktuell.toString(Zeit));
// Affichage OLED
oled.clear();
oled.println(Mitarbeiter);
oled.println(aktuell.toString(Datum));
oled.println(aktuell.toString(Zeit));
delay(2000);
oled.clear();
oled.print(F(" Enregistré !"));
delay(2000);
// Réinitialisation pour le prochain cycle
rfidGelesen = false;
/*
FILE_WRITE - Ouvrir le fichier en écriture
*/
Zeiterfassung = SD.open("Zeiterfassung.csv", FILE_WRITE);
if (Zeiterfassung) {
// Répéter l'en-tête après chaque jeu de données
Zeiterfassung.print(F("Employé :"));
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(F("Date :"));
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(F("Heure"));
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(F("Action"));
Zeiterfassung.println();
// Écrire les données dans le fichier
Zeiterfassung.print(Mitarbeiter);
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(Datum);
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(Zeit);
Zeiterfassung.print(TrennZeichen);
if (ButtonValue == 1) {
Zeiterfassung.print(F("venir"));
} else if (ButtonValue == 2) {
Zeiterfassung.print(F("partir"));
}
Zeiterfassung.println();
Zeiterfassung.println();
}
// Fermer le fichier
Zeiterfassung.close();
Serial.println(F("Enregistrement terminé."));
Serial.println();
delay(200);
// Réinitialisation pour le prochain cycle
ButtonValue = 0;
oled.clear();
oled.println(F(" venir partir"));
oled.println(F(" "));
oled.println(F(" Pour le pointage"));
oled.println(F(" Appuyez sur un bouton !"));
}
2. Configurer et tester le module RTC séparément
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(9600);
Wire.begin();
if (!rtc.begin()) {
Serial.println("Module RTC introuvable !");
while (1);
}
// Régler le RTC sur la date et l'heure de compilation
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println("RTC réglé avec succès sur la date et l'heure de compilation !");
}
void loop() {
// D'autres instructions peuvent être insérées ici
}