Stechuhr aufbauen

Hallo zusammen,

ich würde mir gerne für das Homeoffice eine Stechuhr bauen.

Dafür habe ich mir folgenden Aufbau überlegt:
Wemos D1 R1 Board + SD Card Shield + RC522 Kartenleser + LCD Display (2x16)

Habe aktuell das Problem, dass wenn ich SD Shield und auch den RC522 nutzen möchte das RC522 keine Karte erkennt. Einzeln funktionieren beide. Ich denke das die SPI Schnittstelle irgendwelche Probleme verursacht da ja der RC522 und das SD Shield drüber kommunizieren. Hatte in der Google Suche schon gelesen das einige es mit einem 330Ohm Widerstand zwischen Uno MISO und SD MISO versucht haben. Hat bei mir nichts gebracht. Kann mir jemand helfen wie ich das Problem gelöst bekomme?

Anbei noch mein Code:

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>

// define pins for RFID
#define CS_RFID 15//10
#define RST_RFID 2//9
// define select pin for SD card module
#define CS_SD 0 //8

// Create a file to store the data
File myFile;

// Instance of the class for RFID
MFRC522 rfid(CS_RFID, RST_RFID); 

// Variable to hold the tag's UID
String uidString;

// LCD-Display Konfiguration
// Standard LCD-Adresse ist 0x27 - 16 zeichen - 2 Zeilen 
LiquidCrystal_I2C lcd(0x27,16,2);


const char *ssid     = "xxxxxxxxx";
const char *password = "xxxxxxx";

//Zeitverschiebung UTC <-> MEZ (Winterzeit) = 3600 Sekunden (1 Stunde)
//Zeitverschiebung UTC <-> MEZ (Sommerzeit) = 7200 Sekunden (2 Stunden)
const long utcOffsetInSeconds = 7200;
char daysOfTheWeek[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};

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

void setup(){
  Serial.begin(9600);
  SPI.begin();         // Initialisiere SPI Kommunikation
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Ich verbinde mich mit dem Internet...");
  }  
  Serial.println("Ich bin mit dem Internet verbunden!");


  timeClient.begin();

  // LCD-Display initialisieren
  lcd.init();

  // Schlatet die Hintergrundbeleuchtung des LCD-Displays an
  lcd.backlight();

  // würde die Hintergrundbeleuchtung ausschalten
  // lcd.noBacklight();
  // SD-Karte initialisieren
  Serial.print("\r\nInitialisiere SD-Karte...");
  if (!SD.begin(CS_SD)) {
    Serial.println(" fehlgeschlagen!");
    // Setup-Funktion verlassen
    return;
  }

  rfid.PCD_Init();  // Initialisiere MFRC522 Lesemodul
  // Details vom MFRC522 RFID READER / WRITER ausgeben
  //mfrc522.PCD_DumpVersionToSerial();  
  Serial.println(" fertig.");
}

void loop() {
  if(rfid.PICC_IsNewCardPresent()) {
    Serial.print("Karte erkannt");
    readRFID();
    logCard();
  }
  timeClient.update();
  lcd.setCursor(0,0);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(timeClient.getFormattedDate());
  //lcd.print(daysOfTheWeek[timeClient.getDay()]);
  lcd.setCursor(0,1);
  lcd.print(timeClient.getFormattedTime());
  delay (1000);
}


void readRFID(){
  rfid.PICC_ReadCardSerial();
  Serial.print("Tag UID: ");
  uidString = String(rfid.uid.uidByte[0]) + " " + String(rfid.uid.uidByte[1]) + " " + 
  String(rfid.uid.uidByte[2]) + " " + String(rfid.uid.uidByte[3]);
  Serial.println(uidString);

  delay (100);
}

void logCard(){
  digitalWrite(CS_SD,LOW);
  
  timeClient.update();

  Serial.print(daysOfTheWeek[timeClient.getDay()]);
  Serial.print(", ");
  Serial.println(timeClient.getFormattedTime());


  lcd.setCursor(0,0);
  lcd.clear();
  lcd.setCursor(0,0);
  //lcd.print("");
  lcd.print(timeClient.getFormattedDate());
  //lcd.print(daysOfTheWeek[timeClient.getDay()]);
  lcd.setCursor(0,1);
  //lcd.clear();
  //lcd.print("");
  lcd.print(timeClient.getFormattedTime());
  
  // Open file
  myFile=SD.open("DATA.txt", FILE_WRITE);

    //Wenn das File existiert dann....
  if (myFile) {
     lcd.setCursor(0,0);
     lcd.clear();
     myFile.println(daysOfTheWeek[timeClient.getDay()]);
     myFile.print(",");
     myFile.print(timeClient.getFormattedTime());
     myFile.print(",");
     myFile.print("uidString");
     myFile.close();
     lcd.print("beschrieben");
     }
     else {
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.println("SD Fehler");
     }  
}

Irgendwas stimmt doch hier mit den Pins nicht, oder?
Und schreibe mal besser

const byte CS_RFID {15};  //10
const byte RST_RFID {2}   //9
// select pin for SD card module
const byte CS_SD {0};      //8

Pin 0 und 1 niemals verwenden. Dort hängt die Serial dran.

Beim Wemos D1 R1 Board?

Hallo,

ups, das habe ich überlesen. Dann muss er nochmal seinen Einzelsketch mit dem kompletten vergleichen was da anders ist.

Hallo,
wie gesagt einzeln funktionieren beide Module, daher ist die PIN Belegung richtig. Sobald ich aber beide zusammenschalte, bekomme ich eine Warnung das der RF522 vielleicht nicht richtig verbunden ist. Daher denke ich das sich die SD Karte und der RFID Reader gegenseitig stören.

Hallo,

ich glaube ich habs.

if (!SD.begin(CS_SD)) {
    Serial.println(" fehlgeschlagen!");
    return;
  }

Wo kommt denn das return her? Die SD Initialisierung muss an der Stelle warten und nicht einfach wohin springen bis das okay kommt. Ersetze return durch while(1) bzw. schau dir nochmal die SD Bsp. der IDE an.

Vermutlich nur mit einem Oszi.
Da solltest du mal die Signalleitungen messen.

Und die von dir verwendeten Pins 0 und 15 sind mit Vorsicht zu verwenden.
Siehe Dazu diese Seite.

Und mich würde interessieren, wie du dein Display angeschlossen hast.
Vermute mal das funktioniert nicht oder ist schon etwas defekt ?

Auch stellt sich mir die Frage, wozu du einen SDCardreader benötigst. Der Wemos hat doch Spiffs oder LittleFS, da kannst du alles reinschreiben und per Web auslesen.
Dann sparst du den CardReader und hast ein Problem weniger.

darf ich einfach mal sagen das das alles Pfusch ist?
SD Karte am ESP8266 wo es doch ein LittleFS gäbe,
eine externe Lib für NTP wobei der ESP8266 Core NTP inklusive Sommerzeit mit 3 Zeilen Code kann
Den Loop 1 Sekunde aufhalten, damit man das Display nicht überfordert wird...

Ernsthaft, möchtest nicht gemeinsam was sauberes machen?

Hallo,

ich gerne für alles offen. Wusste nicht das der ESP auch NTP Funktion hat.
Loop auf 1s, war damit ich die Uhrzeit mit der Sekundenanzeige snychron habe.
Das Display ist nicht überfordert und funktioniert einwandfrei.

Was wäre denn dein Vorschlag an Verbesserungen?

Der ESP8266 ist Hardware, NTP wird per Software erreicht.
Wenn du die originalen Treiber der core verwendest, ist alles dabei, auch die Unterstützung des NTP.
Du solltest einfach mal die vorhandenen Beispiele ansehen und studieren. Hier hat es noiasca schon richtig auf den Punkt gebracht.
Auch auf die delay() solltest du verzichten.

Warum beantwortest du nicht alle gestellten Fragen ?

Hallo, ich konnte noch nicht alle Fragen beantworten da ich dafür ein wenig mehr Zeit benötige und mir das auch anschauen muss, wenn z.B. Links verlinkt sind. Ich melde mich später mit alles antworten. Ob es Pfusch ist weiß ich nicht. Die SD Karte kam dadurch ins Spiel das ich diese einfach an meinen PC anschließen kann ins Excel importiere und dann auf der Arbeit den Stundennachweis einreichen kann. Das war für mich auf den 1. Blick eine einfache und dankbare Lösung. Das Display dient mir dafür um noch weitere Informationen anzuzeigen. Ich habe im Hintergrund IOBroker laufen und würde dann später gerne weitere Informationen anzeigen die für mich aus dem Smarthome relevant wären. Das mit der SD Initialisierung scheint wohl Falsch im Code zu sein. Werde mir das nochmal anschauen. Mit Pin 0 und 15 ist ein gute Punkt. Da lese ich gerade den Link durch ob ich ggf. den Pin wechseln muss. Display ist nicht defekt. Anschluss ist Adapter so das ich nur 4 Kontakte habe (VCC, GND,SDA (D4), SCL (D3). Bzgl. NTP und ESP8266 muss ich erst verstehen wie ich das abändern kann. Wie gesagt bin für alles offen und versuche auch alles zu verstehen. Daher vielen Dank für die Anregungen.

Ok, dann noch der Hinweis auf die Seite von Fips. Da findest du sehr viel nützliche Infos.
Zum Display:
Dein ESP arbeitet mit 3,3V, dein Display mit 5V. Das verträgt sich nicht. Damit kannst du deinen ESP schnell zerstören. Für I2C brauchst du einen Levelshifter.

Und wenn du mit LittleFS im ESP arbeitest, kannst du auch Exceldateien (CSV) erstellen und diese per Web auf deinen PC übertragen. Du brauchst keine SDCard.

Ok schaue ich mir an bzgl LittleFS, ja ich benötige unterschiedliche Spannungen aber das ESP D1 Board liefert 3,3V und 5V. Somit liegen mir beide Spannungen vor.

Das hilft dir nicht.
Die meisten LCD arbeiten nicht mit 3,3V, bzw. funktionieren die nicht richtig, da die Anzeige (Kontrast) nicht mehr deutlich ist. Und bei 5V hast du das oben beschriebene Problem.

Du verwechselst Betriebsspannung mit Signalspannung.
Der ESP8266 ist lt. Datenblatt nicht 5V trolerant.
Manche behauten das Gegenteil, das entspricht aber nicht dem Datenblatt.

Gruß Tommy

wegen NTP:
ich hab das mal hier beschrieben:
https://werner.rothschopf.net/201802_arduino_esp8266_ntp.htm

das sind am ESP eigentlich nur 4 Zeilen Code:

// global:
#define MY_NTP_SERVER "at.pool.ntp.org"           
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"   

#include <time.h>                   // time() ctime()

// im setup()
configTime(MY_TZ, MY_NTP_SERVER);

probier mal das verlinkte Beispiel.
wenn du das mal ausprobierst und sagst - ja geht, dann können wir weitermachen.

Kannst du deinen ESP im Internet zugänglich machen/Portweiterleitung oder VPN und von der Firma aus abfragen? Weil dann macht LittleFS am ESP (nicht SD Karte) einen Sinn.
Wenn du die Daten nur mittels Datenträger in die Firma bekommst, dann natürlich nicht so sehr.

Kürzlich hat mal eine Schaltung von mir gesponnen, nachdem ich ein LC-Display zusätzlich angeschlossen hatte. Das lag am Stronverbrauch der Hintergrundbeleuchtung. Du brauchst also nicht nur die Spannungen, sondern auch den notwendigen Strom.

Da ich weder Wemos D1 R1 Board noch RC522 Kartenleser habe, kann ich es nicht einschätzen, aber eine Störquelle könnte es sein.

Abhilfe können Kondensatoren schaffen oder ein ordentliches Netzteil.

Hallo, habe das mit der Zeit über den ESP8266 probiert wie im Artikel beschrieben. Das funktioniert.

/* Configuration of NTP */
#define MY_NTP_SERVER "0.europe.pool.ntp.org"           
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"   

/* Necessary Includes */
#include <ESP8266WiFi.h>            // we need wifi to get internet access
#include <time.h>                   // time() ctime()


/* Globals */
time_t now;                         // this is the epoch
tm tm;                              // the structure tm holds time information in a more convient way

const char *ssid     = "XXX";
const char *password = "XXX";
char daysOfTheWeek[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};


void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &tm);           // update the structure tm with the current time

  Serial.println(String(daysOfTheWeek[tm.tm_wday]) + ": " + String(tm.tm_mday) + "." + String(tm.tm_mon + 1) + "." + String(tm.tm_year + 1900) + " " + tm.tm_hour + ":" + tm.tm_min + ":" + tm.tm_sec);
}

void setup() {
  Serial.begin(115200);
  Serial.println("\nNTP TZ DST - bare minimum");

  configTime(MY_TZ, MY_NTP_SERVER); // --> Here is the IMPORTANT ONE LINER needed in your sketch!

  // start network
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Ich verbinde mich mit dem Internet...");
  }  
  Serial.println("Ich bin mit dem Internet verbunden!");
}

void loop() {
  showTime();
  delay(1000); // dirty delay
}

Ich habe als NTP-Server den ausgewählt, dass der ESP später diesen über die Fritzbox bekommt und der ESP somit nicht ins Internet direkt eingebunden werden muss.

Zu den weiteren Fragen: Ich möchte den ESP nicht im Internet zugänglich machen. Die Stundendokumentation dient vorläufig erstmal mir, aber der Vorgesetzte kann sie anfordern. Daher wäre meine Überlegung ob das File nicht auf einen NAS oder auf die Fritzbox NAS gespeichert werden könnte. Dann benötige ich die SD Karte nicht.

Bzgl dem Anschluss des LCD Displays habt ihr mich abgehängt. Das WEMOS D1 Board bietet beide Spannungen an. Sprich VCC 5V vom Board, SDA und SDL werden ja vom ESP gesteuert. (somit maximale 3,3V). Verstehe aktuell nicht wo das Problem liegen soll? Könnt ihr mir das nochmal erklären?

Das wurde doch schon beschrieben, aber gerne noch mal.
Dein LCD betreibst du mit 5Volt, somit sind auf dem I2C-Bus vom LCD die 5Volt. Die schließt du am Wemos an, der auf den Pins nur 3,3V verträgt. Da gibt es einen Konflikt, der deinen Wemos zerstören kann/wird. Dazu brauchst du zwingend einen Levelshifter, wenn du an deinem Projekt länger Freude haben möchtest.

Zu der Frage, wo die Datei aus dem LittleFS gespeichert werden kann, die Info, das kannst du beim Speichern (download) selbst festlegen. Das geht dann irgendwo auf deinem PC oder angeschlossene Speichermedien.

Ok nun hab ich verstanden. Hatte die Seite vom LCD nicht betrachtet.