PN532 (I2C) sleep mode

Come é possibile mettere il dispositivo in basso consumo in modo software e riattivarlo al passggio di un tag ?
Avrei la necessità di fare consumare energia il meno possibile, visto che viene alimentato da una batteria.

Nel datasheet viene indicato in modo abbastanza chiaro quali sono i registri su cui agire

L'avevo letto, ma non capisco come impostarli in un programma, mi puoi fare un esempio ?
È a quel punto che ho chiesto aiuto, perchè per ora non ho trovato un esempio su internet

Dipende ovviamente da come stai controllando il dispositivo... leggi e scrivi direttamente i registri in i2c? Usi una libreria e si quale?

Ho fatto una rapida ricerca online e non mi sembra che ci siano librerie che gestiscono il power mode dell'integrato, quindi temo che dovrai rimboccarti le maniche, studiare in modo approfondito il datasheet ed agire direttamente sul registro magari sfruttando i meccanismi già implementati nell'eventuale libreria che stai usando.

Non riesco a capire cosa intendi: .."come stai controllando il dispositivo..".
La libreria che uso è PN532 di adafruit.
il codice che sto usando è simile a questo:

/*!
 This example is for communicating with the PN532 chip using I2C. Wiring
should be as follows:
  PN532 SDA -> SDA pin
  PN532 SCL -> SCL pin
  PN532 IRQ -> D2
  PN532 GND -> GND
*/
#include <Wire.h>

#include <Adafruit_PN532.h>

#define PN532_IRQ   (3)
#define PN532_RESET (10)  // Not connected by default on the NFC Shield

const int DELAY_BETWEEN_CARDS = 1500;
long timeLastCardRead = 0;
boolean readerDisabled = false;
int irqCurr;
int irqPrev;

// This example uses the IRQ line, which is available when in I2C mode.
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

void setup(void) {
  Serial.begin(9600);
   Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
 
  startListeningToNFC();
}

void loop(void) {
  if (readerDisabled) {
    if (millis() - timeLastCardRead > DELAY_BETWEEN_CARDS) {
      readerDisabled = false;
      startListeningToNFC();
    }
  } else {
    irqCurr = digitalRead(PN532_IRQ);

    // When the IRQ is pulled low - the reader has got something for us.
    if (irqCurr == LOW && irqPrev == HIGH) {
       Serial.println("Got NFC IRQ");
       handleCardDetected();
    }

    irqPrev = irqCurr;
  }
}

void startListeningToNFC() {
  // Reset our IRQ indicators
  irqPrev = irqCurr = HIGH;

  Serial.println("Waiting for an ISO14443A Card ...");
  nfc.startPassiveTargetIDDetection(PN532_MIFARE_ISO14443A);
}

void handleCardDetected() {
    uint8_t success = false;
    uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
    uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

    // read the NFC tag's info
    success = nfc.readDetectedPassiveTargetID(uid, &uidLength);
    Serial.println(success ? "Read successful" : "Read failed (not a card?)");

    if (success) {
      // Display some basic information about the card
      Serial.println("Found an ISO14443A card");
      Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
      Serial.print("  UID Value: ");
      nfc.PrintHex(uid, uidLength);

      if (uidLength == 4)
      {
        // We probably have a Mifare Classic card ...
        uint32_t cardid = uid[0];
        cardid <<= 8;
        cardid |= uid[1];
        cardid <<= 8;
        cardid |= uid[2];
        cardid <<= 8;
        cardid |= uid[3];
        Serial.print("Seems to be a Mifare Classic card #");
        Serial.println(cardid);
      }
      Serial.println("");

      timeLastCardRead = millis();
    }

    // The reader will be enabled again after DELAY_BETWEEN_CARDS ms will pass.
    readerDisabled = true;
}

Pensi se chiedo sul forum di adafruit, mi possano aiutare ?

Ci puoi provare, ma considera che a quanto pare si tratta di implementare una funzionalità che nella libreria in questione non è presente.
Questo significa studiarsi il datasheet e modificare il codice della libreria aggiungendo quello che manca.

Magari prova ad aprire una issue nel repository GitHub della libreria

Nel frattempo ho trovato questa discussione, ma parla dell'interfaccia SPI e non I2C.
Non riesco a capire la connessione tra i registri ed i valori.
Potrei provarla ad usarla con l'interfaccia I2C, perchè nella mia ignoranza ritengo che i registri non cambiano con il tipo di interfaccia usato, forse cambia il modo di invio ?

Credo anche io, non sono sicuro però.

A me comunque rimane il dubbio di mettere in sleep sto lettore. Legge schede/tessere passive (senza corrente), è lui che da corrente al chip sulle schede. Quindi come può essere che si risveglia quando appoggi una tessera che è "morta" ? Ovvero solo quando lui è acceso da corrente alla tessera appoggiata quindi la può "sentire".

Mmm ... non sembra che funzioni proprio così ...

... vedi il segnale RF_DETECT che arriva dalla Contactless Interface Unit?

Nella sezione in cui parla de Soft Power Down dice:

The PN532 can be woken up from a Soft-Power-Down mode when an event occurs on
one of the wake up sources, which has been enabled. There are eight wake-up sources:
• P32_INT0
• P33_INT1
• RF field detected (RF_DETECT)
• HSU wake-up (HSU_ON)
• I2C wake-up (I 2C_ON)
• SPI wake-up (SPI_ON)
• NFC_WI counters
• GPIRQ: P34, P35, P50_SCL, P71

... ovvero, si sveglia con quel segnale. Ora, la CIU (Contactless Interface Unit) ha anche lei i suoi modi di Power Down, sia "Hard-Power-Down" (dove si spegne completamente) che "CIU Power-down" (dove invece sembra che continua a sentire l'avvicinarsi dei RFID).

Comunque, su quel chip la gestione del Power Down è molto complessa, richiede di attivare le "sorgenti" che risvegliano il chip, selezionare i vari Power-Down, ecc. ecc. ... quindi ... occorre studiarsi molto, ma molto bene il datasheet ... PN532_C1.pdf (1.7 MB)

Guglielmo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.