Arduino mega WIEGAND 4Dsystems 70DT-screen

Hello,

I have an arduino mega, a 4D systems 70-DT screen and its adaptor shield (7.0", 800x480 pixels, Intelligent TFT-LCD Module with embedded Diablo16 processor) and a 13.56 Mhz MIFARE reader (https://stid-security.com/images/produits/telechargements/commun/Gamme_Architect_FR.pdf). The cards used are coded in 32 bits and the reader dialogs in WIEGAND.
The reader dialogs with the Arduino through 4 wires : 5V, GND, DATA1 (connected pin3 of the Arduino) and DATA0(pin2).

The reader’s GND is connected to the Arduino’s, the screen’s and the external power supply’s GND.

What I want my project to look like : X passes his card in front of the reader. Once identified, screen asks him if he wants to open lock 1 or lock 2, then sends 5V voltage to the wanted lock in order to open the locker.

I have a code to read the card’s number, and it works fine - I get the right card number. Here it is :

#define MAX_BITS 100                 // nombre maximum de bits
#define WEIGAND_WAIT_TIME  3000      // temps à attendre pour une nouvelle pulsation WIEGAND

unsigned char databits[MAX_BITS];    // Stock tous les bits
unsigned char bitCount;              // Nombre de bit comptés
unsigned char flagDone;              
unsigned int weigand_counter;        

unsigned long cardCode=0;            // code de la carte

// Fonctions déinitialisation

void ISR_INT0()  //Permet de compter les "1" envoyés
{
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME; 
 
}


void ISR_INT1()   // Permet de compter les "0" envoyés
{
  databits[bitCount] = 1;
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME; 
}

void setup()
{
  pinMode(2, INPUT_PULLUP);      // Sur le pin 2 de l'Arduino, nous recevons les "0" envoyés
  pinMode(3, INPUT_PULLUP);      // Sur le pin 3 de l'Arduino, nous recevons les "1" envoyés
 
  Serial.begin(9600);
  attachInterrupt(0, ISR_INT0, FALLING); 
  attachInterrupt(1, ISR_INT1, FALLING);
 

  weigand_counter = WEIGAND_WAIT_TIME;
}

void loop()
{
  if (!flagDone) {
    if (--weigand_counter == 0)
      flagDone = 1;  
  }
 
  if (bitCount == 32 && flagDone) {
    unsigned char i;

      for (i=2; i<31; i++)
      {
         cardCode <<=1;
         cardCode |= databits[i];     
      }
     
      printBits();
    }
    

     // réinitialisation
     bitCount = 0;
     cardCode = 0;
     for (i=0; i<MAX_BITS; i++)
     {
       databits[i] = 0;
     }
  }
}

void printBits()
{
      Serial.print("Le code de la carte est ");
      Serial.println(cardCode);
}

I have tried using it and modifying it a bit into a larger code to satisfy what I want my project to finally look like. However, when I run the program, the screen displays the user to pass his card correctly, however when I pass the card, nothing happens?? I think there might be a code problem. I have tried looking through it with 4Dsystems (the screen’s supplier) but they see nothing wrong in the program. I can’t see what’s the problem ? I have attached the code to this post.

Any help would be appreciated !

28_JUNE.ino (6.23 KB)

void conditions()
{
  if (cardCode == 26741719)
  {
    nom = "Oumy";
  }
  else if ( cardCode == 26759498)
  {
    nom = "Francois";
  }
}

So 'nom' is not set if the number doesn't match one of the two you are looking for?

void affichage(void)
{
  Display.gfx_BGcolour(LIGHTGOLD) ;
  Display.gfx_Cls() ;
  Display.txt_BGcolour(LIGHTGOLD) ;
  Display.txt_FGcolour(BLACK) ;
  Display.print(" ");
  Display.print("Bonjour"); //It doesn't happen !
  Display.print(" ");

Try using a different background color from the previous screen. Does the screen change to the new background color?

Declare the variables used in the ISRs as volatile, and temporarily disable interrupts when accessing weigand_counter in the main code, because it is a multi-byte variable and an interrupt can occur between byte accesses.

david_2018:
Declare the variables used in the ISRs as volatile, and temporarily disable interrupts when accessing weigand_counter in the main code, because it is a multi-byte variable and an interrupt can occur between byte accesses.

Thank you ! I have tried declaring the variable as volatile, could you tell me if that's the correct way to do it ?
:

volatile unsigned char databits[MAX_BITS]; // stock les données des bits
volatile unsigned char bitCount; // nombre de bits stockés
volatile unsigned char flagDone; // est égale à 0 quand une donnée et en cours de "stockage"
volatile unsigned int weigand_counter; // countdown until we assume there are no more bits

Or am I missing some more variables that I need to declare as volatile ?

I am not sure how to temproriraly disable interrupts, I have tried this in the main loop :

void loop() {
if (!flagDone) {
   noInterrupts();
if (--weigand_counter == 0) {
flagDone = 1;
}}

unsigned char i;

interrupts();
if (bitCount == 32 && flagDone) {

I have modified the code to add these two new additions but nothing happened. Maybe I'm coding wrong - in this case could you please show me the right way around ? Thank you!!

johnwasser:

void conditions()

{
  if (cardCode == 26741719)
  {
    nom = “Oumy”;
  }
  else if ( cardCode == 26759498)
  {
    nom = “Francois”;
  }
}





So 'nom' is not set if the number doesn't match one of the two you are looking for?

void affichage(void)
{
Display.gfx_BGcolour(LIGHTGOLD) ;
Display.gfx_Cls() ;
Display.txt_BGcolour(LIGHTGOLD) ;
Display.txt_FGcolour(BLACK) ;
Display.print(" ");
Display.print("Bonjour"); //It doesn't happen !
Display.print(" ");[/code]
Try using a different background color from the previous screen. Does the screen change to the new background color?

Hello, thank you for your reply !! You are right about nom, thank you for underlying the problem! I have modified the code to this :

void conditions()
{
if (cardCode == 26741719) {
nom = "Oumy";
}

else if ( cardCode == 26759498) {
nom = "Francois";
}
}

void affichage(void) {
  if (nom == "Oumy" || nom == "Francois")
  {
Display.gfx_BGcolour(BLUE) ; 
Display.gfx_Cls() ;
Display.txt_BGcolour(BLUE) ;
Display.txt_FGcolour(BLACK) ;
Display.print(" ");
Display.print("Bonjour"); //It doesn't happen !
Display.print(" ");
Display.print(nom);
//Display.putstr(nom);
Display.print(".");
Display.print(" ");
Display.print("Quel est le numero du casier que vous souhaitez emprunter ?") ;
Display.gfx_BevelShadow(3) ; // make it really dark
Display.gfx_BevelWidth(20) ; // make the button bigger by increasing the bevel size for (i = 1; i <= 10; i++) { Display.gfx_Button(ON, 120,50, BLUE, WHITE, FONT3, 1, 1, "Smile") ;
delay(100) ;
Display.gfx_Button(OFF, 120,200, BLUE, WHITE, FONT3, 1, 1, "1") ;
delay(100);
Display.gfx_Button(OFF, 500, 200, BLUE, WHITE, FONT3, 1, 1, "2") ;
delay(100) ;
Display.touch_Set(TOUCH_ENABLE);}
else 
{
 Display.gfx_BGcolour(BLUE) ; 
 Display.gfx_Cls() ;
 Display.txt_BGcolour(BLUE) ;
 Display.txt_FGcolour(BLACK) ;
 Display.print(" ");
  Display.print("Utilisateur non reconnu"); 
}
}

As you can see, I have also tried using a different background color from the previous screen (from Lightgold to Blue). Howerver, the screen doesn’t change to the new background color and I still have the same problem as before.

oumaima_h:
As you can see, I have also tried using a different background color from the previous screen (from Lightgold to Blue). Howerver, the screen doesn't change to the new background color and I still have the same problem as before.

If the screen background doesn't change, that would indicate that affichage() never gets called. What does Serial Monitor show? You should add more Serial.println() messages to better track the flow of control. Perhaps at the beginning and end of functions and inside the 'if' statements.