RFID e relè blocco?

Ciao,

ho realizzato un progetto che tramite un lettore rfid (RC522) collegato ad un arduino permette l'apertura di 2 motori lineari collegati a dei relè optoisolati che comando con l'arduino alla lettura della scheda. La lettura della scheda aziona i relè e fa chiudere i motori, mentre per l'apertura degli stessi, l'arduino riceve comandi seriali da un pc (il collegamento tra pc e arduino è tramite la USB). Visto che i motori sono 2 ho utilizzato un modolu a 4 relè che a seconda delle condizioni switchano da NO a NC

Tutto funziona, ma quando alimento i motori lineari tutto il procedimento funziona un paio di volte e poi sembra bloccarsi. Questo avviene però solo quando il pc invia comandi all'arduino, se inglobo tutto (apertura e chiusura dei motori) nello skech tutto funziona correttamente.

La libreria del RC522, tramite il metodo PCD_Init(), permette di reinizializzare la scheda. Quando il sistema smette di funzionare (come su descritto), se chiamo questo metodo tutto riprende a funzionare correttamente.

Ora vorrei sapere secondovoi se :

Il problema è di natura elettrico?
La chiamata al metodo PCD_Init() ogni volta che leggo una scheda (così da resettare tutto) ha controindicazioni a lungo andare?

Dovresti postare schema elettrico e codice.

Ciao,
P.

pgiagno:
Dovresti postare schema elettrico e codice.

Ciao,
P.

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

#define RST_PIN   9
#define SS_PIN    10
#define LED 8 

const byte MY_ID = 3;

MFRC522 mfrc522(SS_PIN, RST_PIN);

const int relay1 = 2;   //Arduino pin that triggers relay #1
const int relay2 = 3;   //Arduino pin that triggers relay #2
const int relay3 = 4;   //Arduino pin that triggers relay #3
const int relay4 = 5;   //Arduino pin that triggers relay #4 

const String DELIMITER = ":AAAAA:";

String message4server = "";
String inputString = "";      // a String to hold incoming data
bool stringComplete = false;  // whether the string is complete

void setup() {
  SPI.begin();        // SPI bus
  Serial.begin(9600);
  mfrc522.PCD_Init(); //  MFRC522
  pinMode(LED, OUTPUT); 
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);

  digitalWrite(LED, LOW);
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW);
  digitalWrite(relay4, LOW);
  
}

void loop() {
  message4server = "";
  if(getID(true)){
    
  }
  else{
    if(Serial.available()){
      char inChar = (char)Serial.read();
      if(inChar == '1'){
        extendActuator();
        delay(3000);       
      }
    }
  }
}

void extendActuator() {
  digitalWrite(relay1, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay2, LOW);
  digitalWrite(relay4, LOW);
}

void retractActuator() {
  digitalWrite(relay1, LOW);
  digitalWrite(relay3, LOW);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay4, HIGH);
}

boolean getID(boolean stopIt){ //Read new tag if available
  if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
    return false;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
    return false;
  }

  blinkLed(3, 100);

  String tagID = "";
  for ( uint8_t i = 0; i < 4; i++) { // The MIFARE PICCs that we use have 4 byte UID
    tagID.concat(String(mfrc522.uid.uidByte, HEX)); // Adds the 4 bytes in a single String variable
  }
  tagID.toUpperCase();
  if(stopIt){
    mfrc522.PICC_HaltA(); // Stop reading
    //mfrc522.PCD_StopCrypto1();
  }
  retractActuator();
  return true;
}

void blinkLed(int volte, int intervallo){
  for(int i=0; i<volte;i++){
    digitalWrite(LED, HIGH);
    delay(intervallo);
    digitalWrite(LED, LOW);
    delay(intervallo);    
  }
}

Se come dici tutto funziona senza problemi finché non invii dati da PC allora possiamo escludere interferenze elettromagnetice et simila (ma non le escluderei del tutto comunque a priori) e focalizzarci sull'annoso problema dell'uso della classe String, sul forum s'è ne parlato un sacco di volte.
Per quanto possibile, evita sempre la classe "String" ... difatti NON sei su un PC dove c'è un sistema operativo ed un "garbage collector", sei su una piccola MCU con solo 2KBytes di SRAM, dove devi fare tutto tu e dove usare la classe "String", a causa dell'allocazione e riallocazione dinamica della memoria, porta quasi sempre ... a grossi problemi e sicuri mal di testa !!! :smiling_imp:
Che come desxrivi potrebbe essere proprio il tuo problema blocchi improvvisi e senza apparente spiegazione.
Come prima cosa eliminerei tutte le varibili con classe String per sostituirle con le stringhe classiche del C (vettori di caratteri, array di char tanto per darti due termini con cui ricercare) e riproverei il tutto.
Tra l'altro sembra che nel codice postato tu non usi un sacco di cose che dichiari, semplicemente ti limiti a leggere un carattere quindi se anche per il progetto finito ti arriverà un solo carattere con cui dovrai intraprendere svariate azioni allora la conversione è semplicissima.
Ma sono quasi pronto a scommettere che in futuro vorrai fare più cose assieme (Es. mentre l'attuatore si distende vorrai fermarlo, farlo ttornare in posizione iniziale, ecc.) e quel delay ti causerà non pochi problemi :slight_smile:

Stavo pensando, ma forse sbaglio. Potrebbe essere il caso di alimentare esternamente il modulo relay?

Assolutamente si, di solito si consiglia di alimentare le schede relè con alimentatore separato.
Resta comunque il problema delle stringhe che tanto alla lunga di daranno problemi se il dispositivo è attivo 24h 7/7, vari escamotage come reset software o hardware sono delle porcherie a cui Windows ha abituato gli utenti quindi secondo me ti conviene pensare seriamente a rimuovere tutto ciò che usa la classe String

fabpolli:
Assolutamente si, di solito si consiglia di alimentare le schede relè con alimentatore separato.
Resta comunque il problema delle stringhe che tanto alla lunga di daranno problemi se il dispositivo è attivo 24h 7/7, vari escamotage come reset software o hardware sono delle porcherie a cui Windows ha abituato gli utenti quindi secondo me ti conviene pensare seriamente a rimuovere tutto ciò che usa la classe String

Grazie,

per il discorso string ho già sistemato. Appena possibile provo anche a isolare l'alimentazione del rele.

Grazie

Ciao,

allora ho avuto modo di alimentare il modulo relè dall'esterno, ma il problema si presenta ancora, in modo però meno frequente.

A questo punto potrebbero essere i motori o forse qualcosa di sbagliato nei collegamenti?

In allegato lo schema completo con i collegamenti anche lato rele

marcomorgia:
allora ho avuto modo di alimentare il modulo relè dall'esterno, ma il problema si presenta ancora, in modo però meno frequente.

Puoi mettere lo schema esatto di come hai fatto QUESTO collegamento ? Perché occorre separare "completamente" (nulla in comune, neanche i GND) le schede relè da Arduino ... ::slight_smile:

Link alla scheda relè che usi?

Guglielmo

Collegamento errato ...
... con quei moduli a 4 relè DEVI seguire il seguente schema (© Brunello) utilizzando DUE alimentatori sepratati, uno per Arduino ed uno per alimentare i relè:


In questo modo vedrai che i relè lavorano a "logica invertita" ... pin LOW -> relè ON, pin HIGH -> relè OFF e quindi dovrai tenerne conto nel codice.

Guglielmo

gpb01:
Collegamento errato ...
... con quei moduli a 4 relè DEVI seguire il seguente schema (© Brunello) utilizzando DUE alimentatori sepratati, uno per Arduino ed uno per alimentare i relè:


In questo modo vedrai che i relè lavorano a "logica invertita" ... pin LOW -> relè ON, pin HIGH -> relè OFF e quindi dovrai tenerne conto nel codice.

Guglielmo

Si scusa, ho postato uno schema vecchio. In realtà l'alimentazione è separata

marcomorgia:
Si scusa, ho postato uno schema vecchio. In realtà l'alimentazione è separata

E quindi quello aggiornato rispecchia esattamente quanto sopra? Puoi mettere la versione completamente aggiornata?

Guglielmo

Ecco lo schema completo

... perdona e ... secondo te quello schema rispecchia quanto ti ho detto di fare ? ? ? :o :o :o

Guglielmo

Scusa scusa ho postato il file sbagliato :confused:

Finalmente ... :smiley:

Io metterei un condensatore ad 0.1 μF in parallelo a ciascun motore, assieme ad un diodo messo in antiparallelo (il tutto per eliminare i disturbi all'apertura e chiusura dei contatti del relè) ... dovrebbe essere sufficiente ::slight_smile:

Guglielmo

Solo una cortesia, potresti mandarmi uno schema tanto per essere sicuro di aver capito bene.

Grazie

Il diodo in ANTIPARALLELO al motore NON LO PUOI METTERE, perché tu cambi polarità per avere le due rotazioni, destrorsa e sinisrtrorsa.

Se lo metti Mandi in corto l'alimentazione nel senso di rotazione opposto al diodo.

Perfetto,

per quanto riguarda il diodo ne serve un modello specifico o va bene il primo che trovo ?