ethernet shield smette di trasmettere se collego RFID MFRC522

Ciao a tutti,

sto utilizzando arduino UNO + ethernet shield + lettore RFID modello MFRC522

l'rfid è collegato ai seguenti PIN di arduino
SS = 8
SCK = 13
MOSI = 11
MISO = 12
RST = 9

Premetto che ho provato a collegare fino a 5 lettori di questo tipo solo con arduino (senza ethernet shield) e tutto funziona regolarmente.

Se aggiungo la ethernet shield gli RFID funzionano mentre la shield NON trasmette nulla. se invece scollego gli RFID la shield torna a funzionare.

La cosa strana è che con il seguente codice utilizzando solo la libreria ethernet.h tutto funziona correttamente finchè non attacco l'rfid ai pin sopra. Appena lo collego (anche se non è gestito nel codice) la shield smette di trasmettere.
Se stacco l'rfid la shield torna a funzionare.

Sembra quasi un problema elettrico, come se gli RFID interferissero con la comunicazione ethernet.

Qualcuno ha qualche suggerimento da darmi per risolvere questo problema?

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xCF, 0xBE, 0xFE, 0xFE, 0xEE };
IPAddress ip(10, 100, 1, 51);
EthernetServer server(80);


void setup() {
  // attivo la comunicazione seriale per il debug
  Serial.begin(9600);

  // imposto indirizzo mac e IP e avvio la funzionalit� di server
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop() {
  
    // leggo il client web per verificare se ci sono connessioni in ingresso
    EthernetClient client = server.available();

    if (client) {
      Serial.println("nuovo client");
        boolean currentLineIsBlank = true;

        // gestisco tutte le connessioni in ingresso
        while (client.connected()) {
            // creo una risposta http e nel corpo della pagina aggiungo le informazioni formattate in XML
            if (client.available()) { 
              char c = client.read();
  
              if (c == '\n' && currentLineIsBlank) { 
                  client.println("HTTP/1.1 200 OK");   
                  client.println("Content-Type: application/json;charset=utf-8");
                  client.println("Connnection: close");
                  client.println();
                  client.println("prova");  
                  client.println();
                  break;
              }

              if (c == '\n') {
                currentLineIsBlank = true;
              } 
              else if (c != '\r') {
                currentLineIsBlank = false;
              }
          }
      }
     
      delay(1);
    }

    // stoppo il client per procedere con la gestione dell'indovinello
    client.stop();
}

Grazie a tutti in anticipo :smiley:
Luca

liuk88:
Sembra quasi un problema elettrico, come se gli RFID interferissero con la comunicazione ethernet.

... NON con la comunicazione "ethernet", di cui non sanno nulla, ma con la comunicazione SPI !!!

Sicuro che la libreria che usi per gli RFID gestisca correttamente il pin SS? Perché, se anche uno solo rimane con il pin SS a LOW, il bus SPI rimane impegnato.

La Ethernet shied originale usa come SS il pin 4 (Ethernet) ed il pin 10 (SD). Se non si usa la SD, il pin 10 va comunque dichiarato in OUTPUT e posto HIGH (... è spiegato nel reference della Ethernet di Arduino).

Guglielmo

Ciao Guglielmo grazie della risposta. :smiley:

Ho provato a impostare il pin 10 ad high ma non cambia nulla.

Il mio problema è un pò strano perchè se carico il codice sotto che non usa nessuna libreria di gestione degli RFID tutto funziona correttamente finchè non collego gli RFID.
Praticamente è sufficiente collegarne uno per far si che la ethernet smetta di funzionare

L'unica cosa che aggiungo è che il collegamento con gli RFID non lo faccio direttamente ma passo per un PCB (allego lo schema). Il PCB in pratica non fa nulla. Serve solo per tenere in ordine i cavi e "morsettarli"

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xCF, 0xBE, 0xFE, 0xFE, 0xEE };
IPAddress ip(10, 100, 1, 51);
EthernetServer server(80);


void setup() {
  // attivo la comunicazione seriale per il debug
  Serial.begin(9600);

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);

  // imposto indirizzo mac e IP e avvio la funzionalit� di server
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop() {
  
    // leggo il client web per verificare se ci sono connessioni in ingresso
    EthernetClient client = server.available();

    if (client) {
      Serial.println("nuovo client");
        boolean currentLineIsBlank = true;

        // gestisco tutte le connessioni in ingresso
        while (client.connected()) {
            // creo una risposta http e nel corpo della pagina aggiungo le informazioni formattate in XML
            if (client.available()) { 
              char c = client.read();
  
              if (c == '\n' && currentLineIsBlank) { 
                  client.println("HTTP/1.1 200 OK");   
                  client.println("Content-Type: application/json;charset=utf-8");
                  client.println("Connnection: close");
                  client.println();
                  client.println("prova");  
                  client.println();
                  break;
              }

              if (c == '\n') {
                currentLineIsBlank = true;
              } 
              else if (c != '\r') {
                currentLineIsBlank = false;
              }
          }
      }
     
      delay(1);
    }

    // stoppo il client per procedere con la gestione dell'indovinello
    client.stop();
}

Qualche idea sul motivo?

Grazie mille

Luca

Ciao a tutti,

sto ufficialmente impazzendo :astonished:

Ho fatto molte prove e sono giunto alla conclusione che il problema è la lunghezza dei cavi.

Nel mio progetto devo collegare 5 RFID MFRC522 ad arduino.
Ogni cavo è lungo 40cm

Se collego solo i 5 RFID tutto funziona regolarmente.

Se invece collego la ethernet shield (originale arduino) smette di funzionare anche SOLO collegando un singolo RFID con cavo da 40cm

Se invece collego gli RFID con cavi cortissimi di pochi cm la ethernet shield funziona.

I cavi sono realizzati utilizzando cavo di rete cat.6 e sono morsettati da entrambi i lati (in allegato le foto)

Questo è mio codice completo
la libreria che uso è questa: GitHub - miguelbalboa/rfid: Arduino RFID Library for MFRC522

#include <MFRC522.h>
#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>

#define RST_PIN 9          // pin reset RFID
#define SS_CANDLE_B_PIN 8  // pin SS RFID (connettore CN18)
#define SS_CANDLE_F_PIN 7  // pin SS RFID (connettore CN25)
#define SS_CANDLE_A_PIN 6  // pin SS RFID (connettore CN15)
#define SS_CANDLE_G_PIN 5  // pin SS RFID (connettore CN11)
#define SS_CANDLE_D_PIN 3  // pin SS RFID (connettore CN7)
#define RESET_RFID_TIME 5000  // tempo di mancata lettura scaduto il quale l'RFID vience considerato rimosso dal giocatore

byte mac[] = { 0xDE, 0xBE, 0xFE, 0xFE, 0xBC, 0xEE };
IPAddress ip(192, 168, 1, 60);
EthernetServer server(80);

MFRC522 mfrc522_candle_b;     
MFRC522 mfrc522_candle_f;
MFRC522 mfrc522_candle_a;
MFRC522 mfrc522_candle_g;
MFRC522 mfrc522_candle_d;

bool candleB;
bool candleF;
bool candleA;
bool candleG;
bool candleD;

unsigned long candleBMillis; 
unsigned long candleFMillis;
unsigned long candleAMillis;
unsigned long candleGMillis;
unsigned long candleDMillis;

void setup() {
  // attivo la comunicazione seriale per il debug
  Serial.begin(9600);
  while (!Serial);

  SPI.begin();
  // inizializzo tutti gli RFID
  mfrc522_candle_b.PCD_Init(SS_CANDLE_B_PIN, RST_PIN);
  mfrc522_candle_f.PCD_Init(SS_CANDLE_F_PIN, RST_PIN);
  mfrc522_candle_a.PCD_Init(SS_CANDLE_A_PIN, RST_PIN);
  mfrc522_candle_g.PCD_Init(SS_CANDLE_G_PIN, RST_PIN);
  mfrc522_candle_d.PCD_Init(SS_CANDLE_D_PIN, RST_PIN);

  // imposto indirizzo mac e IP e avvio la funzionalit� di server
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop() {
    // leggo il client web per verificare se ci sono connessioni in ingresso
    EthernetClient client = server.available();

    if (client) {
        boolean currentLineIsBlank = true;

        // gestisco tutte le connessioni in ingresso
        while (client.connected()) {
            // creo una risposta http e nel corpo della pagina aggiungo le informazioni formattate in XML
            if (client.available()) { 
              char c = client.read();
  
              if (c == '\n' && currentLineIsBlank) { 
                  client.println("HTTP/1.1 200 OK");   
                  client.println("Content-Type: application/json;charset=utf-8");
                  client.println("Connnection: close");
                  client.println();
                  client.println("{\"candleB\":" + String(candleB) + ",\"candleF\":" + String(candleF) + ",\"candleA\":" + String(candleA) + ",\"candleG\":" + String(candleG) + ",\"candleD\":" + String(candleD) + "}");  
                  client.println();
                  break;
              }

              if (c == '\n') {
                currentLineIsBlank = true;
              } 
              else if (c != '\r') {
                currentLineIsBlank = false;
              }
          }
      }
     
      delay(1);
    }

    // stoppo il client per procedere con la gestione dell'indovinello
    client.stop();

    
  
   if (mfrc522_candle_b.PICC_IsNewCardPresent()) {
    if (mfrc522_candle_b.PICC_ReadCardSerial()) {
      String value = getRfidTag(mfrc522_candle_b.uid.uidByte, mfrc522_candle_b.uid.size);
      if (value == " fa 6c 91 15") {
        candleB = true;
        candleBMillis = millis();
      }
    }
  }
  mfrc522_candle_b.PICC_HaltA();
  mfrc522_candle_b.PCD_StopCrypto1();

  if (mfrc522_candle_f.PICC_IsNewCardPresent()) {
    if (mfrc522_candle_f.PICC_ReadCardSerial()) {
      String value = getRfidTag(mfrc522_candle_f.uid.uidByte, mfrc522_candle_f.uid.size);
      if (value == " 9a 34 b5 15") {
        candleF = true;
        candleFMillis = millis();
      }
    }
  }
  mfrc522_candle_f.PICC_HaltA();
  mfrc522_candle_f.PCD_StopCrypto1();

  if (mfrc522_candle_a.PICC_IsNewCardPresent()) {
    if (mfrc522_candle_a.PICC_ReadCardSerial()) {
      String value = getRfidTag(mfrc522_candle_a.uid.uidByte, mfrc522_candle_a.uid.size);
      if (value == " 9a 90 95 15") {
        candleA = true;
        candleAMillis = millis();
      }
    }
  }
  mfrc522_candle_a.PICC_HaltA();
  mfrc522_candle_a.PCD_StopCrypto1();

  if (mfrc522_candle_g.PICC_IsNewCardPresent()) {
    if (mfrc522_candle_g.PICC_ReadCardSerial()) {
      String value = getRfidTag(mfrc522_candle_g.uid.uidByte, mfrc522_candle_g.uid.size);
      if (value == " 7a b4 33 15") {
        candleG = true;
        candleGMillis = millis();
      }
    }
  }
  mfrc522_candle_g.PICC_HaltA();
  mfrc522_candle_g.PCD_StopCrypto1();

  if (mfrc522_candle_d.PICC_IsNewCardPresent()) {
    if (mfrc522_candle_d.PICC_ReadCardSerial()) {
      String value = getRfidTag(mfrc522_candle_d.uid.uidByte, mfrc522_candle_d.uid.size);
      if (value == " 6a 0d bb 15") {
        candleD = true;
        candleDMillis = millis();
      }
    }
  }
  mfrc522_candle_d.PICC_HaltA();
  mfrc522_candle_d.PCD_StopCrypto1();
  
  unsigned long currentMillis = millis();

  if (currentMillis - candleBMillis > RESET_RFID_TIME) {
    candleB = false;
  }

  if (currentMillis - candleFMillis > RESET_RFID_TIME) {
    candleF = false;
  }

  if (currentMillis - candleAMillis > RESET_RFID_TIME) {
    candleA = false;
  }

  if (currentMillis - candleGMillis > RESET_RFID_TIME) {
    candleG = false;
  }

  if (currentMillis - candleDMillis > RESET_RFID_TIME) {
    candleD = false;
  }
}

String getRfidTag(byte *buffer, byte bufferSize) {
  String value = "";
  for (byte i = 0; i < bufferSize; i++) {
     value.concat(String(buffer[i] < 0x10 ? " 0" : " "));
     value.concat(String(buffer[i], HEX));
  }
  return value;
}

Qualcuno ha qualche suggerimento?

Grazie in anticipo :smiley:

Luca

Il fatto è che il bus SPI NON è nato per essere portato in giro, ma per connettere tra di loro IC sullo stesso stampato.

Considera che la frequenza dei segnali che viaggiono su di esso è dell'ordine dei MHz (su Arduino di base viaggiano a 4MHz) con fronti di salita e discesa estremamente veloci ... la capacità dei cavi arrotonda tali fronti e ... spesso non funziona più nulla.

Mi spiace, NON ho una soluzione se non quella di accorciare i cavi ed usare cavi a bassissima capacità o ... adottare tecniche per estenderne la lunghezza ...

Prova a studiarti l'allegato.

Guglielmo

Extending the SPI bus for long-distance communication.pdf (146 KB)

Ciao Guglielmo,

grazie della risposta proverò a cambiare tipo di cavi e accorciare la distanza il più possibile.

Secondo te per i cavi è meglio che utilizzo quelli "dritti". Tipo quelli utilizzati negli allarmi che non sono intrecciati può essere la soluzione migliore?

Per intenderci vorrei provare con questi:

Grazie mille :smiley:
Luca

Ma di quali "cavi lunghi 40cm" stiamo parlando? Se riesci a fare una foto del tutto, anche solo in versione prototipo...

Ciao,

attualmente sto usando cavi di rete cat.6.

Su ogni arduino vorrei collegare 5 RFID + ethernet shield

I cavi sono questi:
Foto 1
Foto 2
Foto 3

Stasera provo con i cavi di allarme e vediamo come va...

Grazie mille
Luca