Pn532 + RTC gleichzeitig an i2c anschließen (TCA9548A)

Hey, ich habe wieder Mal Probleme mit der Programmierung. Ich habe nicht viel Ahnung und mache viel mit ChatGPT. Ich nutze aktuell einen Arduino Mini Pro 5V. Ich habe ein Programm was funktioniert hat, um mit dem PN532 Text auf einem NFC Sticker auszulesen und mit Textdatein mit dem selben Namen/ Zahl auf der SD Karte aufzurufen. Dort sind Zahlen für ein Delay einer LED gespeichert. Der PN532 ist per i2c angeschlossen, das funktioniert super.

#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
#include <SPI.h>
#include <SD.h>

PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);

const int ledPin = 2; // Pin für die LED
const int chipSelect = 10; // CS-Pin des SD-Kartenmoduls

void setup() {
  Serial.begin(9600);
  Serial.println("System initialized");
  
  // Initialisiere SD-Karte
  if (!SD.begin(chipSelect)) {
    Serial.println("SD-Karte konnte nicht initialisiert werden.");
    return;
  }
  Serial.println("SD-Karte initialisiert.");
  
  nfc.begin();
  pinMode(ledPin, OUTPUT); // Den Pin als Ausgang für die LED konfigurieren
}

void loop() {
  readNFC();
}

void readNFC() {
  if (nfc.tagPresent()) {
    NfcTag tag = nfc.read();
    Serial.println("NFC Tag detected");
    
    NdefMessage message = tag.getNdefMessage();
    NdefRecord firstRecord = message.getRecord(0);
    
    byte payload[11]; // Maximale Länge der Nutzlast ist 11 Bytes
    firstRecord.getPayload(payload);
    
    String payloadText = "";
    for (int i = 0; i < 11; i++) {
      payloadText += (char)payload[i];
    }
    
    String numberPayload = "";
    for (int i = 0; i < payloadText.length(); i++) {
      if (isdigit(payloadText.charAt(i))) {
        numberPayload += payloadText.charAt(i);
      }
    }
    
    // Die Zahl in einen Integer konvertieren
    int number = numberPayload.toInt();
    
    Serial.print("Number from NFC Tag: ");
    Serial.println(number);
    
    // Speichern der Zahl in einer Datei auf der SD-Karte
    String filename = String(number) + ".txt";
    File dataFile = SD.open(filename);
    if (dataFile) {
      String delayStr = dataFile.readStringUntil('\n');
      int delayValue = delayStr.toInt();
      dataFile.close();
      
      Serial.print("Delay from file: ");
      Serial.println(delayValue);
      
      // Verarbeitung der Zahl, z.B. für das Delay
      digitalWrite(ledPin, HIGH); // Die LED einschalten
      delay(delayValue); // Hier wird das Delay verwendet
      digitalWrite(ledPin, LOW); // Die LED ausschalten
    } else {
      Serial.println("Fehler beim Öffnen der Datei: " + filename);
    }
  }
  delay(2000);
}

Jetzt möchte ich noch eine RTC anschlißen, dies geht ja nur über i2c. Gleichzeitig hat es nicht funktioniert, da wird dann eines von beiden blockiert. Ich bin auf die Lösung eines TCA9548A gekommen, bekomme die Programmierung nicht hin.

Kann mir jemand das umschreiben, hier ist noch ein funktionierender Code für die RTC:

#include <Wire.h>
#include <RTClib.h>
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>

RTC_DS3231 rtc;
PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);
String tagId = "None";
byte nuidPICC[4];

void setup() {
  Serial.begin(9600);

  if (!rtc.begin()) {
    Serial.println("RTC konnte nicht gefunden werden!");
    while (1);
  }

  nfc.begin();
}

void loop() {
  readNFC();
}

void readNFC() {
  if (nfc.tagPresent()) {
    NfcTag tag = nfc.read();
    tag.print();
    tagId = tag.getUidString();
    printTime(); // Anzeige der Zeit nur wenn ein NFC-Sticker erkannt wird
    delay(2000); // Kurze Verzögerung, um Mehrfacherkennung zu vermeiden
  }
}

void printTime() {
  DateTime now = rtc.now();
  
  Serial.print("Tag ID: ");
  Serial.println(tagId);

  Serial.print(now.year());
  Serial.print('-');
  Serial.print(now.month());
  Serial.print('-');
  Serial.print(now.day());
  Serial.print(' ');
  Serial.print(now.hour());
  Serial.print(':');
  Serial.print(now.minute());
  Serial.print(':');
  Serial.print(now.second());
  Serial.println();
}

Einfach ChatGPT fragen bis das Programm arbeitet und der Schaltplan da ist.

1 Like

Ja da hängt es gerade, deswegen brauche ich hier Hilfe. der PN532 ist an bus 0 angeschlossen die RTC an Bus 1.

Das ist der Code bis jetzt:

#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
#include <Wire.h>
#include <SD.h>
#include <RTClib.h>

PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);

const int ledPin = 2; // Pin für die LED
const int chipSelect = 10; // CS-Pin des SD-Kartenmoduls

RTC_DS3231 rtc;

void setup() {
  Serial.begin(9600);
  Serial.println("System initialized");
  
  // Initialisiere SD-Karte
  if (!SD.begin(chipSelect)) {
    Serial.println("SD-Karte konnte nicht initialisiert werden.");
    return;
  }
  Serial.println("SD-Karte initialisiert.");
  
  nfc.begin();
  pinMode(ledPin, OUTPUT); // Den Pin als Ausgang für die LED konfigurieren
  
  if (!rtc.begin()) {
    Serial.println("Konnte RTC nicht finden!");
    while (1);
  }
}

void loop() {
  readNFC();
}

void readNFC() {
  tcaselect(0); // Wähle Port 0 für PN532
  if (nfc.tagPresent()) {
    NfcTag tag = nfc.read();
    Serial.println("NFC Tag detected");
    
    NdefMessage message = tag.getNdefMessage();
    NdefRecord firstRecord = message.getRecord(0);
    
    byte payload[11]; // Maximale Länge der Nutzlast ist 11 Bytes
    firstRecord.getPayload(payload);
    
    String payloadText = "";
    for (int i = 0; i < 11; i++) {
      payloadText += (char)payload[i];
    }
    
    String numberPayload = "";
    for (int i = 0; i < payloadText.length(); i++) {
      if (isdigit(payloadText.charAt(i))) {
        numberPayload += payloadText.charAt(i);
      }
    }
    
    // Die Zahl in einen Integer konvertieren
    int number = numberPayload.toInt();
    
    Serial.print("Number from NFC Tag: ");
    Serial.println(number);
    
    // Speichern der Zahl in einer Datei auf der SD-Karte
    String filename = String(number) + ".txt";
    File dataFile = SD.open(filename);
    if (dataFile) {
      String delayStr = dataFile.readStringUntil('\n');
      int delayValue = delayStr.toInt();
      dataFile.close();
      
      Serial.print("Delay from file: ");
      Serial.println(delayValue);
      
      // Verarbeitung der Zahl, z.B. für das Delay
      digitalWrite(ledPin, HIGH); // Die LED einschalten
      delay(delayValue); // Hier wird das Delay verwendet
      digitalWrite(ledPin, LOW); // Die LED ausschalten
    } else {
      Serial.println("Fehler beim Öffnen der Datei: " + filename);
    }
  }
  delay(2000);
}

void tcaselect(uint8_t i) {
  if (i > 7) return;

  Wire.beginTransmission(0x70);
  Wire.write(1 << i);
  Wire.endTransmission();
}

Hallo,

Überlege einmal ganz genau. Du hast einen I2C Bus. Einen! Wie sollen damit mehrere am Bus angeschlossene Geräte gleichzeitig bedient werden? Das funktioniert nur nacheinander. Dafür hilft dir auch ein TCA9548A nichts. Weil was macht der denn? Warum ist nacheinander nicht ausreichend? Was ich sagen will ist. Eine gewisse Grundvorstellung bzw. Grundwissen über das was wie funktionieren soll muss immer vorhanden sein. Sonst passiert genau das.

Klar das du die Uhr nicht siechst, die wird kompiliert aber nicht angesprochen .
Das ist das Problem wen man selber nicht denkt.
Egal was für Bus man nutzt man kann so viele Dinger dran klemmen wie der Speicher reicht, außer I²C der kann nur bis 170.

Mit dem pn532 hatte ich auch nur Probleme es mit mehreren Teilnehmern an einem i2c bus zu betreiben. Meine Lösung bestand dann darin es an den spi bus zu klemmen. Hier aber das gleiche Problem wie bei i2c, dass sobald da ein weiterer Teilnehmer dazu kommt, dass ganze wieder nicht funktionieren mag. Aber das PN532 kann Glücklicherweise auch softspi und somit hat es bei mir jetzt seinen eigenen softspi bus und alle Probleme gehören der Vergangenheit an.

1 Like

Mensch Fony, dafür gibt es doch den Roboter :slight_smile:

1 Like

Der kann auch nicht denken und wir sind nicht dessen Debugger.

Gruß Tommy

Warum funktioniert das nicht?

  1. Den brauchts nur bei Adresskonflikten. Hast du diese?
  2. Der ist voll einfach zu bedienen! Einfach mal Datenblatt lesen...

Ja das habe ich verstanden, es soll auch nacheinander laufen, also der pn532 ist aktiv, sobald der Tag erkannt wird Schalter er um auf die RTC.

VoidReadnfc ist doch da oder wo ist das Problem?

Okay also kenne mich nicht aus und finde es sehr kompliziert alles. Ich hatte beides eben gleichzeitig angeschlossen an a4 und a5 und der Tag wurde erkannt, aber die RTC hat dann nicht funktioniert.

Dann setze die Funktion der RTC mal so ein, dass diese auch in der Loop gelesen werden kann.
Evtl. merkst du dann, wo dein Problem liegt.

Kannst du mir nicht die Lösung sagen, warum Frage ich sonst in einem Forum? Bin nicht hier um mir Vorwürfe anzuhören, ich kann Arduino nicht

Ach, Du machst alles richtig und wir sind die bösen, weil wir etwas von Dir verlangen?
Wenn Du jemanden suchst, der kritiklos Deine Arbeit macht, dann kaufe Dir einen Dienstleister.

Leute gibt es.

Gruß Tommy

Kennst du einen günstigen? Habe ca. 50€ übrig dafür

Welche Vorwürfe ?
Und was du machen solltest, habe ich dir geschrieben. Und "Arduino" kann man lernen.
Natürlich geht das nicht in einer Stunde oder einem Tag. Meist dauert es etwas länger, sich in ein neues Fachgebiet einzuarbeiten. Mit etwas Mühe schaffst du das auch.

Ich weiß auch nicht wie ich es beschreiben soll, ich kenne mich eben nicht aus und Frage deshalb Experten in einem Forum nach Lösungen. Wenn du schon siehst, dass etwas falsch ist, dann sag doch wie es richtig wäre

Da fehlen ein paar Nullen hinten dran.

Gruß Tommy

Er hat dir doch gesagt was falsch ist. Du hast zwar eine Funktion, welche die Uhr betrifft (printTime) aber du verwendest diese in deinem Code nie. Die musst du in der loop() Funktion aufrufen.