5 RFID con Arduino Uno

Ciao a tutti, avrei un problema con Arduino Uno nel gestire 5 RFID Reader ID-12 nello stesso tempo.
Ora ne sto usando 2 per le prove e spesso non riescono a leggere il tag RFID o lo fanno male.
Non so se il problema è dell'alimentazione(li alimento con l'Arduino, ma con un alimentatore esterno non funzionano, non so perchè) o del programma:

#include <NewSoftSerial.h>

NewSoftSerial ss(8, 3);
NewSoftSerial ss2(9, 4);
NewSoftSerial ss3(10, 5);
NewSoftSerial ss4(11, 6);
NewSoftSerial ss5(12, 7);

void setup()
{
  
  Serial.begin(9600);
  ss.begin(9600);
  ss2.begin(9600);
  ss3.begin(9600);
  ss4.begin(9600);
  ss5.begin(9600);
  
}

void loop()
{
  ss.listen();
  
  char c = 0;
  int cont = 0;
    if(ss.available()){
    do{
    cont++;
    if (ss.available())
    {
      cont=0;
      c = ss.read();
      Serial.print(c);
    }
    }while(cont != 11);
    }
  
  ss2.listen();
  c = 0;
  cont = 0;
  if(ss2.available()){
  do{
  cont++;
  if (ss2.available())
  {
    cont=9;
    c = ss2.read();
    Serial.print(c);
  }
  }while(cont != 11);
  }
  ss3.listen();
  
  c = 0;
  cont = 0;
    if(ss3.available()){
    do{
    cont++;
    if (ss3.available())
    {
      cont=9;
      c = ss3.read();
      Serial.print(c);
    }
    }while(cont != 11);
    }
    
  ss4.listen();
  c = 0;
  cont = 0;
  if(ss4.available()){
  do{
  cont++;
  if (ss4.available())
  {
    cont=9;
    c = ss4.read();
    Serial.print(c);
  }
  }while(cont != 11);
  }
  ss5.listen();
  
  c = 0;
  cont = 0;
    if(ss5.available()){
    do{
    cont++;
    if (ss5.available())
    {
      cont=9;
      c = ss5.read();
      Serial.print(c);
    }
    }while(cont != 11);
    }
  
}

Grazie!

Che tipo sono ? 125Khz o 13.56Mhz ??
Molti tipi di rfid non hanno l'anti collissione, non puoi leggerli più di uno contemporaneamente!

Secondo me anche voler gestire 5 connessioni seriali emulate via SW con un Arduino non é possibile.
Ciao Uwe

uwefed:
Secondo me anche voler gestire 5 connessioni seriali emulate via SW con un Arduino non é possibile.
Ciao Uwe

La NewSoftSerial può reggere più canali seriali software a patto di usarne solo 1 alla volta. Non ho esaminato il suo codice per cui non so se il problema sta qui.
Anche la SoftwareSerial dell'Arduino IDE 1.0 permette di poter gestire più canali seriali software ma di poter dialogare solo con 1 alla volta.

Leo, cosa intendi per dialogare?
Penso che per ricevere i dati di 5 lettori RFID debbano essere attivi tutti i 5 canali di ricezione delle seriali.
Ciao Uwe

ciao

La NewSoftSerial può reggere più canali seriali software a patto di usarne solo 1 alla volta. Non ho esaminato il suo codice per cui non so se il problema sta qui.
Anche la SoftwareSerial dell'Arduino IDE 1.0 permette di poter gestire più canali seriali software ma di poter dialogare solo con 1 alla volta.

effettivamente la SoftwareSerial distribuita con l'IDE 1.0 è basata sulla NewSoftSerial :P:

The version of SoftwareSerial included in 1.0 and later is based on the NewSoftSerial library by Mikal Hart.

uwefed:
Leo, cosa intendi per dialogare?
Penso che per ricevere i dati di 5 lettori RFID debbano essere attivi tutti i 5 canali di ricezione delle seriali.
Ciao Uwe

Siccome è basata sugli interrupt, per non caricare eccessivamente la ISR potrà spedire/ricevere solo da 1 canale seriale per volta. Per cui se metti, ad esempio, 5 invii sulle 5 seriali saranno eseguiti 1 dietro l'altro e non in contemporanea. Così varrà immagino per la ricezione, nel senso che non appena metti un read su un canale, non potrai fare altrettanto su un altro canale dato che dai l'uso dell'interrupt al primo.

lollotek:
Che tipo sono ? 125Khz o 13.56Mhz ??
Molti tipi di rfid non hanno l'anti collissione, non puoi leggerli più di uno contemporaneamente!

Sinceramente non ne ho idea...

leo72:

uwefed:
Leo, cosa intendi per dialogare?
Penso che per ricevere i dati di 5 lettori RFID debbano essere attivi tutti i 5 canali di ricezione delle seriali.
Ciao Uwe

Siccome è basata sugli interrupt, per non caricare eccessivamente la ISR potrà spedire/ricevere solo da 1 canale seriale per volta. Per cui se metti, ad esempio, 5 invii sulle 5 seriali saranno eseguiti 1 dietro l'altro e non in contemporanea. Così varrà immagino per la ricezione, nel senso che non appena metti un read su un canale, non potrai fare altrettanto su un altro canale dato che dai l'uso dell'interrupt al primo.

Si, è quello che ho cercato di fare, ma temo non mi sia riuscito bene, per questo ho chiesto :slight_smile:

Andryy:
Si, è quello che ho cercato di fare, ma temo non mi sia riuscito bene, per questo ho chiesto :slight_smile:

Sinceramente non so come opera la NewSoftSerial "dietro le quinte". Andrebbe esaminato il codice e capita la sua struttura. Io non ci ho mai gestito più di 1 canale per volta.

Scusa, avevo capito che volevi leggere 5 tessere contemporaneamente..
Ma da che codice di esempio sei partito? Perché dici che legge male? Ma con una tessera funge?
Quando ci sono problemi bisogna sempre scomporre in sotto parti.. una volta che va bene uno basta fare un cliclo for..

lollotek:
Scusa, avevo capito che volevi leggere 5 tessere contemporaneamente..
Ma da che codice di esempio sei partito? Perché dici che legge male? Ma con una tessera funge?
Quando ci sono problemi bisogna sempre scomporre in sotto parti.. una volta che va bene uno basta fare un cliclo for..

Beh, quasi, in pratica devo leggere rfid da 5 lettori, non contemporaneamente, però spesso non mi restituisce il tag dell'rfid.
Con uno funziona, però per quello ho usato la SoftwareSerial, che non sono riuscito a fare funzionare con 2 rfid.
Suggerimenti su come usare la SoftwareSerial (se si può) con più rfid o su come farne andare 5 con la NewSoftSerial?
Grazie!

potrei dire una bestialità, ma se hai 5 device seriali attaccati ad arduino ma alimentati separatamente, hai controllato che il gnd arduino sia connesso ai gnd dei 5 device?

Poi NewSoftwareSerial e SoftwareSerial sono veramente le stesse in IDE 1.0 ...

No, sono totalmente separati, l'Arduino lo alimento da pc mentre gli rfid da un alimentatore, ma cosa cambia?

Succede che con alimentazione esterna rispetto alle linee dati arduino ha un gnd diverso da quello dei device e spesso questo crea problemi

Quindi esternalmente dovrei dargli solo i 5v e il gnd darlo all'Arduino?

no, il gnd degli alimentatori va collegato al GND dell'arduino.
GND è il valore di riferimento, essendo il voltaggio una "differenza di tensione", servono due valori: il gnd, che rappresenta lo 0V, e il 5v, che rappresenta uno scostamento di 5v dal GND. se tu misurassi il GND degli alimentatori rispetto a quello arduino probabilmente rileveresti qualche V di differenza: ognuno ha il suo 0v! collegandoli insieme fai in modo che il valore di riferimento sia uguale per tutti

Andryy:

lollotek:
Scusa, avevo capito che volevi leggere 5 tessere contemporaneamente..
Ma da che codice di esempio sei partito? Perché dici che legge male? Ma con una tessera funge?
Quando ci sono problemi bisogna sempre scomporre in sotto parti.. una volta che va bene uno basta fare un cliclo for..

Beh, quasi, in pratica devo leggere rfid da 5 lettori, non contemporaneamente, però spesso non mi restituisce il tag dell'rfid.
Con uno funziona, però per quello ho usato la SoftwareSerial, che non sono riuscito a fare funzionare con 2 rfid.
Suggerimenti su come usare la SoftwareSerial (se si può) con più rfid o su come farne andare 5 con la NewSoftSerial?
Grazie!

questo è un altro problema. fossi in te farei una read su ogni porta ogni loop, nel momento in cui leggi un qualcosa in arrivo, ti blocchi a leggere quella porta per il tempo necessario a ricevere 3 volte il codice RFID (in modo da ricevere almeno una lettura completa, puoi fare anche solo 2 volte ma poi devi giocare di concatenazione). Una volta passato questo tempo indipendentemente se hai letto qualcosa, e se questo qualcosa era valido o meno, prosegui per la tua strada.
a 9600 baud leggi 960 caratteri al secondo, quindi se il rfid è di 12 caratteri +2 di inizio e fine, il tempo (in millisecondi) per una lettura completa è 1000/(960/14) = circa 14 millisecondi

Lesto è stato più lesto di me :slight_smile:
Prova a connettere i gnd arduino e quelli dell'alimentatore e 90% hai risolto il problema del funzionamento.
Per la lettura non dovresti avere problemi di temporizzazione. La chiave di un Mifare è lunga al max 7 byte, più 4 o 5 byte di incapsulamento del messaggio. Io normalmente ho usato lettori con interfaccia I2c, e con un protocollo che ha come header la lunghezza del messaggio in arrivo. Questo mi permette di verificare se è arrivato tutta la risposta o meno. Se poi la risposta non arriva posso abortire l'operazione di lettura, passare al prossimo rfid e ritentare la lettura il ciclo successivo. Dipende dal protocollo di interfaccia

lesto:
no, il gnd degli alimentatori va collegato al GND dell'arduino.
GND è il valore di riferimento, essendo il voltaggio una "differenza di tensione", servono due valori: il gnd, che rappresenta lo 0V, e il 5v, che rappresenta uno scostamento di 5v dal GND. se tu misurassi il GND degli alimentatori rispetto a quello arduino probabilmente rileveresti qualche V di differenza: ognuno ha il suo 0v! collegandoli insieme fai in modo che il valore di riferimento sia uguale per tutti

Andryy:

lollotek:
Scusa, avevo capito che volevi leggere 5 tessere contemporaneamente..
Ma da che codice di esempio sei partito? Perché dici che legge male? Ma con una tessera funge?
Quando ci sono problemi bisogna sempre scomporre in sotto parti.. una volta che va bene uno basta fare un cliclo for..

Beh, quasi, in pratica devo leggere rfid da 5 lettori, non contemporaneamente, però spesso non mi restituisce il tag dell'rfid.
Con uno funziona, però per quello ho usato la SoftwareSerial, che non sono riuscito a fare funzionare con 2 rfid.
Suggerimenti su come usare la SoftwareSerial (se si può) con più rfid o su come farne andare 5 con la NewSoftSerial?
Grazie!

questo è un altro problema. fossi in te farei una read su ogni porta ogni loop, nel momento in cui leggi un qualcosa in arrivo, ti blocchi a leggere quella porta per il tempo necessario a ricevere 3 volte il codice RFID (in modo da ricevere almeno una lettura completa, puoi fare anche solo 2 volte ma poi devi giocare di concatenazione). Una volta passato questo tempo indipendentemente se hai letto qualcosa, e se questo qualcosa era valido o meno, prosegui per la tua strada.
a 9600 baud leggi 960 caratteri al secondo, quindi se il rfid è di 12 caratteri +2 di inizio e fine, il tempo (in millisecondi) per una lettura completa è 1000/(960/14) = circa 14 millisecondi

Come dovrei fare quindi?
Il programma che uso non va bene?

E una cosa, il GND dell'alimentatore va collegato insieme al GND dell'Arduino ed agli rfid sulla breadboard? O va collegato solo al GND dell'Arduino?
Grazie!

non va bene se credi che i tag rfid sino letti per meno di 14ms. In pratica per un essere umano la cosa è immediata (il riflesso minimo dell'occhio si aggira sui 30ms)

Ok, ma come faccio in termini di programmazione a farlo?