Mise en service alarme RFID et Clavier

Bonjour.
Actuellement j'ai une alarme qui se met en service ou hors service avec un clavier.
Je voudrais mettre en parallèle une mise en service ou hors service avec un badge RFID le tout piloté par une carte arduino uno.
Dans mon montage j'ai mis un relais qui fonctionne en télérupteur. Je badge, l'alarme se met en service. Je badge à nouveau l'alarme se met hors service.
Jusque là tout va bien.
Mais si je met le clavier dans le circuit , mon relais rebondit sans cesse et fait comme une mitraillette.
Ça fait un bon moment que je cherche la cause mais là je sèche.
J'ai l'impression que le RFID perturbe mon entrée clavier.
Car si je met le code du clavier seul ça fonctionne mais dès que j'y ajoute les premières lignes d'initialisation du clavier le relais refait la mitraillette.
J'ai essayé de changer de sortie, j'ai changé de carte uno, en utilisant une fonction ou non pas de changement.
Est ce que quelqu'un aurait une idée de ce problème ?
Je vous met mon code à la suite.
J'espère que la méthode d'insertion est bonne.

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

#define SS_PIN 10

#define RST_PIN 9

#define Led_Rouge_PIN 2

#define Relais_PIN 3

#define EtatAlarme_PIN 4

#define CdeClavier_PIN 5


boolean mem1 = 0;
boolean Etat_Relais;
boolean EtatAlarme;
boolean CdeClavier;
byte Count_acces = 0;
byte CodeVerif = 0;
byte Code_Acces[4] = { 0xB5, 0xF7, 0x32, 0x5F };


MFRC522 rfid(SS_PIN, RST_PIN);  // Instance of the class

// Init array that will store new NUID
byte nuidPICC[4];


void setup() {
 
  // Init SPI bus
  SPI.begin();

  // Init MFRC522
  rfid.PCD_Init();

  // Init broches
  pinMode(Led_Rouge_PIN, OUTPUT);
  pinMode(Relais_PIN, OUTPUT);
  pinMode(EtatAlarme_PIN, INPUT);
  pinMode(CdeClavier_PIN, INPUT);

  digitalWrite(Relais_PIN, HIGH);
}

void loop() {
  EtatAlarme = digitalRead(EtatAlarme_PIN);
  CdeClavier = digitalRead(CdeClavier_PIN);
  Etat_Relais = digitalRead(Relais_PIN);

  if (EtatAlarme == 1) {
    digitalWrite(Led_Rouge_PIN, HIGH);
  }

  else 
  {
    digitalWrite(Led_Rouge_PIN, LOW);
  }
  if (CdeClavier == 1) 
  {
    relais();
  }
  // Initialiser la boucle si aucun badge n'est présent
  if (!rfid.PICC_IsNewCardPresent())
    return;

  // Vérifier la présence d'un nouveau badge
  if (!rfid.PICC_ReadCardSerial())
    return;


  // Enregistrer l’ID du badge (4 octets)
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }

  // Vérification du code
  CodeVerif = GetAccesState(Code_Acces, nuidPICC);
  if (CodeVerif == 1)

  {
  relais();
  }

  else {
    for (int i = 0; i < 3; i++) {
      digitalWrite(Led_Rouge_PIN, HIGH);
      delay(200);
      digitalWrite(Led_Rouge_PIN, LOW);
      delay(200);
    }
  }

  // Re-Init RFID
  rfid.PICC_HaltA();       // Halt PICC
  rfid.PCD_StopCrypto1();  // Stop encryption on PCD
}

byte GetAccesState(byte *CodeAcces, byte *NewCode) {
  byte StateAcces = 0;
  if ((CodeAcces[0] == NewCode[0]) && (CodeAcces[1] == NewCode[1]) && (CodeAcces[2] == NewCode[2]) && (CodeAcces[3] == NewCode[3]))
    return StateAcces = 1;
  else
    return StateAcces = 0;
}
// Fonction commande relais
void relais() {
  if (Etat_Relais = !mem1) {
    digitalWrite(Relais_PIN, LOW);
  } else {
    digitalWrite(Relais_PIN, HIGH);
  }
  mem1 = !mem1;
}

Bonsoir bruno-d

As tu mis une résistance de PULLDOWN sur ton entrée clavier (CdeClavier_PIN)?
Ton fil fait peut-être antenne et collecte des parasites.

Cordialement
jpbbricole

Bonjour jpbbricole.
Merci pour ta contribution mais oui j'ai bien fixé l'entrée 3 avec une résistance de 1kohms sur le négatif. C'est quand j'y amène mon plus que ça mitraille.
Mais avec ce code tout fonctionne bien.

void loop() {
  EtatAlarme = digitalRead(EtatAlarme_PIN);
  CdeClavier = digitalRead(CdeClavier_PIN);
  Etat_Relais = digitalRead(Relais_PIN);

  
  if (CdeClavier == 1) 
  {
    relais();
  }

Il suffit de mettre que ces lignes pour que ça mitraille à nouveau.
Je n'y comprends rien.

   // Initialiser la boucle si aucun badge n'est présent
  if (!rfid.PICC_IsNewCardPresent())
    return;
  }

La résistance de PULLDOWN doit être sur l'entrée 5
#define CdeClavier_PIN 5
l'entrée 3 étant la commande du relais:
#define Relais_PIN 3

Je n'ai pas bien compris ce que tu as voulu faire dans void relais()

A+
Cordialement
jpbbricole

A mon avis c'est plus un problème logiciel mais je suis incapable de chercher plus loin.
Le void relais est une fonction que j'appelle quand je veux commander le relais.
Ça évite d'écrire plusieurs fois les mêmes lignes.
Au début je ne l'avais pas mis et puis j'ai tenté. J'espérais que ça corrige mon problème. On ne sait jamais ...
Mais non :worried:
J'espère que quelqu'un puisse trouver le problème, c'est frustrant ...
Merci.
A+
Bruno D

Cela n'indique pas ce que tu as voulu faire dans la fonction.

if (Etat_Relais = !mem1)

l'opérateur = est une affectation, tu affecte Etat_Relais à l'inverse de mem1, puis tu test cette valeur.
c'est bien ce que tu as voulu faire?
normalement vu que Etat_Relais represente l'état réel de la broche, on suppose que c'est une comparaison que tu voulais faire.

if (Etat_Relais == !mem1)

qui test si Etat_Relais est le contraire de ce qui à était mémoriser.

comme tu as des problème de mitraillette, je suppose que c'est pour essayer d'enrayer ce problème.
Donc cela ne devrait pas être

void relais() {
  if (Etat_Relais) {
    digitalWrite(Relais_PIN, LOW);
  } else {
    digitalWrite(Relais_PIN, HIGH);
  }
}

qui inverse le niveau de la broche Relais_PIN

Si tu as un effet de mitraillette c'est que CdeClavier ou CodeVerif est égale à 1 en permanence
puisque ta fonction alterne la valeur de mem1 et que lorsque mem1 est vrai Relais_PIN est à HIGH et "mem1" est faux, Relais_PIN est à LOW

Juste pour pinailler, lorsque tu utilises une variable de type booléen, il plus cohérent d'utiliser True ou False au lieu de 0 et 1

Bonjour bruno-d

C'est un excellent réflex :wink:

Donc, si j'ai bien compris, tu veux simplement faire tirer le relais, le temps de déverrouiller la porte et, ce avec une carte ou pression sur le clavier?

Si c'est le cas un simple:
tirer le relais
attente 1 seconde
faire tomber le relais
suffit, et ça donne ceci:

// Fonction commande relais
void relais() {
	digitalWrite(Relais_PIN, LOW);
	delay(1000);     // Relais tiré 1 seconde
	digitalWrite(Relais_PIN, HIGH);     // Relais tombé

	//if (Etat_Relais = !mem1) {
		//digitalWrite(Relais_PIN, LOW);
		//} else {
		//digitalWrite(Relais_PIN, HIGH);
	//}
	//mem1 = !mem1;
}

j'ai laissé, en remarques, les lignes devenues inutiles.
Dans le cas de l'usage du clavier, il faut attendre que le clavier soit relâché pour éviter la répétition, tant que pressé, de l'attraction/chute du relais.

	if (digitalRead(CdeClavier_PIN) == 1)     // Si clavier pressé
	{
		relais();
		while(digitalRead(CdeClavier_PIN) == 1)     // Tant que le clavier est pressé
		{}     // On ne fait rien
	}

Ton programme ajusté:

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

#define SS_PIN 10

#define RST_PIN 9

#define Led_Rouge_PIN 2

#define Relais_PIN 3

#define EtatAlarme_PIN 4

#define CdeClavier_PIN 5


//boolean mem1 = 0;
//boolean Etat_Relais;
boolean EtatAlarme;
//boolean CdeClavier;
byte Count_acces = 0;
byte CodeVerif = 0;
byte Code_Acces[4] = { 0xB5, 0xF7, 0x32, 0x5F };


MFRC522 rfid(SS_PIN, RST_PIN);  // Instance of the class

// Init array that will store new NUID
byte nuidPICC[4];


void setup() {
	
	// Init SPI bus
	SPI.begin();

	// Init MFRC522
	rfid.PCD_Init();

	// Init broches
	pinMode(Led_Rouge_PIN, OUTPUT);
	pinMode(Relais_PIN, OUTPUT);
	pinMode(EtatAlarme_PIN, INPUT);
	pinMode(CdeClavier_PIN, INPUT);

	digitalWrite(Relais_PIN, HIGH);
}

void loop() {
	EtatAlarme = digitalRead(EtatAlarme_PIN);
	//CdeClavier = digitalRead(CdeClavier_PIN);
	//Etat_Relais = digitalRead(Relais_PIN);

	if (EtatAlarme == 1) {
		digitalWrite(Led_Rouge_PIN, HIGH);
	}

	else
	{
		digitalWrite(Led_Rouge_PIN, LOW);
	}
	if (digitalRead(CdeClavier_PIN) == 1)     // Si clavier pressé
	{
		relais();
		while(digitalRead(CdeClavier_PIN) == 1)     // Tant que le clavier est pressé
		{}     // On ne fait rien
	}
	// Initialiser la boucle si aucun badge n'est présent
	if (!rfid.PICC_IsNewCardPresent())
	return;

	// Vérifier la présence d'un nouveau badge
	if (!rfid.PICC_ReadCardSerial())
	return;


	// Enregistrer l’ID du badge (4 octets)
	for (byte i = 0; i < 4; i++) {
		nuidPICC[i] = rfid.uid.uidByte[i];
	}

	// Vérification du code
	CodeVerif = GetAccesState(Code_Acces, nuidPICC);
	if (CodeVerif == 1)

	{
		relais();
	}

	else {
		for (int i = 0; i < 3; i++) {
			digitalWrite(Led_Rouge_PIN, HIGH);
			delay(200);
			digitalWrite(Led_Rouge_PIN, LOW);
			delay(200);
		}
	}

	// Re-Init RFID
	rfid.PICC_HaltA();       // Halt PICC
	rfid.PCD_StopCrypto1();  // Stop encryption on PCD
}

byte GetAccesState(byte *CodeAcces, byte *NewCode) {
	byte StateAcces = 0;
	if ((CodeAcces[0] == NewCode[0]) && (CodeAcces[1] == NewCode[1]) && (CodeAcces[2] == NewCode[2]) && (CodeAcces[3] == NewCode[3]))
	return StateAcces = 1;
	else
	return StateAcces = 0;
}
// Fonction commande relais
void relais() {
	digitalWrite(Relais_PIN, LOW);
	delay(1000);     // Relais tiré 1 seconde
	digitalWrite(Relais_PIN, HIGH);     // Relais tombé

	//if (Etat_Relais = !mem1) {
		//digitalWrite(Relais_PIN, LOW);
		//} else {
		//digitalWrite(Relais_PIN, HIGH);
	//}
	//mem1 = !mem1;
}

A+
Cordialement
jpbbricole

Bonjour jpbbricole et terwal.
Grace à vos réflexions j'ai enfin résolu mon problème.
Pour bien comprendre le fonctionnement.
Je veux faire fonctionner en télérupteur.
Avec mon badge RFID, une fois le relais colle, une fois il décolle.
Idem avec mon clavier qui ferme un contact pendant 1s.
Je rentre le code sur mon clavier le relais colle.
J'entre à nouveau le code sur le clavier pour que le relais décolle.
Terwal, le truc de la mémoire je l'avais trouvé sur d'autres exemples et je suis d'accord avec toi il suffirait de vérifier l'état du relais et faire la commande inverse.
Mais ça ne fonctionne pas et je ne me l'explique pas bien encore.
En fait j'ai ajouté un délai de 1500ms avant la mise à jour de ma mémoire.
Le temps que j'y amène une polarité sur mon entrée puis que je l'enlève.
Le code n'est certainement pas très "propre" mais en tout cas ça fonctionne parfaitement comme je le voulais.
Merci beaucoup à vous deux.
A+
Bruno D

Bonjour bruno-d

Dommage que l'on ait pas eu toute cette explication dès le début :wink: mais super que cela fonctionne.

Bonne continuation!

Cordialement
jpbbricole

Bonjour
Un dernier message avant de clore le sujet.
Désolé si mes explications n'étaient pas assez claires dès le départ.
J'ai re travaillé un peu sur le sujet et j'ai réussi à me débarrasser de cette mem1.
Je mets le code en entier pour ceux qui voudraient s'en inspirer.
Encore merci à Terwal et Jpbbricole pour leur aide précieuse.
A bientôt sur le forum
Bruno D

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

#define SS_PIN 10

#define RST_PIN 9

#define Led_Rouge_PIN 2

#define Relais_PIN 3

#define EtatAlarme_PIN 4

#define CdeClavier_PIN 5


boolean Etat_Relais;
boolean EtatAlarme;
boolean CdeClavier;
byte Count_acces = 0;
byte CodeVerif = 0;
byte Code_Acces[4] = { 0xB5, 0xF7, 0x32, 0x5F };


MFRC522 rfid(SS_PIN, RST_PIN);  // Instance of the class

// Init array that will store new NUID
byte nuidPICC[4];


void setup() {
 
  // Init SPI bus
  SPI.begin();

  // Init MFRC522
  rfid.PCD_Init();

  // Init broches
  pinMode(Led_Rouge_PIN, OUTPUT);
  pinMode(Relais_PIN, OUTPUT);
  pinMode(EtatAlarme_PIN, INPUT);
  pinMode(CdeClavier_PIN, INPUT);

  digitalWrite(Relais_PIN, HIGH);
}

void loop() {
  EtatAlarme = digitalRead(EtatAlarme_PIN);
  CdeClavier = digitalRead(CdeClavier_PIN);
  Etat_Relais = digitalRead(Relais_PIN);

  if (EtatAlarme == true) {
    digitalWrite(Led_Rouge_PIN, HIGH);
  }

  else 
  {
    digitalWrite(Led_Rouge_PIN, LOW);
  }
  if (CdeClavier == 1) 
  {
    relais();
  }
  // Initialiser la boucle si aucun badge n'est présent
  if (!rfid.PICC_IsNewCardPresent())
    return;

  // Vérifier la présence d'un nouveau badge
  if (!rfid.PICC_ReadCardSerial())
    return;


  // Enregistrer l’ID du badge (4 octets)
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }

  // Vérification du code
  CodeVerif = GetAccesState(Code_Acces, nuidPICC);
  if (CodeVerif == 1)

  {
  relais();
  }

  else {
    for (int i = 0; i < 3; i++) {
      digitalWrite(Led_Rouge_PIN, HIGH);
      delay(200);
      digitalWrite(Led_Rouge_PIN, LOW);
      delay(200);
    }
  }

  // Re-Init RFID
  rfid.PICC_HaltA();       // Halt PICC
  rfid.PCD_StopCrypto1();  // Stop encryption on PCD
}

byte GetAccesState(byte *CodeAcces, byte *NewCode) {
  byte StateAcces = 0;
  if ((CodeAcces[0] == NewCode[0]) && (CodeAcces[1] == NewCode[1]) && (CodeAcces[2] == NewCode[2]) && (CodeAcces[3] == NewCode[3]))
    return StateAcces = 1;
  else
    return StateAcces = 0;
}
// Fonction commande relais
void relais() {
  if (Etat_Relais == true) {
    digitalWrite(Relais_PIN, LOW);
  } else {
    digitalWrite(Relais_PIN, HIGH);
  }
  delay (1500);
 
}
````Texte préformaté`

Bonjour bruno-d

Un dernier petit truc pour inverser ton relais:

// Fonction commande relais
void relais() {
	digitalWrite(Relais_PIN, !digitalRead(Relais_PIN));

	delay (1500);
}

On y écrit, l'inverse (! = NOT) de ce que l'on y lit.

Bonne continuation!
Cordialement
jpbbricole

Bonjour Jpbbricole.
Super cette commande.
Un relais qui fonctionne en bistable sur une seule ligne.
Bravo.
Du coup j'ai un peu honte d'avoir créé un Void pour si peu de texte.
Merci et bon week end à toi.
Bruno-D

Non, il ne faut pas, si tu as besoin de l'état à plusieurs endroit, ton code était tout indiqué.
De même si tu as besoin de changer l'état à des endroits différent, la fonction est alors tout indiqué

Bonsoir bruno-d

Je suis du même avis que @terwal.
Ce n'est pas une question de quantité de texte, mais de pratique, si tu veux modifier l'action du relais, tu n'as qu'un endroit où corriger.
Perso, dès qu'une paire ou plus de "choses" doivent être exécutées plusieurs fois, c'est systématique, je crée une fonction (presque toujours :wink:)

Bonne soirée
Cordialement
jpbbricole

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