Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. French
  4. Problème en lecture/écriture de badge RFID mifare classic avec Raspberry et CR038
Forum Updated to NodeBB v4.3 + New Features

Problème en lecture/écriture de badge RFID mifare classic avec Raspberry et CR038

Scheduled Pinned Locked Moved Unsolved French
30 Posts 4 Posters 7.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jym92
    wrote on last edited by
    #1

    Bonjour à tous,

    je travaille actuellement sur la lecture/écriture de badges RFID mifare classic et pour cela j'ai à ma disposition une Raspberry pi 4 sous raspbian et un module RFID le CR058 (les deux sont reliés en série via un ftdi usb pour convertir les niveaux en tension).

    lien module RFID CR038 :

    Pour finir je programme une application C++ via QTcreator car la lecture badge rfid fait partie d'un projet plus grand déja initié sous QTcreator.

    Pour réaliser le code, je me suis beaucoup inspiré du code arduino fourni par le constructeur :

    char button_1 = 10;  //Define pin 10 as button_1
    char button_2 = 11;  //Define pin 11 as button_2
     
    /*****MiFare commands*****/
    char LED_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x01,0x07};  //Command to turn on MiFare module onboard LED
    char LED_OFF[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x00,0x06}; //Command to turn off MiFare module onboard LED
    char ANTENNA_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x0C,0x01,0x01,0x0C};  //Command to turn off MiFare module onboard antenna
    char READ_DEV[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x03,0x01,0x02};  //Command to read MiFare module device number
    char CARD_REQ[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x01,0x02,0x52,0x51};  //Command to request card type of MiFare card 
    char ANTI_COL[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x02,02,00};  //Command for anti-collision
    char CARD_SEL[] = {0xAA,0xBB,0x09,0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00};  //Command to select specific MiFare card for access
                                                                                           //Byte 0 to byte 12 of this command is initialized with 0x00, since have to obtain the NUID of the MiFare card scanned 
                                                                                           //Byte 8 to byte 11 of this command will filled with NUID (started with the lowest byte) of the MiFare card desire to access
                                                                                           //Byte 12 of this command is checksum from byte 4 to byte 11 of this command may change for NUID different from that in this case
                                                                                           //This array will be filled during the subroutine of the get_nuid() in this program       
    char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65};  //Command to authenticate Sector 0 in memory of MiFare card
    char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x61};  //Command to authenticate Sector 1 in memory of MiFare card
    char READ_0[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x00,0x0A};  //Command to read Block 0 (manufacturer block in Sector 0) in memory of MiFare card
    char WRITE_4[] = {0xAA,0xBB,0x16,0x00,0x00,0x00,0x09,0x02,0x04,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F}; //Command to write data into Block 4 (in Sector 1) in memory of MiFare card
                                                                                                                                                          //Data to be written (started with the lowest byte) is from byte 9 to 24, 
                                                                                                                                                          //total of 16 bytes data
                                                                                                                                                          //Data is 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A
                                                                                                                                                          //0x0B,0x0C,0x0D,0x0E,0x0F in this case
                                                                                                                                                          //The last checksum byte of this command may change for data to written different from 
                                                                                                                                                          //that in this case
    char READ_4[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x04,0x0E};  //Command to read data in Block 4 (in Sector 1) in memory of MiFare card
    /*****************************/
     
    unsigned char reply_buffer[26]; //Buffer to store data received from MiFare module when a certain command is sent (maximum is 26 bytes in this case)
    unsigned char NUID[4];  //Array for storing NUID of a MiFare card
    char mode = 0;  //Variable storing current mode of the program 
     
    void setup()
    {
      pinMode(button_1,INPUT);  //Configure pins button_1 & button_2 as inputs
      pinMode(button_2,INPUT); 
      digitalWrite(button_1,HIGH);  //Pull-up pins button_1 & button_2 
      digitalWrite(button_2,HIGH);  
     
      Serial.begin(19200);  //Initiallize UART serial communication with baudrate = 19200bps (default baudrate of MiFare module)
      lcd.begin(8,2);  //Initialize the lcd object created as type 2 rows x 8 column
     
      lcd.print("MiFare");  //Print welcome message "MiFare Demo" on LCD  
      lcd.setCursor(0,1);
      lcd.print("Demo");
      delay(2000);
      lcd.clear();
    }
     
    void loop()
    {
      lcd.setCursor(0,0);
      switch(mode)  
      {
         case 0:
         //Blinking of the MiFare module onboard LED in at rate of 0.5 Hertz
           lcd.print("0.LED    ");
           if(!digitalRead(button_2))
           {
               while(!digitalRead(button_2));  
               while(1)
               {
                 lcd.setCursor(0,1);
                 lcd.print("LED ON ");
                 led_on();      
                 delay(1000);  
                 lcd.setCursor(0,1);
                 lcd.print("LED OFF");
                 led_off();
                 delay(1000); 
               }
            }
            break;
     
          case 1:
          //Read the device number of MiFare module
            lcd.print("1.DEV NO"); 
            if(!digitalRead(button_2))
            {
                while(!digitalRead(button_2));
                read_dev();
                lcd.setCursor(0,1);
                lcd_to_hex(reply_buffer[10]);  //Byte 9 and byte 10 of replied bytes (started with lowest byte)contains MiFare module device number
                lcd_to_hex(reply_buffer[9]);
                while(1);
            }
            break;
     
           case 2:
           //Read the NUID of MiFare card 
             lcd.print("2.NUID    ");
             if(!digitalRead(button_2))
             {
                while(!digitalRead(button_2));
                get_nuid();  //NUID of MiFare card  is stored in NUID[] array after execution of this subroutine 
                             //There is total of 4 bytes started with the lowest byte
                lcd.setCursor(0,1);
                for(int i = 3; i>=0; i--)
                {
                   lcd_to_hex(NUID[i]);  //Print out the NUID obtained on LCD
                }
                while(1);
             }
             break;
     
           case 3:
           //Read the data stored in Block 0 in Sector 0 in memory of MiFare card 
             lcd.print("3.READ0   ");
             if(!digitalRead(button_2))
             {
                while(!digitalRead(button_2));
                read_0();
                while(1)
                {
                  //Byte 9 to byte 24  of the replied bytes contains data (started with the lowest byte) read from Block 0 in Sector 0
                  //Due to the small screen of the LCD used, the data is printed on LCD for twice. The lower 8 bytes (started with lowest byte of the lower 8 bytes) is printed at the first time
                  //While the upper 8 bytes (started with lowest byte of the upper 8 bytes)is printed at the second time.
                  lcd.clear();
                  lcd.setCursor(0,0);
                  lcd.print("0 to 7");
                  lcd.setCursor(0,1);
                  lcd.print("byte");
                  delay(2000);
                  lcd.clear();
                  lcd.setCursor(0,0);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[9+i]); 
                  }
                  lcd.setCursor(0,1);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[13+i]); 
                  }
                  delay(5000); 
                  lcd.clear();
                  lcd.setCursor(0,0);
                  lcd.print("8 to 15");
                  lcd.setCursor(0,1);
                  lcd.print("byte");
                  delay(2000);
                  lcd.clear();
                  lcd.setCursor(0,0);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[17+i]); 
                  }
                  lcd.setCursor(0,1);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[21+i]); 
                  }
                  delay(5000);
                }
             }
             break;
           case 4:
           //Write data into Block 4 in Sector 1 in memory of MiFare card 
             lcd.print("4.WRT_4 ");
             if(!digitalRead(button_2))
             {
                while(!digitalRead(button_2));
                write_4();
                lcd.setCursor(0,1);
                lcd.print("Success!");  //Print "Success" on LCD to indicate a success write
                while(1);
             }
             break;
           case 5:
           //Read the data stored in Block 4 in Sector 1 in memory of MiFare card 
             lcd.print("5.READ_4");
             if(!digitalRead(button_2))
             {
                while(!digitalRead(button_2));
                read_4();
                while(1)
                {
                  //Byte 9 to byte 24  of the replied bytes contains data (started with the lowest byte) read from Block 4 in Sector 1
                  //Due to the small screen of the LCD used, the data is printed on LCD for twice. The lower 8 bytes (started with lowest byte of the lower 8 bytes) is printed at the first time
                  //While the upper 8 bytes (started with lowest byte of the upper 8 bytes) is printed at the second time
                  lcd.clear();
                  lcd.setCursor(0,0);
                  lcd.print("0 to 7");
                  lcd.setCursor(0,1);
                  lcd.print("byte");
                  delay(2000);
                  lcd.clear();
                  lcd.setCursor(0,0);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[9+i]); 
                  }
                  lcd.setCursor(0,1);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[13+i]); 
                  }
                  delay(5000);
                  lcd.clear();
                  lcd.setCursor(0,0);
                  lcd.print("8 to 15");
                  lcd.setCursor(0,1);
                  lcd.print("byte");
                  delay(2000);
                  lcd.clear();
                  lcd.setCursor(0,0);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[17+i]); 
                  }
                  lcd.setCursor(0,1);
                  for(int i = 0; i<4; i++)
                  {
                     lcd_to_hex(reply_buffer[21+i]); 
                  }
                  delay(5000);
                }
             }
             break;
           default: break;      
      }
     
      if(!digitalRead(button_1))  //Detect the pressing down of button_1, change mode accordingly 
      {
         while(!digitalRead(button_1));
         mode++;
         if(mode > 5)  
         {
           mode = 0;
         } 
      }
    }
     
    //Turn on MiFare module LED subroutine
    void led_on(void)
    {
      for(int i = 0; i<10; i++)
      {
        Serial.write(LED_ON[i]); 
      }
     
      for(int i = 0; i<10; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      } 
    }
     
    //Turn on MiFare module LED subroutine
    void led_off(void)
    {
      for(int i = 0; i<10; i++)
      {
        Serial.write(LED_OFF[i]); 
      }
     
      for(int i = 0; i<10; i++)
      {
        while(!Serial.available());
        reply_buffer[i] = Serial.read();
      }
    }
     
    //Read MiFare device number subroutine
    void read_dev(void)
    {
      for(int i = 0; i<9; i++)
      {
        Serial.write(READ_DEV[i]); 
      }
     
      for(int i = 0; i<12; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }    
    }
     
    //Turn on antenna of MiFare module subroutine
    void antenna_on(void)
    {
      for(int i = 0; i<10; i++)
      {
        Serial.write(ANTENNA_ON[i]); 
      }
     
      for(int i = 0; i<10; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }  
    }
     
    //Request MiFare card type subroutine
    void card_req(void)
    {
      for(int i = 0; i<10; i++)
      {
        Serial.write(CARD_REQ[i]); 
      }
     
      for(int i = 0; i<12; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }   
    }
     
    //Perform Anti-Collison subroutine
    void anti_col(void)
    {
      for(int i = 0; i<9; i++)
      {
        Serial.write(ANTI_COL[i]); 
      }
     
      for(int i = 0; i<14; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      } 
     
      //Byte 9 to byte 12 of replied bytes contains NUID of the MiFare card 
      //Store them in NUID[] array
      for(int i = 0; i<4; i++)
      {
          NUID[i] = reply_buffer[9+i];
      }
    }
     
    //Select MiFare card subroutine
    void card_sel(void)
    {
      for(int i = 0; i<13; i++)
      {
        Serial.write(CARD_SEL[i]); 
      }
     
      for(int i = 0; i<11; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }   
    }
     
    //Authenticate Sector 0 in memory of MiFare card subroutine
    void authen_sec0(void)
    {
      for(int i = 0; i<17; i++)
      {
        Serial.write(AUTHEN_SEC0[i]); 
      }
     
      for(int i = 0; i<10; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }   
    }
     
    //Authenticate Sector 1 in memory of MiFare card subroutine
    void authen_sec1(void)
    {
      for(int i = 0; i<17; i++)
      {
        Serial.write(AUTHEN_SEC1[i]); 
      }
     
      for(int i = 0; i<10; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }   
    }
     
    //Read data from Block 0 (manufaturer block) in memory of MiFare card subroutine
    void read_0 (void)
    {
      get_nuid();
      card_sel();  //Select MiFare card 
      authen_sec0();  //Authenticate Sector 0 in memory of MiFare card
      for(int i = 0; i<10; i++)
      {
        Serial.write(READ_0[i]); 
      }
     
      for(int i = 0; i<26; i++)
      {
        while(!Serial.available());
        reply_buffer[i] = Serial.read(); 
      }
    }
     
    //Read data from Block 4 in memory of MiFare card subroutine
    void read_4(void)
    {
      get_nuid(); 
      card_sel();  //Select MiFare card 
      authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
      for(int i = 0; i<10; i++)
      {
        Serial.write(READ_4[i]); 
      }
     
      for(int i = 0; i<26; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }  
    }
     
    //Write data into from Block 4 in memory of MiFare card subroutine
    void write_4(void)
    {
      get_nuid();
      card_sel();  //Select MiFare card 
      authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
      for(int i = 0; i<26; i++)
      {
        Serial.write(WRITE_4[i]); 
      }
     
      for(int i = 0; i<10; i++)
      {
         while(!Serial.available());
         reply_buffer[i] = Serial.read();
      }   
    }
     
    //Get NUID of MiFare card subroutine
    void get_nuid(void)
    {
      unsigned char xor_temp = 0;
      antenna_on();  //On the MiFare module onboard antenna
      card_req();  //Request card type of MiFare card 
      anti_col();  //Perform anti-collision
     
      for(int i = 0; i<4; i++)  //Fill up byte 8 to byte 11 of CARD_SEL[] with NUID 
      {
         CARD_SEL[i+8] = NUID[i]; 
      }
     
      for(int i = 0; i<8; i++)  //Calculate the checksum of byte 4 to byte 11 of the CARD_SEL[] 
      {
        xor_temp ^= CARD_SEL[4+i];
      }
      CARD_SEL[12] = xor_temp; //Fill the checksum in byte 12 of CARD_SEL[]
    }
     
    //Print byte as hex numbers on LCD subroutine
    void lcd_to_hex(unsigned char byte_receive)
    {
      unsigned char byte_temp = 0;
      byte_temp = (byte_receive>>4) & 0x0F;
      lcd.print(byte_temp,HEX);
      byte_temp = byte_receive & 0x0F;
      lcd.print(byte_temp,HEX);
    }
    

    Dans les fonctions de base tels éteindre et allumer les leds fonctionnent bien ! Donc la communication fonctionne !

    j'ai écris les fonctions de la manière suivante :

    //*******************************************
    //Select MiFare card subroutine
    void card_sel(void)
    {
      QByteArray da(CARD_SEL, sizeof(CARD_SEL));
      serialRFID->write(da);
      //delay(200)
     
      QByteArray ba;
      while(!serialRFID->isOpen());
      ba = serialRFID->readAll();
      qDebug() << "reception CARD_SEL :" << ba;
     
     
    }
     
    //*******************************************
    //Authenticate Sector 0 in memory of MiFare card subroutine
    void authen_sec0(void)
    {
      QByteArray da(AUTHEN_SEC0, sizeof(AUTHEN_SEC0));
      serialRFID->write(da);
      //delay(200)
      QByteArray ba;
      while(!serialRFID->isOpen());
      ba = serialRFID->readAll();
      qDebug() << "reception AUTHEN_SEC0 :" << ba;
     
    }
     
    //*******************************************
    //Authenticate Sector 1 in memory of MiFare card subroutine
    void authen_sec1(void)
    {
      QByteArray da(AUTHEN_SEC1, sizeof(AUTHEN_SEC1));
      serialRFID->write(da);
      //delay(200)
     
      QByteArray ba;
      while(!serialRFID->isOpen());
      ba = serialRFID->readAll();
      qDebug() << "reception AUTHEN_SEC1 :" << ba;
     
     
    }
     
    //*******************************************
    //Read data from Block 0 (manufaturer block) in memory of MiFare card subroutine
    void read_0 (void)
    {
      get_nuid();
      card_sel();  //Select MiFare card
      authen_sec0();  //Authenticate Sector 0 in memory of MiFare card
     
      QByteArray da(READ_0, sizeof(READ_0));
      serialRFID->write(da);
      //delay(200)
      QByteArray ba;
      while(!serialRFID->isOpen());
      ba = serialRFID->readAll();
      qDebug() << "reception READ_0 :" << ba;
     
    }
    

    Et le problème que j'ai c'est que vu j'utilise la fonction QTserialport "readAll()", je n'ai aucun moyen de fixer la taille de ce que je veux récupérer et du coup je reçoit que certaines réponses à mes commandes et bien souvent pas la correspondante à ma commande. Car les commandes sont souvent envoyé rapidement à la suite (exemple: read_0 envoi 5 commandes) et du coup cela mets le bazard... et je ne reçois qu'une réponse à la dernière lecture de réponse....

    Du coup j'aimerai créer des fonctions Qt plus proches de celles utiliser par l'arduino donc en lisant et écrivant caractère par caractère....

    Y-a t'il un moyen pour lire les caractère un par un sur le port série ? existe t-il une alternatve à "readAll" ?

    Avez-vous déja utiliser un module RFID mifare sous Qt en c++ ?

    Avez-vous des idées pour résoudre mon problème ?

    Merci d'avance pour réponses !

    ps: n'hésitez à me demander des précisions si besoin ;)

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Bonjour et bienvenue sur devnet,

      Le fonctionnement par défauts de QSerialPort est asynchrone et là il est utilisé de manière synchrone.

      Je recommande d'aller lire les examples de QSerialPort en particulier ceux notés "blocking".

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jym92
        wrote on last edited by
        #3

        Bonjour et merci de ta réponse !

        j'ai essayé de mettre en place le fonctionnement synchrone avec un thread, je bataille toujours dessus mais cela me semble très compliqué pour pas grand chose....

        En effet utilisé un thread et une une manière synchrone de lecture de port série pour lire une réponse à une commande qu'on envoi de manière périodique dont on connait la taille ne devrait pas être si complexe...

        A noter: la lecture RFID avec ce module a déjà était mise en place sous Arduino et sous PIC via une simple communication série asynchrone avec une lecture des réponses caractères par caractères !

        Pour ma part je suis issue du monde de l'embarqué et la commande " ReadAll() ", qui lit tout le contenu reçu sans s'occuper ou même si le port série est dispo ou si il reçoit encore des choses me parait trop simpliste pour le coup ....

        Y'aurai pas un entre deux ? basé sur une communication asynchrone mais qui vérifie que le port série est bien dispo et que personne n'écrit dedans ?
        et si possible avec une lecture caractère par caractère...

        Je m'excuse pour mes questions mais je suis un peux neuf dans le domaine QT ;)

        après si vous avez d'autres idées pour résoudre mon problème je suis preneur !

        merci d'avance !

        KroMignonK 1 Reply Last reply
        0
        • J jym92

          Bonjour et merci de ta réponse !

          j'ai essayé de mettre en place le fonctionnement synchrone avec un thread, je bataille toujours dessus mais cela me semble très compliqué pour pas grand chose....

          En effet utilisé un thread et une une manière synchrone de lecture de port série pour lire une réponse à une commande qu'on envoi de manière périodique dont on connait la taille ne devrait pas être si complexe...

          A noter: la lecture RFID avec ce module a déjà était mise en place sous Arduino et sous PIC via une simple communication série asynchrone avec une lecture des réponses caractères par caractères !

          Pour ma part je suis issue du monde de l'embarqué et la commande " ReadAll() ", qui lit tout le contenu reçu sans s'occuper ou même si le port série est dispo ou si il reçoit encore des choses me parait trop simpliste pour le coup ....

          Y'aurai pas un entre deux ? basé sur une communication asynchrone mais qui vérifie que le port série est bien dispo et que personne n'écrit dedans ?
          et si possible avec une lecture caractère par caractère...

          Je m'excuse pour mes questions mais je suis un peux neuf dans le domaine QT ;)

          après si vous avez d'autres idées pour résoudre mon problème je suis preneur !

          merci d'avance !

          KroMignonK Offline
          KroMignonK Offline
          KroMignon
          wrote on last edited by
          #4

          @jym92 Bonjour, je comprends tout à fait ce sentiment, quand on travaille surtout sur des "systèmes restreints", et je présume essentiellement en C ANSI, le fait d'utiliser une API C++ comme Qt peut surprendre.
          QSerialPort::readAll() est capable de savoir tout seul que je port est ouvert et que des données sont présentes.

          La base de Qt est la notion de Signals/Slots, et tout repose la dessus. C'est très important à comprendre. C'est un pli à prendre, et après tout roule (plus ou moins ;) ).

          Pour que la classe QSerialPort fonctionne, il faut laisser la possibilité de traiter les signaux en attente, on ne peut pas boucler comme une brute, c'est contraire au mode de fonctionnement de Qt tout simplement.
          Il faut "donner du temp" pour traiter les événements, par exemple avec un appel du type:

          QThread::currentThread()->eventDispatcher()->processEvents(QEventLoop::AllEvents);
          

          Est-ce que vous avez un extrait de code à monter pour nous détailler ce qui ne vas pas?

          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jym92
            wrote on last edited by jym92
            #5

            bonjour,

            effectivement je travaille souvent en C embarqué ou alors carrement en c#(application mobile) ...

            ok je vois donc je devrais pouvoir utilisé readAll() pour faire ce dont j'ai besoin.

            Mais repartons depuis le debut pour expliquer ce que je recherche...

            Je voudrais mettre au point un Thread RFID indépendant qui aurait pour de rôle de scanner en permanence la présence de carte RFID et de remonter leurs contenus grâce a des variables globales dans le reste du projet.
            Sur le papier ça devrait fonctionner parfaitement surtout en mode asynchrone vu le peu de chose qu'il y a à faire....

            donc voila le code de mon Thread RFID :

            /*********************************************************************
                                RFID THRED In I2C mode
            ********************************************************************/
            #include <QtGui>
            #include <string.h>
            #include "RFIDthread.h"
            #include <wiringPi.h>
            #include "global.h"
            #include <QDebug>
            #include <math.h>
            #include <iostream>
            #include <cstdint>
            #include <cstring>
            #include <stdio.h>
            #include <stdint.h>
            #include <stdbool.h>
            #include <QtSerialPort/QSerialPort>
            #include <QSerialPortInfo>
            
            #include <mainwindow.h>
            
            
            static QSerialPort* serialRFID;
            
            /***********************************************  MiFare commands  *********************************************************/
            static char INIT_BAUD[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x01,0x01,0x03,0x03}; // init command to set baud at 19200
            static char LED_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x01,0x07};  //Command to turn on MiFare module onboard LED
            static char LED_OFF[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x00,0x06}; //Command to turn off MiFare module onboard LED
            static char ANTENNA_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x0C,0x01,0x01,0x0C};  //Command to turn off MiFare module onboard antenna
            static char READ_DEV[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x03,0x01,0x02};  //Command to read MiFare module device number
            static char CARD_REQ[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x01,0x02,0x52,0x51};  //Command to request card type of MiFare card
            static char ANTI_COL[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x02,02,00};  //Command for anti-collision
            static char CARD_SEL[] = {0xAA,0xBB,0x09,0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00};  //Command to select specific MiFare card for access
                                                                                                   //Byte 0 to byte 12 of this command is initialized with 0x00, since have to obtain the NUID of the MiFare card scanned
                                                                                                   //Byte 8 to byte 11 of this command will filled with NUID (started with the lowest byte) of the MiFare card desire to access
                                                                                                   //Byte 12 of this command is checksum from byte 4 to byte 11 of this command may change for NUID different from that in this case
                                                                                                   //This array will be filled during the subroutine of the get_nuid() in this program
            //static char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65};  //Command to authenticate Sector 0 in memory of MiFare card
            //static char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x61};  //Command to authenticate Sector 1 in memory of MiFare card
            
            static char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0x45,0x52,0x41,0x46,0x49,0x4D,0x65};  //Command to authenticate Sector 0 in memory of MiFare card
            static char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0x4D,0x49,0x46,0x41,0x52,0x45,0x61};
            
            static char READ_0[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x00,0x0A};  //Command to read Block 0 (manufacturer block in Sector 0) in memory of MiFare card
            static char WRITE_4[] = {0xAA,0xBB,0x16,0x00,0x00,0x00,0x09,0x02,0x04,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F}; //Command to write data into Block 4 (in Sector 1) in memory of MiFare card
                                                                                                                                                                  //Data to be written (started with the lowest byte) is from byte 9 to 24,
                                                                                                                                                                  //total of 16 bytes data
                                                                                                                                                                  //Data is 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A
                                                                                                                                                                  //0x0B,0x0C,0x0D,0x0E,0x0F in this case
                                                                                                                                                                  //The last checksum byte of this command may change for data to written different from
                                                                                                                                                                  //that in this case
            static char READ_4[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x04,0x0E};  //Command to read data in Block 4 (in Sector 1) in memory of MiFare card
            /*************************************************************************************************************************/
            static BYTE Key_A[]={0x4D,0x49,0x46,0x41,0x52,0x45};   //MIFARE 4D4946415245  identique pour toutes les machines
            
            static unsigned char reply_buffer[26]; //Buffer to store data received from MiFare module when a certain command is sent (maximum is 26 bytes in this case)
            //static unsigned char NUID[4];  //Array for storing NUID of a MiFare card //déja déclaré en global.... à verif !
            static char mode = 0;  //Variable storing current mode of the program
            static bool Rfid_wrtitting = false;
            
            
            // pour appel clase //
            RFIDthread::RFIDthread(QObject *parent) :
                QThread(parent)
            {
            }
            RFIDthread::~RFIDthread()
            {
                m_mutex.lock();
                m_quit = true;
                m_cond.wakeOne();
                m_mutex.unlock();
                wait();
            }
            
            
            //*************************************** SETUP FOR INFORMATION TRANSACTION *********************//
            void RFIDthread::transaction(const QString &portName, int waitTimeout, const QString &request)
            {
            //! [1]
                const QMutexLocker locker(&m_mutex);
                m_portName = portName;
                m_waitTimeout = waitTimeout;
                m_request = request;
            //! [3]
                if (!isRunning())
                    start();
                else
                    m_cond.wakeOne();
            }
            
            
            
            
            /*******************************************************************************************************
            * *************                    ---- Main de RFIDthread ----	                  ************         *
            *******************************************************************************************************/
            void RFIDthread::run()
            {
            
                bool Rfid_justarrived = true;
                int count_rfid_abs = 0;
                qDebug() << " Init thread RFID :";
            
                //----------------------- Parametrage de la liaison serie -------------------------------------- //
                QList<QSerialPortInfo> listPsi; // liste des ports série existant
                listPsi = QSerialPortInfo::availablePorts(); // récupère les ports série disponibles
            
                serialRFID = new QSerialPort(this);
            
                // ----- INIT SERIAL RFID ----//
                serialRFID->setPortName("ttyUSB0");
                serialRFID->setBaudRate(QSerialPort::Baud19200);
                serialRFID->setDataBits(QSerialPort::Data8);
                serialRFID->setParity(QSerialPort::NoParity);
                serialRFID->setStopBits(QSerialPort::OneStop);
                serialRFID->setFlowControl(QSerialPort::NoFlowControl);
                serialRFID->open(QIODevice::ReadWrite);
            
                if (serialRFID->isOpen() == true)
                {
                    qDebug() << "Serial ttyUSB0(USB0) is opened";
                }
                else
                {
                    qDebug() << "Connexion impossible RFID ! ";
                }
            
                qDebug() << " Thread RFID lancé !";
            
                // boucle principale du Thread :
                while(1)
                {
                    led_on();
                    delay(1000);
            
                    led_off();
                    delay(1000);
            
                    /*
                    // read dev num ;
                    read_dev();
                    delay(1000);
            
                    // read 4 ;
                    read_4();
                    delay(1000);
                    */
                }
            }
            
            
            /************************************************************************************************************************
            ********************                     ---- FIN du Main de RFIDthread ----	                   ***********************
            **************************************************************************************************************************/
            
            //======================================================================
            //************             RFID CR038 fonctions :               ****** //
            //======================================================================
            
            
            //******************************************
            //Turn on MiFare module LED subroutine
            void led_on(void)
            {
              // on envoit tout d'un coup !
              QByteArray da(LED_ON, sizeof(LED_ON));
              serialRFID->write(da);
              //delay(200)
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception LED_ON :" << ba;
            }
            
            //*******************************************
            //Turn on MiFare module LED subroutine
            void led_off(void)
            {
            
               QByteArray da(LED_OFF, sizeof(LED_OFF));
               serialRFID->write(da);
               QByteArray ba;
               //delay(200)
               while(!serialRFID->isOpen());
               ba = serialRFID->readAll();
               qDebug() << "reception LED_OFF :" << ba;
            }
            
            //*******************************************
            //Read MiFare device number subroutine
            void read_dev(void)
            {
              serialRFID->open(QIODevice::ReadWrite);
              QByteArray da(READ_DEV, sizeof(READ_DEV));
              serialRFID->write(da);
              //delay(200)
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception READ_DEV :" << ba;
            }
            
            //*******************************************
            //Turn on antenna of MiFare module subroutine
            void antenna_on(void)
            {
               QByteArray da(ANTENNA_ON, sizeof(ANTENNA_ON));
               serialRFID->write(da);
               //delay(200);
            
               QByteArray ba;
               while(!serialRFID->isOpen());
               ba = serialRFID->readAll();
               qDebug() << "reception ANTENNA_ON :" << ba;
            
            
            }
            
            //*******************************************
            //Request MiFare card type subroutine
            void card_req(void)
            {
              QByteArray da(CARD_REQ, sizeof(CARD_REQ));
              serialRFID->write(da);
              //delay()200
            
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception CARD_REQ :" << ba;
            
            }
            
            //*******************************************
            //Perform Anti-Collison subroutine
            void anti_col(void)
            {
            
              QByteArray da(ANTI_COL, sizeof(ANTI_COL));
              serialRFID->write(da);
              //delay()200
            
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception ANTI_COL :" << ba;
            
              //Byte 9 to byte 12 of replied bytes contains NUID of the MiFare card
              //Store them in NUID[] array
              for(int i = 0; i<4; i++)
              {
                  NUID[i] = ba[9+i];
              }
            
            }
            
            //*******************************************
            //Select MiFare card subroutine
            void card_sel(void)
            {
              QByteArray da(CARD_SEL, sizeof(CARD_SEL));
              serialRFID->write(da);
              //delay(200)
            
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception CARD_SEL :" << ba;
            
            
            }
            
            //*******************************************
            //Authenticate Sector 0 in memory of MiFare card subroutine
            void authen_sec0(void)
            {
              QByteArray da(AUTHEN_SEC0, sizeof(AUTHEN_SEC0));
              serialRFID->write(da);
              //delay(200)
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception AUTHEN_SEC0 :" << ba;
            
            }
            
            //*******************************************
            //Authenticate Sector 1 in memory of MiFare card subroutine
            void authen_sec1(void)
            {
              QByteArray da(AUTHEN_SEC1, sizeof(AUTHEN_SEC1));
              serialRFID->write(da);
              //delay(200)
            
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception AUTHEN_SEC1 :" << ba;
            
            
            }
            
            //*******************************************
            //Read data from Block 0 (manufaturer block) in memory of MiFare card subroutine
            void read_0 (void)
            {
              get_nuid();
              card_sel();  //Select MiFare card
              authen_sec0();  //Authenticate Sector 0 in memory of MiFare card
            
              QByteArray da(READ_0, sizeof(READ_0));
              serialRFID->write(da);
              //delay(200)
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception READ_0 :" << ba;
            
            }
            
            //*******************************************
            // init Read data  of MiFare card subroutine
            void init_read(void)
            {
              get_nuid();
              card_sel();  //Select MiFare card
            }
            
            //*******************************************
            //quick Read data from Block 4
            void read_4_quick(void)
            {
            
              authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
            
              QByteArray da(READ_4, sizeof(READ_4));
              serialRFID->write(da);
              //delay(200)
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception READ_4 :" << ba;
            }
            //*******************************************
            //Read data from Block 4 in memory of MiFare card subroutine
            void read_4(void)
            {
              get_nuid();
              card_sel();  //Select MiFare card
              authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
            
              QByteArray da(READ_4, sizeof(READ_4));
              serialRFID->write(da);
              //delay(200)
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception READ_4 :" << ba;
            }
            
            //*******************************************
            //Write data into from Block 4 in memory of MiFare card subroutine
            void write_4(void)
            {
              get_nuid();
              card_sel();  //Select MiFare card
              authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
            
              QByteArray da(WRITE_4, sizeof(WRITE_4));
              serialRFID->write(da);
              //delay(200)
              QByteArray ba;
              while(!serialRFID->isOpen());
              ba = serialRFID->readAll();
              qDebug() << "reception WRITE_4 :" << ba;
            }
            
            //*******************************************
            //Get NUID of MiFare card subroutine
            void get_nuid(void)
            {
              unsigned char xor_temp = 0;
              antenna_on();  //On the MiFare module onboard antenna
              card_req();  //Request card type of MiFare card
              anti_col();  //Perform anti-collision
            
              for(int i = 0; i<4; i++)  //Fill up byte 8 to byte 11 of CARD_SEL[] with NUID
              {
                 CARD_SEL[i+8] = NUID[i];
              }
              //delay(200)
              for(int i = 0; i<8; i++)  //Calculate the checksum of byte 4 to byte 11 of the CARD_SEL[]
              {
                xor_temp ^= CARD_SEL[4+i];
              }
              CARD_SEL[12] = xor_temp; //Fill the checksum in byte 12 of CARD_SEL[]
            }
            

            Cependant après avoir bataillé plusieurs jours je me suis rendu compte que pour que mon port série fonctionne je devais le déclarer et interagir depuis mon fichier mainwindow.cpp mais du coup on perdrais tout l’intérêt d'un Thread ...

            Voyez-vous une déclaration que j'aurais pu oublier dans mon Thread pour que celui-ci fonctionne de manière autonome ?
            (sans déclaration du port dans mainwindow...)

            Sinon j'ai déjà réussi à mettre au point un port série dans mainwindow pour communiquer avec un DSPIC33 de manière synchrone et cela marche très bien avec ça :

            if (serial->isOpen() == true)
                {
                    qDebug() << "Serial ttyAMA2(uart5) is opened";
                    connect(serial, SIGNAL(readyRead()),this,SLOT(on_Received_Data()));
                }
                else
                {
                    qDebug() << "Connexion impossible PIC ! ";
                }
            

            et

            //----- for serial port !! ------
            
            // boucle activé sur reception de données serie :
            void MainWindow::on_Received_Data()
            {
                // ------- choses à faire - RX side -------
                qDebug() << "reception données :";
                QByteArray ba;
                ba = serial->readAll();
                ui->label_uart_pic->setText("Données reçues : " + ba );
                qDebug() << ba;
            
            }
                
            

            Cependant je n'arrive pas à mettre au point ce même fonctionnement dans mon Thread RFID ....

            Vous avez des Idées ?

            merci ;)

            KroMignonK 1 Reply Last reply
            0
            • J jym92

              bonjour,

              effectivement je travaille souvent en C embarqué ou alors carrement en c#(application mobile) ...

              ok je vois donc je devrais pouvoir utilisé readAll() pour faire ce dont j'ai besoin.

              Mais repartons depuis le debut pour expliquer ce que je recherche...

              Je voudrais mettre au point un Thread RFID indépendant qui aurait pour de rôle de scanner en permanence la présence de carte RFID et de remonter leurs contenus grâce a des variables globales dans le reste du projet.
              Sur le papier ça devrait fonctionner parfaitement surtout en mode asynchrone vu le peu de chose qu'il y a à faire....

              donc voila le code de mon Thread RFID :

              /*********************************************************************
                                  RFID THRED In I2C mode
              ********************************************************************/
              #include <QtGui>
              #include <string.h>
              #include "RFIDthread.h"
              #include <wiringPi.h>
              #include "global.h"
              #include <QDebug>
              #include <math.h>
              #include <iostream>
              #include <cstdint>
              #include <cstring>
              #include <stdio.h>
              #include <stdint.h>
              #include <stdbool.h>
              #include <QtSerialPort/QSerialPort>
              #include <QSerialPortInfo>
              
              #include <mainwindow.h>
              
              
              static QSerialPort* serialRFID;
              
              /***********************************************  MiFare commands  *********************************************************/
              static char INIT_BAUD[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x01,0x01,0x03,0x03}; // init command to set baud at 19200
              static char LED_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x01,0x07};  //Command to turn on MiFare module onboard LED
              static char LED_OFF[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x00,0x06}; //Command to turn off MiFare module onboard LED
              static char ANTENNA_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x0C,0x01,0x01,0x0C};  //Command to turn off MiFare module onboard antenna
              static char READ_DEV[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x03,0x01,0x02};  //Command to read MiFare module device number
              static char CARD_REQ[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x01,0x02,0x52,0x51};  //Command to request card type of MiFare card
              static char ANTI_COL[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x02,02,00};  //Command for anti-collision
              static char CARD_SEL[] = {0xAA,0xBB,0x09,0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00};  //Command to select specific MiFare card for access
                                                                                                     //Byte 0 to byte 12 of this command is initialized with 0x00, since have to obtain the NUID of the MiFare card scanned
                                                                                                     //Byte 8 to byte 11 of this command will filled with NUID (started with the lowest byte) of the MiFare card desire to access
                                                                                                     //Byte 12 of this command is checksum from byte 4 to byte 11 of this command may change for NUID different from that in this case
                                                                                                     //This array will be filled during the subroutine of the get_nuid() in this program
              //static char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65};  //Command to authenticate Sector 0 in memory of MiFare card
              //static char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x61};  //Command to authenticate Sector 1 in memory of MiFare card
              
              static char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0x45,0x52,0x41,0x46,0x49,0x4D,0x65};  //Command to authenticate Sector 0 in memory of MiFare card
              static char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0x4D,0x49,0x46,0x41,0x52,0x45,0x61};
              
              static char READ_0[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x00,0x0A};  //Command to read Block 0 (manufacturer block in Sector 0) in memory of MiFare card
              static char WRITE_4[] = {0xAA,0xBB,0x16,0x00,0x00,0x00,0x09,0x02,0x04,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F}; //Command to write data into Block 4 (in Sector 1) in memory of MiFare card
                                                                                                                                                                    //Data to be written (started with the lowest byte) is from byte 9 to 24,
                                                                                                                                                                    //total of 16 bytes data
                                                                                                                                                                    //Data is 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A
                                                                                                                                                                    //0x0B,0x0C,0x0D,0x0E,0x0F in this case
                                                                                                                                                                    //The last checksum byte of this command may change for data to written different from
                                                                                                                                                                    //that in this case
              static char READ_4[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x04,0x0E};  //Command to read data in Block 4 (in Sector 1) in memory of MiFare card
              /*************************************************************************************************************************/
              static BYTE Key_A[]={0x4D,0x49,0x46,0x41,0x52,0x45};   //MIFARE 4D4946415245  identique pour toutes les machines
              
              static unsigned char reply_buffer[26]; //Buffer to store data received from MiFare module when a certain command is sent (maximum is 26 bytes in this case)
              //static unsigned char NUID[4];  //Array for storing NUID of a MiFare card //déja déclaré en global.... à verif !
              static char mode = 0;  //Variable storing current mode of the program
              static bool Rfid_wrtitting = false;
              
              
              // pour appel clase //
              RFIDthread::RFIDthread(QObject *parent) :
                  QThread(parent)
              {
              }
              RFIDthread::~RFIDthread()
              {
                  m_mutex.lock();
                  m_quit = true;
                  m_cond.wakeOne();
                  m_mutex.unlock();
                  wait();
              }
              
              
              //*************************************** SETUP FOR INFORMATION TRANSACTION *********************//
              void RFIDthread::transaction(const QString &portName, int waitTimeout, const QString &request)
              {
              //! [1]
                  const QMutexLocker locker(&m_mutex);
                  m_portName = portName;
                  m_waitTimeout = waitTimeout;
                  m_request = request;
              //! [3]
                  if (!isRunning())
                      start();
                  else
                      m_cond.wakeOne();
              }
              
              
              
              
              /*******************************************************************************************************
              * *************                    ---- Main de RFIDthread ----	                  ************         *
              *******************************************************************************************************/
              void RFIDthread::run()
              {
              
                  bool Rfid_justarrived = true;
                  int count_rfid_abs = 0;
                  qDebug() << " Init thread RFID :";
              
                  //----------------------- Parametrage de la liaison serie -------------------------------------- //
                  QList<QSerialPortInfo> listPsi; // liste des ports série existant
                  listPsi = QSerialPortInfo::availablePorts(); // récupère les ports série disponibles
              
                  serialRFID = new QSerialPort(this);
              
                  // ----- INIT SERIAL RFID ----//
                  serialRFID->setPortName("ttyUSB0");
                  serialRFID->setBaudRate(QSerialPort::Baud19200);
                  serialRFID->setDataBits(QSerialPort::Data8);
                  serialRFID->setParity(QSerialPort::NoParity);
                  serialRFID->setStopBits(QSerialPort::OneStop);
                  serialRFID->setFlowControl(QSerialPort::NoFlowControl);
                  serialRFID->open(QIODevice::ReadWrite);
              
                  if (serialRFID->isOpen() == true)
                  {
                      qDebug() << "Serial ttyUSB0(USB0) is opened";
                  }
                  else
                  {
                      qDebug() << "Connexion impossible RFID ! ";
                  }
              
                  qDebug() << " Thread RFID lancé !";
              
                  // boucle principale du Thread :
                  while(1)
                  {
                      led_on();
                      delay(1000);
              
                      led_off();
                      delay(1000);
              
                      /*
                      // read dev num ;
                      read_dev();
                      delay(1000);
              
                      // read 4 ;
                      read_4();
                      delay(1000);
                      */
                  }
              }
              
              
              /************************************************************************************************************************
              ********************                     ---- FIN du Main de RFIDthread ----	                   ***********************
              **************************************************************************************************************************/
              
              //======================================================================
              //************             RFID CR038 fonctions :               ****** //
              //======================================================================
              
              
              //******************************************
              //Turn on MiFare module LED subroutine
              void led_on(void)
              {
                // on envoit tout d'un coup !
                QByteArray da(LED_ON, sizeof(LED_ON));
                serialRFID->write(da);
                //delay(200)
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception LED_ON :" << ba;
              }
              
              //*******************************************
              //Turn on MiFare module LED subroutine
              void led_off(void)
              {
              
                 QByteArray da(LED_OFF, sizeof(LED_OFF));
                 serialRFID->write(da);
                 QByteArray ba;
                 //delay(200)
                 while(!serialRFID->isOpen());
                 ba = serialRFID->readAll();
                 qDebug() << "reception LED_OFF :" << ba;
              }
              
              //*******************************************
              //Read MiFare device number subroutine
              void read_dev(void)
              {
                serialRFID->open(QIODevice::ReadWrite);
                QByteArray da(READ_DEV, sizeof(READ_DEV));
                serialRFID->write(da);
                //delay(200)
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception READ_DEV :" << ba;
              }
              
              //*******************************************
              //Turn on antenna of MiFare module subroutine
              void antenna_on(void)
              {
                 QByteArray da(ANTENNA_ON, sizeof(ANTENNA_ON));
                 serialRFID->write(da);
                 //delay(200);
              
                 QByteArray ba;
                 while(!serialRFID->isOpen());
                 ba = serialRFID->readAll();
                 qDebug() << "reception ANTENNA_ON :" << ba;
              
              
              }
              
              //*******************************************
              //Request MiFare card type subroutine
              void card_req(void)
              {
                QByteArray da(CARD_REQ, sizeof(CARD_REQ));
                serialRFID->write(da);
                //delay()200
              
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception CARD_REQ :" << ba;
              
              }
              
              //*******************************************
              //Perform Anti-Collison subroutine
              void anti_col(void)
              {
              
                QByteArray da(ANTI_COL, sizeof(ANTI_COL));
                serialRFID->write(da);
                //delay()200
              
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception ANTI_COL :" << ba;
              
                //Byte 9 to byte 12 of replied bytes contains NUID of the MiFare card
                //Store them in NUID[] array
                for(int i = 0; i<4; i++)
                {
                    NUID[i] = ba[9+i];
                }
              
              }
              
              //*******************************************
              //Select MiFare card subroutine
              void card_sel(void)
              {
                QByteArray da(CARD_SEL, sizeof(CARD_SEL));
                serialRFID->write(da);
                //delay(200)
              
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception CARD_SEL :" << ba;
              
              
              }
              
              //*******************************************
              //Authenticate Sector 0 in memory of MiFare card subroutine
              void authen_sec0(void)
              {
                QByteArray da(AUTHEN_SEC0, sizeof(AUTHEN_SEC0));
                serialRFID->write(da);
                //delay(200)
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception AUTHEN_SEC0 :" << ba;
              
              }
              
              //*******************************************
              //Authenticate Sector 1 in memory of MiFare card subroutine
              void authen_sec1(void)
              {
                QByteArray da(AUTHEN_SEC1, sizeof(AUTHEN_SEC1));
                serialRFID->write(da);
                //delay(200)
              
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception AUTHEN_SEC1 :" << ba;
              
              
              }
              
              //*******************************************
              //Read data from Block 0 (manufaturer block) in memory of MiFare card subroutine
              void read_0 (void)
              {
                get_nuid();
                card_sel();  //Select MiFare card
                authen_sec0();  //Authenticate Sector 0 in memory of MiFare card
              
                QByteArray da(READ_0, sizeof(READ_0));
                serialRFID->write(da);
                //delay(200)
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception READ_0 :" << ba;
              
              }
              
              //*******************************************
              // init Read data  of MiFare card subroutine
              void init_read(void)
              {
                get_nuid();
                card_sel();  //Select MiFare card
              }
              
              //*******************************************
              //quick Read data from Block 4
              void read_4_quick(void)
              {
              
                authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
              
                QByteArray da(READ_4, sizeof(READ_4));
                serialRFID->write(da);
                //delay(200)
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception READ_4 :" << ba;
              }
              //*******************************************
              //Read data from Block 4 in memory of MiFare card subroutine
              void read_4(void)
              {
                get_nuid();
                card_sel();  //Select MiFare card
                authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
              
                QByteArray da(READ_4, sizeof(READ_4));
                serialRFID->write(da);
                //delay(200)
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception READ_4 :" << ba;
              }
              
              //*******************************************
              //Write data into from Block 4 in memory of MiFare card subroutine
              void write_4(void)
              {
                get_nuid();
                card_sel();  //Select MiFare card
                authen_sec1();  //Authenticate Sector 0 in memory of MiFare card
              
                QByteArray da(WRITE_4, sizeof(WRITE_4));
                serialRFID->write(da);
                //delay(200)
                QByteArray ba;
                while(!serialRFID->isOpen());
                ba = serialRFID->readAll();
                qDebug() << "reception WRITE_4 :" << ba;
              }
              
              //*******************************************
              //Get NUID of MiFare card subroutine
              void get_nuid(void)
              {
                unsigned char xor_temp = 0;
                antenna_on();  //On the MiFare module onboard antenna
                card_req();  //Request card type of MiFare card
                anti_col();  //Perform anti-collision
              
                for(int i = 0; i<4; i++)  //Fill up byte 8 to byte 11 of CARD_SEL[] with NUID
                {
                   CARD_SEL[i+8] = NUID[i];
                }
                //delay(200)
                for(int i = 0; i<8; i++)  //Calculate the checksum of byte 4 to byte 11 of the CARD_SEL[]
                {
                  xor_temp ^= CARD_SEL[4+i];
                }
                CARD_SEL[12] = xor_temp; //Fill the checksum in byte 12 of CARD_SEL[]
              }
              

              Cependant après avoir bataillé plusieurs jours je me suis rendu compte que pour que mon port série fonctionne je devais le déclarer et interagir depuis mon fichier mainwindow.cpp mais du coup on perdrais tout l’intérêt d'un Thread ...

              Voyez-vous une déclaration que j'aurais pu oublier dans mon Thread pour que celui-ci fonctionne de manière autonome ?
              (sans déclaration du port dans mainwindow...)

              Sinon j'ai déjà réussi à mettre au point un port série dans mainwindow pour communiquer avec un DSPIC33 de manière synchrone et cela marche très bien avec ça :

              if (serial->isOpen() == true)
                  {
                      qDebug() << "Serial ttyAMA2(uart5) is opened";
                      connect(serial, SIGNAL(readyRead()),this,SLOT(on_Received_Data()));
                  }
                  else
                  {
                      qDebug() << "Connexion impossible PIC ! ";
                  }
              

              et

              //----- for serial port !! ------
              
              // boucle activé sur reception de données serie :
              void MainWindow::on_Received_Data()
              {
                  // ------- choses à faire - RX side -------
                  qDebug() << "reception données :";
                  QByteArray ba;
                  ba = serial->readAll();
                  ui->label_uart_pic->setText("Données reçues : " + ba );
                  qDebug() << ba;
              
              }
                  
              

              Cependant je n'arrive pas à mettre au point ce même fonctionnement dans mon Thread RFID ....

              Vous avez des Idées ?

              merci ;)

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by KroMignon
              #6

              @jym92 Ohlala, je vois très bien le soucis... Dans Qt, il y a plusieurs règles "de base" à respecter pour éviter les ennuis, et l'une d'elle c'est de ne jamais utiliser QThread comme classe de base, mais de créer une "worker class" que l'on va faire travailler dans un thread dédié.

              Il y a plusieurs bonnes raisons à cela, et ce serait trop long a expliquer comme ça, je vous conseille d'aller lire les article suivants:

              • http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
              • https://www.toptal.com/qt/qt-multithreading-c-plus-plus
              • https://hub.packtpub.com/multithreading-qt/

              Pour résumer, je dirais:
              a. créer une classe RfidReader qui va faire la gestion du port série / lecture du RFID
              b. créer une instance de cette classe
              c. créer une instance de QThread et "déplacé" l'instance de la worker class vers ce thread
              d. utiliser des connection signals/slots pour transférer les données du thread de travail vers le thread principal, comme ça c'est Qt qui s'occupe de faire les copies et vous éviter de devoir gérer les accès multi-thread.

              Autres règles de base pour Qt

              • ne jamais bloquer le thread principal, sinon votre IHM devient inutilisable!!
              • toutes les actions IHM/graphique doivent être exécutées dans le thread principale

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jym92
                wrote on last edited by
                #7

                Ok je regarde ça et j'essaye de le mettre en place !

                Oui je connais bien ces règles principales, ce sont les mêmes qu'en C# d'où pour la nécessité de faire fonctionner le RFID de manière indépendante dans son propre Thread.

                merci !

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  jym92
                  wrote on last edited by
                  #8

                  Bonjour @KroMignon ,

                  j'ai crée la classe RFIDreader(cpp + h) dans la laquelle j'ai rangé toutes mes fonctions de base RFID telles que LedOn, LedOff, read, write....

                  et j'ai fait du coup du ménage dans mon thread RFID ;)

                  par contre j'ai une question, j'ai commencé à mettre en place ce qui est indiqué dans ce tuto : https://hub.packtpub.com/multithreading-qt/

                  cependant j'ai plusieures questions :

                  1- dans mon Thread RFID j'aurai ma déclaration de port série, les routines d’exécution RFID qui y seront appelées ainsi que ceci :

                  class Thread : public QThread
                  {
                  Q_OBJECT
                  protected:
                      void run() 
                      {
                          Object* myObject = new Object();
                          connect(myObject, &Object::started, 
                                  this, &Thread::doWork);
                          exec();
                      }
                  
                  private slots:
                      void doWork();
                  };
                  

                  C'est bien ça ? (bien-sur j'adapterai les noms...)

                  2- Pour ce qui est de la classe worker , je suis censé le mettre où ?
                  (fichier indépendant RfidWorker(cpp+h) ou dans RFIDThread )

                  class Worker : public QObject
                  {
                      Q_OBJECT
                  public slots:
                      void doWork() 
                      {
                          emit result("workers are the best");
                      }
                  
                  signals:
                      void result(QString data);
                  };
                  

                  D'ailleurs cette classe worker ne sert qu'a faire le lien ou bien c'est la que je dois implémenté le déroulement de mon thread ?

                  3- ça sert à quoi ça ?

                  connect(thread, &QThread::finished, 
                          worker, &QObject::deleteLater);
                  connect(this, &MainWindow::startWork, 
                          worker, &Worker::doWork);
                  connect(worker, &Worker::resultReady, 
                          this, handleResult);
                  

                  Sachant que dans mon cas, mon Thread a seulement pour role d'indiquer si un badge et son montant ... donc je pensais passer ces 2 infos au Thread principal (mainwindow) via 2 variables globales (un bool et un int)...

                  merci d'avance si tu peux à toutes mes interrogations ;)

                  KroMignonK 1 Reply Last reply
                  0
                  • J jym92

                    Bonjour @KroMignon ,

                    j'ai crée la classe RFIDreader(cpp + h) dans la laquelle j'ai rangé toutes mes fonctions de base RFID telles que LedOn, LedOff, read, write....

                    et j'ai fait du coup du ménage dans mon thread RFID ;)

                    par contre j'ai une question, j'ai commencé à mettre en place ce qui est indiqué dans ce tuto : https://hub.packtpub.com/multithreading-qt/

                    cependant j'ai plusieures questions :

                    1- dans mon Thread RFID j'aurai ma déclaration de port série, les routines d’exécution RFID qui y seront appelées ainsi que ceci :

                    class Thread : public QThread
                    {
                    Q_OBJECT
                    protected:
                        void run() 
                        {
                            Object* myObject = new Object();
                            connect(myObject, &Object::started, 
                                    this, &Thread::doWork);
                            exec();
                        }
                    
                    private slots:
                        void doWork();
                    };
                    

                    C'est bien ça ? (bien-sur j'adapterai les noms...)

                    2- Pour ce qui est de la classe worker , je suis censé le mettre où ?
                    (fichier indépendant RfidWorker(cpp+h) ou dans RFIDThread )

                    class Worker : public QObject
                    {
                        Q_OBJECT
                    public slots:
                        void doWork() 
                        {
                            emit result("workers are the best");
                        }
                    
                    signals:
                        void result(QString data);
                    };
                    

                    D'ailleurs cette classe worker ne sert qu'a faire le lien ou bien c'est la que je dois implémenté le déroulement de mon thread ?

                    3- ça sert à quoi ça ?

                    connect(thread, &QThread::finished, 
                            worker, &QObject::deleteLater);
                    connect(this, &MainWindow::startWork, 
                            worker, &Worker::doWork);
                    connect(worker, &Worker::resultReady, 
                            this, handleResult);
                    

                    Sachant que dans mon cas, mon Thread a seulement pour role d'indiquer si un badge et son montant ... donc je pensais passer ces 2 infos au Thread principal (mainwindow) via 2 variables globales (un bool et un int)...

                    merci d'avance si tu peux à toutes mes interrogations ;)

                    KroMignonK Offline
                    KroMignonK Offline
                    KroMignon
                    wrote on last edited by
                    #9

                    @jym92 Bonjour, hmm je ne sais pas si j'ai bien compris la structure que vous avez décidé d'implémenter...
                    Je vais broder autour de ce que j'ai cru comprendre... désolé si je suis à côté de la plaque

                    Pour moi, il suffit de créer une seule classe qui va faire la gestion du port série, la fameuse "RfidWorker".
                    Cette classe va avoir un signal "newTag" et des slots "start" et "stop", quelque chose comme ça:

                    class RfIdWorker : public QObject
                    {
                        Q_OBJECT
                    
                    public:
                        explicit RfIdWorker (QObject * parent);
                    ...
                    
                    public slots:
                        void start();
                        void stop();
                    
                    signals:
                        void newTag(QString tagID, int tagValue);
                    
                    };
                    

                    Après pour démarrer l'utilisation du Rfid:

                      auto * rfWorker = new RfIdWorker();
                      auto* rfThread = new QThread();
                    
                      // start RF ID Reader on thread start
                      connect(rfThread, &QThread::started, rfWorker , &RfIdWorker::start);
                      // stop RF ID Reader on main application exit
                      connect(qApp, &QApplication::aboutToQuit, rfWorker, &QObject::deleteLater);
                      // delete thread on worker end
                      connect(rfWorker, &QObject::destroyed, rfThread, [rfThread](QObject *) 
                              {
                                  if(rfThread.isRunning())
                                  {
                                       rfThread.quit();
                                       rfThread.wait();
                                  }
                                  rfThread.deleteLater();
                              }
                              , Qt::DirectConnection);  // needs "DirectConnection" to work
                    
                        // to be informed about new RF ID tag
                        connect(rfWorker,  &RfIdWorker::newTag, this, &MyMainClass::newRfIdTag);
                        // move worker object to worker  thread
                        rfWorker.moveToThread(rfThread);
                        // last but not least, start worker thread
                        rfThread.start();
                    

                    Dans le slot start, le port série est initialisé et démarré.
                    Dans le slot stop; le port série est fermé.

                    En gros, voici comment je ferai.

                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      jym92
                      wrote on last edited by
                      #10

                      Ok je vois c'est déja un peu plus clair pour moi ...

                      Donc j'aurai juste une classe "RFIDworker" et un thread "RFIDThread", et mes fonctions de base pour le RFID seront contenu et appelée dans la classe "RFIDworker".

                      J'ai bien saisi pour l'initialisation de port série ainsi que pour l'init du thread et du Qobject qui se feront dans mainwindow.

                      Cependant j'aurai besoin de mettre en place une boucle infini ou un timer me permettant de scanner en boucle si il y a un new tag...
                      Je dois mettre ça en place dans la classe RFIDworker en créant un slot "onWork" qui contiendra une boucle infini qui scannera puis déclenchera le signal Newtag ?
                      ou je ma boucle déclenchant newtag devrait etre dans le fichier RFIDThread ?

                      désolé pour mes questions mais je suis un peu neuf avec genre de fonctionnement à cheval entre l'embarqué et la création d'application ....

                      Un grand merci pour ton aide !

                      KroMignonK 1 Reply Last reply
                      0
                      • J jym92

                        Ok je vois c'est déja un peu plus clair pour moi ...

                        Donc j'aurai juste une classe "RFIDworker" et un thread "RFIDThread", et mes fonctions de base pour le RFID seront contenu et appelée dans la classe "RFIDworker".

                        J'ai bien saisi pour l'initialisation de port série ainsi que pour l'init du thread et du Qobject qui se feront dans mainwindow.

                        Cependant j'aurai besoin de mettre en place une boucle infini ou un timer me permettant de scanner en boucle si il y a un new tag...
                        Je dois mettre ça en place dans la classe RFIDworker en créant un slot "onWork" qui contiendra une boucle infini qui scannera puis déclenchera le signal Newtag ?
                        ou je ma boucle déclenchant newtag devrait etre dans le fichier RFIDThread ?

                        désolé pour mes questions mais je suis un peu neuf avec genre de fonctionnement à cheval entre l'embarqué et la création d'application ....

                        Un grand merci pour ton aide !

                        KroMignonK Offline
                        KroMignonK Offline
                        KroMignon
                        wrote on last edited by KroMignon
                        #11

                        @jym92 Pour moi, il suffit de créer une classe qui sait décoder les trames de ton (c'est au moins mon 3ème message... je passe au tutoiement ;-) ) récepteur RFID.

                        Je continue sur l'exemple d'avant:

                        class RfIdWorker : public QObject
                        {
                            Q_OBJECT
                        
                        public:
                            explicit RfIdWorker (QObject * parent);
                        ...
                        
                        public slots:
                            void start();
                            void stop();
                        
                        private slots:
                           void checkRFID();
                        
                        signals:
                            void newTag(QString tagID, int tagValue);
                        
                        private:
                            QSerialPort *m_serial;
                        };
                        

                        Et du côté C++

                        RfIdWorker:RfIdWorker (QObject *parent): QObject(parent), m_serial(Q_NULLPTR)
                        {
                        }
                        
                        void RfIdWorker::start()
                        {
                            if(!m_serial)
                            {
                                m_serial = new QSerialPort(this);
                                // serial port initialistion
                                ...
                                connect(m_serial, &QSerialPort::readyRead, this, &RfIdWorker::checkRFID);
                            }
                            m_serial.open();
                        }
                        
                        void RfIdWorker::stop()
                        {
                            if(m_serial && m_serial.isOpen())
                            {
                                m_serial.close();
                            }
                        }
                        
                        void RfIdWorker::checkRFID()
                        {
                            while(!m_serial->atEnd())
                            {
                                QByteArray rfIdRaw = m_serial->readAll();
                                // process data
                                ...
                                if(!tag.isEmpty())
                                    emit newTag(tag, value);
                            }
                        }
                        

                        Ce n'est qu'un squelette, mais ça donne une idée de l'architecture

                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          jym92
                          wrote on last edited by
                          #12

                          Oui tu fais bien d'utiliser le tutoiement au vu de ton implication ;)

                          Ok je vois à peu près le squelette, j'essaye de mettre tout ça en place et je reviens vers toi !

                          merci

                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            jym92
                            wrote on last edited by
                            #13

                            Alors il me semble avoir bien suivi tes consignes, le Thread se lance puis le worker et tout semble bien tourner au vu du debug ...
                            Cependant comme auparavant il semblerait que lorsque j'essaye d'envoyer des commandes par le port série rien ne se passe(une led sur mon ftdi devrait indiquer l'émission de données).

                            Je ne comprends pas pourquoi mon worker ne pourrait pas interagir avec mon port série "ttyusb0"...

                            voici ce que j'ai fait :

                            RFIDThread.cpp:

                            /*********************************************************************
                                                RFID THRED In I2C mode
                            ********************************************************************/
                            #include <QtGui>
                            #include "RFIDthread.h"
                            #include "global.h"
                            #include <QDebug>
                            #include <mainwindow.h>
                            #include "RFIDworker.h"
                            
                            //static unsigned char NUID[4];  //Array for storing NUID of a MiFare card //déja déclaré en global.... à verif !
                            static char mode = 0;  //Variable storing current mode of the program
                            static bool Rfid_wrtitting = false;
                            
                            
                            // pour appel clase //
                            RFIDthread::RFIDthread(QObject *parent) :
                                QThread(parent)
                            {
                            }
                            
                            /*******************************************************************************************************
                            * *************                    ---- Main de RFIDthread ----	                  ************         *
                            *******************************************************************************************************/
                            void RFIDthread::run()
                            {
                            
                                qDebug() << " Thread RFID lancé !";
                            
                            }
                            
                            
                            /************************************************************************************************************************
                            ********************                     ---- FIN du Main de RFIDthread ----	                   ***********************
                            **************************************************************************************************************************/
                            

                            Pour ce qui est RFIDworker :

                            
                            static QSerialPort *serialRFID;
                            
                            //RFIDworker :: RFIDworker (QObject *parent): QObject(parent), serialRFID(Q_NULLPTR)
                            RFIDworker::RFIDworker(QObject *parent): QObject(parent)
                            {
                            }
                            
                            void RFIDworker::start()
                            {
                                if(!serialRFID)
                                {
                                    serialRFID = new QSerialPort(this);
                                    // serial port initialistion
                                    // ----- INIT SERIAL RFID ----//
                                    serialRFID->setPortName("ttyUSB0");
                                    serialRFID->setBaudRate(QSerialPort::Baud19200);
                                    serialRFID->setDataBits(QSerialPort::Data8);
                                    serialRFID->setParity(QSerialPort::NoParity);
                                    serialRFID->setStopBits(QSerialPort::OneStop);
                                    serialRFID->setFlowControl(QSerialPort::NoFlowControl);
                                    serialRFID->open(QIODevice::ReadWrite);
                            
                                    connect(serialRFID, &QSerialPort::readyRead, this, &RFIDworker::checkRFID);
                            
                                    if (serialRFID->isOpen() == true)
                                    {
                                        qDebug() << "Serial ttyUSB0(USB0) is opened";
                                    }
                                    else
                                    {
                                        qDebug() << "Connexion impossible RFID ! ";
                                    }
                            
                                    // lancement de la routine recherche badge
                                    checkRFID();
                                }
                            }
                            
                            void RFIDworker::stop()
                            {
                                if(serialRFID && serialRFID->isOpen())
                                {
                                    serialRFID->close();
                                }
                            }
                            
                            void RFIDworker::checkRFID()
                            {
                                while(1)
                                {
                                    led_on();
                                    delay(400);
                                    led_off();
                                    delay(400);
                            
                                }
                            }
                            
                            

                            et enfin voila comment je démarre le tout dans mainwindow :

                            // ------------ Lancement du Thread RFID et du worker lié -----------------//
                                auto* rfWorker = new RFIDworker();
                                auto* rfThread = new RFIDthread();
                            
                                // start RF ID Reader on thread start
                                connect(rfThread, &QThread::started, rfWorker , &RFIDworker::start);
                                // stop RF ID Reader on main application exit
                                connect(qApp, &QApplication::aboutToQuit, rfWorker, &QObject::deleteLater);
                                // delete thread on worker end
                                connect(rfWorker, &QObject::destroyed, rfThread, [rfThread](QObject *)
                                {
                                    if(rfThread->isRunning())
                                    {
                                         rfThread->quit();
                                         rfThread->wait();
                                    }
                                    rfThread->deleteLater();
                                }
                                , Qt::DirectConnection);  // needs "DirectConnection" to work
                                // to be informed about new RF ID tag
                                //connect(rfWorker,  &RFIDworker::newTag, this, &MyMainClass::newRfIdTag);
                                // move worker object to worker  thread
                                rfWorker->moveToThread(rfThread);
                                // last but not least, start worker thread
                                rfThread->start();
                            

                            remarque : ce morceau de code est situé dans le init de mainwindow.cpp.

                            Enfin j'ai également noté que le fait de déclarer un second port série dans un Thread différent semble brouiller mon premier port série lorsque celui-ci essaye d’émettre des données, il croit voir une réponse (il s'agit du port série réserver au PIC et les fils sont en l'air ...).

                            Une idée pour que je puisse interagir avec le port série depuis mon worker ?

                            Une idée d'ou peut venir le conflit entre les 2 ports séries ?

                            merci d'avance ;)

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              La variable static QSerialPort est une mauvaise idée. Il n'y a aucune raison qu'elle soit déclarée static. Elle devrait être un membre du worker object.

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                jym92
                                wrote on last edited by
                                #15

                                merci de ta réponse @SGaist , je viens de le paramètre extern dans mon fichier global avec :

                                //global.h
                                extern QSerialPort* serialRFID;
                                extern QSerialPort* serial;
                                
                                //global.cpp
                                QSerialPort* serial;
                                QSerialPort* serialRFID;
                                

                                Mais cela ne change rien, j'ai pas de réaction sur le port série ....

                                Comment je peux ajouter mon port série à Qserialport serialRFID à mon worker object ?

                                KroMignonK 1 Reply Last reply
                                0
                                • J jym92

                                  merci de ta réponse @SGaist , je viens de le paramètre extern dans mon fichier global avec :

                                  //global.h
                                  extern QSerialPort* serialRFID;
                                  extern QSerialPort* serial;
                                  
                                  //global.cpp
                                  QSerialPort* serial;
                                  QSerialPort* serialRFID;
                                  

                                  Mais cela ne change rien, j'ai pas de réaction sur le port série ....

                                  Comment je peux ajouter mon port série à Qserialport serialRFID à mon worker object ?

                                  KroMignonK Offline
                                  KroMignonK Offline
                                  KroMignon
                                  wrote on last edited by
                                  #16

                                  @jym92 Comme l'a déjà souligné @SGaist, l'utilisation de la variables statiques est en générale une très mauvaise idée en C++. A moins de vouloir partager une variable entre plusieurs instances de cette classe, mais c'est un cas d'usage très particulier.

                                  Encore une fois, il n'est pas utile de créer une classe dérivée de QThread!. De plus, je fait de faire une propre implémentation du slot run() fait en sorte de ne pas créer, ni démarrer une EventQueue pour ce thread, donc le mécanisme de signals/slots de Qt ne fonctionnera pas avec ce thread!

                                  Après, à quoi sert RFIDworker::checkRFID()? A part bloquer le thread dans une boucle infinie ;-)
                                  Bref là également une très mauvaise idée, je veut dire par là, pas 'Qt Conforme'.
                                  Pour que le mécanisme signals/slots fonctionne, il faut une EventQueue et ne faut pas bloquer le thread dans une boucle infinie!

                                  Je reprends mon exemple de WorkerClass

                                  class RfIdWorker : public QObject
                                  {
                                      Q_OBJECT
                                  
                                  public:
                                      explicit RfIdWorker (QObject * parent);
                                  ...
                                  
                                  public slots:
                                      void start();
                                      void stop();
                                  
                                  private slots:
                                     void checkRFID();
                                      void ledTimer();
                                  
                                  signals:
                                      void newTag(QString tagID, int tagValue);
                                  
                                  private:
                                      QSerialPort *m_serial;
                                      QTimer *m_timer;
                                      bool m_ledState;
                                  };
                                  

                                  Pour le C++:

                                  RfIdWorker:RfIdWorker (QObject *parent)
                                      : QObject(parent)
                                      , m_serial(Q_NULLPTR)
                                      , m_timer(Q_NULLPTR)
                                      , m_ledState(false)
                                  {
                                  }
                                  
                                  void RfIdWorker::start()
                                  {
                                      if(!m_ledTimer)
                                      {
                                          m_ledTimer = new QTimer(this);
                                          m_ledTimer->setSingleShot(false);
                                          m_ledTiler->setInterval(400);
                                          connect(m_ledTimer, &QTimer::timeout, this, &RfIdWorker::ledTimer);
                                      }
                                  
                                      if(!m_serial)
                                      {
                                          m_serial = new QSerialPort(this);
                                          // serial port initialistion
                                          ...
                                          connect(m_serial, &QSerialPort::readyRead, this, &RfIdWorker::checkRFID);
                                      }
                                      m_serial>open();
                                      m_ledTimer->start();
                                  }
                                  
                                  void RfIdWorker::stop()
                                  {
                                      if(m_serial && m_serial->isOpen())
                                      {
                                          m_serial->close();
                                      }
                                      if(m_ledTimer && m_ledTimer->isActive())
                                          m_ledTimer->stop();
                                  }
                                  
                                  void RfIdWorker::ledTimer()
                                  {
                                      if(m_ledState)
                                          led_on();
                                      else
                                          led_off();
                                      m_ledState = !m_ledState;
                                  }
                                  
                                  void RfIdWorker::checkRFID()
                                  {
                                      while(!m_serial->atEnd())
                                      {
                                          QByteArray rfIdRaw = m_serial->readAll();
                                          // process data
                                          ...
                                          if(!tag.isEmpty())
                                              emit newTag(tag, value);
                                      }
                                  }
                                  
                                  
                                  

                                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                  1 Reply Last reply
                                  0
                                  • J Offline
                                    J Offline
                                    jym92
                                    wrote on last edited by
                                    #17

                                    Bonjour,

                                    Tout d'abord je vous remercie pour vos conseils et je commence à petit à petit à saisir la logique un peu tordu de Qt ;p

                                    J'ai du coup modifier mon worker pour passer le port serie en private à la classe et j'ai mis en place le fonctionnement via le timer au lieu de la boucle infini.

                                    Cependant le timer ne démarre pas alors qu'au vu des lignes de debug tout semble bien se lancer sauf le timer ...

                                    voici le code du worker.h :

                                    #ifndef RFIDworker_H
                                    #define RFIDworker_H
                                    
                                    #include <QObject>
                                    #include <QtSerialPort>
                                    
                                    
                                    
                                    class RFIDworker : public QObject
                                    {
                                        Q_OBJECT
                                    
                                    public:
                                        explicit RFIDworker(QObject *parent= nullptr);
                                    
                                    
                                    public slots:
                                        void start();
                                        void stop();
                                    
                                    private slots:
                                       void checkRFID();
                                       void ledTimer();
                                    
                                    signals:
                                        void newTag(QString tagID, int tagValue);
                                    
                                    private:
                                       QSerialPort *RFIDserial;
                                       QTimer *m_timer;
                                       bool m_ledState;
                                    };
                                    
                                    //======================================================================
                                    //************             RFID CR038 fonctions :               ****** //
                                    //======================================================================
                                    
                                    //*******************************************//
                                    //Turn on MiFare module LED subroutine
                                    void led_on(QSerialPort *RFIDport);
                                    
                                    //*******************************************//
                                    //Turn on MiFare module LED subroutine
                                    void led_off(QSerialPort *RFIDport);
                                    

                                    et du worker.cpp :

                                    RFIDworker::RFIDworker(QObject *parent): QObject(parent)
                                        , RFIDserial(Q_NULLPTR)
                                        , m_timer(Q_NULLPTR)
                                        , m_ledState(false)
                                    {
                                    }
                                    
                                    void RFIDworker::start()
                                    {
                                        if(!m_timer)
                                            {
                                                m_timer = new QTimer(this);
                                                m_timer->setSingleShot(false);
                                                m_timer->setInterval(400);
                                                connect(m_timer, &QTimer::timeout, this, &RFIDworker::ledTimer);
                                            }
                                    
                                        if(!RFIDserial)
                                        {
                                            RFIDserial = new QSerialPort(this);
                                            // serial port initialistion
                                            // ----- INIT SERIAL RFID ----//
                                            RFIDserial->setPortName("ttyUSB0");
                                            RFIDserial->setBaudRate(QSerialPort::Baud19200);
                                            RFIDserial->setDataBits(QSerialPort::Data8);
                                            RFIDserial->setParity(QSerialPort::NoParity);
                                            RFIDserial->setStopBits(QSerialPort::OneStop);
                                            RFIDserial->setFlowControl(QSerialPort::NoFlowControl);
                                            RFIDserial->open(QIODevice::ReadWrite);
                                    
                                            connect(RFIDserial, &QSerialPort::readyRead, this, &RFIDworker::checkRFID);
                                    
                                            if (RFIDserial->isOpen() == true)
                                            {
                                                qDebug() << "Serial ttyUSB0(USB0) is opened";
                                            }
                                            else
                                            {
                                                qDebug() << "Connexion impossible RFID ! ";
                                            }
                                            // lancement timer
                                            m_timer->start();
                                    
                                    
                                        }
                                    }
                                    
                                    void RFIDworker::stop()
                                    {
                                        if(serialRFID && serialRFID->isOpen())
                                        {
                                            serialRFID->close();
                                        }
                                        if(m_timer && m_timer->isActive())
                                                m_timer->stop();
                                    }
                                    
                                    void RFIDworker::ledTimer()
                                    {
                                        if(m_ledState)
                                            led_on(RFIDserial);
                                        else
                                            led_off(RFIDserial);
                                        m_ledState = !m_ledState;
                                        qDebug() << "passage dans Ledtimer";
                                    }
                                    
                                    void RFIDworker::checkRFID()
                                    {
                                        while(!RFIDserial->atEnd())
                                            {
                                                qDebug() << "passage dans checkRFID";
                                                //QByteArray rfIdRaw = RFIDserial->readAll();
                                                // process data
                                                /*
                                                if(!tag.isEmpty())
                                                    emit newTag(tag, value);
                                                */
                                            }
                                    }
                                    
                                    
                                    //======================================================================
                                    //************             RFID CR038 fonctions :               ****** //
                                    //======================================================================
                                    
                                    
                                    //******************************************
                                    //Turn on MiFare module LED subroutine
                                    void led_on(QSerialPort *RFIDport)
                                    {
                                      // on envoit tout d'un coup !
                                      QByteArray da(LED_ON, sizeof(LED_ON));
                                      RFIDport->write(da);
                                      //delay(200)
                                      QByteArray ba;
                                      while(!RFIDport->isOpen());
                                      ba = RFIDport->readAll();
                                      qDebug() << "reception LED_ON :" << ba;
                                    }
                                    
                                    //*******************************************
                                    //Turn on MiFare module LED subroutine
                                    void led_off(QSerialPort *RFIDport)
                                    {
                                    
                                       QByteArray da(LED_OFF, sizeof(LED_OFF));
                                       RFIDport->write(da);
                                       QByteArray ba;
                                       //delay(200)
                                       while(!RFIDport->isOpen());
                                       ba = RFIDport->readAll();
                                       qDebug() << "reception LED_OFF :" << ba;
                                    }
                                    
                                    

                                    Coté init dans le mainwindow j'ai rien changé ....

                                    en réponse console j'ai :

                                    Serial ttyUSB0(USB0) is opened
                                     Thread RFID lancé !
                                    

                                    donc le worker a bien été lancé ainsi que le thread RFID.

                                    Une idée ? J'ai oublié un truc ?

                                    J'ai essayé d'échanger Tx et Rx coté connectique mais rien ne se passe...
                                    et je devrais quand même avoir des lignes de debug coté worker qui indique le déroulement du ledtimer...

                                    J'essaye de coller au mieu à la "QT conforme" mais vu que mon projet est a cheval entre une IHM et de l'embarqué pur c'est pas simple...

                                    Merci pour votre aide ;)

                                    KroMignonK 2 Replies Last reply
                                    0
                                    • J jym92

                                      Bonjour,

                                      Tout d'abord je vous remercie pour vos conseils et je commence à petit à petit à saisir la logique un peu tordu de Qt ;p

                                      J'ai du coup modifier mon worker pour passer le port serie en private à la classe et j'ai mis en place le fonctionnement via le timer au lieu de la boucle infini.

                                      Cependant le timer ne démarre pas alors qu'au vu des lignes de debug tout semble bien se lancer sauf le timer ...

                                      voici le code du worker.h :

                                      #ifndef RFIDworker_H
                                      #define RFIDworker_H
                                      
                                      #include <QObject>
                                      #include <QtSerialPort>
                                      
                                      
                                      
                                      class RFIDworker : public QObject
                                      {
                                          Q_OBJECT
                                      
                                      public:
                                          explicit RFIDworker(QObject *parent= nullptr);
                                      
                                      
                                      public slots:
                                          void start();
                                          void stop();
                                      
                                      private slots:
                                         void checkRFID();
                                         void ledTimer();
                                      
                                      signals:
                                          void newTag(QString tagID, int tagValue);
                                      
                                      private:
                                         QSerialPort *RFIDserial;
                                         QTimer *m_timer;
                                         bool m_ledState;
                                      };
                                      
                                      //======================================================================
                                      //************             RFID CR038 fonctions :               ****** //
                                      //======================================================================
                                      
                                      //*******************************************//
                                      //Turn on MiFare module LED subroutine
                                      void led_on(QSerialPort *RFIDport);
                                      
                                      //*******************************************//
                                      //Turn on MiFare module LED subroutine
                                      void led_off(QSerialPort *RFIDport);
                                      

                                      et du worker.cpp :

                                      RFIDworker::RFIDworker(QObject *parent): QObject(parent)
                                          , RFIDserial(Q_NULLPTR)
                                          , m_timer(Q_NULLPTR)
                                          , m_ledState(false)
                                      {
                                      }
                                      
                                      void RFIDworker::start()
                                      {
                                          if(!m_timer)
                                              {
                                                  m_timer = new QTimer(this);
                                                  m_timer->setSingleShot(false);
                                                  m_timer->setInterval(400);
                                                  connect(m_timer, &QTimer::timeout, this, &RFIDworker::ledTimer);
                                              }
                                      
                                          if(!RFIDserial)
                                          {
                                              RFIDserial = new QSerialPort(this);
                                              // serial port initialistion
                                              // ----- INIT SERIAL RFID ----//
                                              RFIDserial->setPortName("ttyUSB0");
                                              RFIDserial->setBaudRate(QSerialPort::Baud19200);
                                              RFIDserial->setDataBits(QSerialPort::Data8);
                                              RFIDserial->setParity(QSerialPort::NoParity);
                                              RFIDserial->setStopBits(QSerialPort::OneStop);
                                              RFIDserial->setFlowControl(QSerialPort::NoFlowControl);
                                              RFIDserial->open(QIODevice::ReadWrite);
                                      
                                              connect(RFIDserial, &QSerialPort::readyRead, this, &RFIDworker::checkRFID);
                                      
                                              if (RFIDserial->isOpen() == true)
                                              {
                                                  qDebug() << "Serial ttyUSB0(USB0) is opened";
                                              }
                                              else
                                              {
                                                  qDebug() << "Connexion impossible RFID ! ";
                                              }
                                              // lancement timer
                                              m_timer->start();
                                      
                                      
                                          }
                                      }
                                      
                                      void RFIDworker::stop()
                                      {
                                          if(serialRFID && serialRFID->isOpen())
                                          {
                                              serialRFID->close();
                                          }
                                          if(m_timer && m_timer->isActive())
                                                  m_timer->stop();
                                      }
                                      
                                      void RFIDworker::ledTimer()
                                      {
                                          if(m_ledState)
                                              led_on(RFIDserial);
                                          else
                                              led_off(RFIDserial);
                                          m_ledState = !m_ledState;
                                          qDebug() << "passage dans Ledtimer";
                                      }
                                      
                                      void RFIDworker::checkRFID()
                                      {
                                          while(!RFIDserial->atEnd())
                                              {
                                                  qDebug() << "passage dans checkRFID";
                                                  //QByteArray rfIdRaw = RFIDserial->readAll();
                                                  // process data
                                                  /*
                                                  if(!tag.isEmpty())
                                                      emit newTag(tag, value);
                                                  */
                                              }
                                      }
                                      
                                      
                                      //======================================================================
                                      //************             RFID CR038 fonctions :               ****** //
                                      //======================================================================
                                      
                                      
                                      //******************************************
                                      //Turn on MiFare module LED subroutine
                                      void led_on(QSerialPort *RFIDport)
                                      {
                                        // on envoit tout d'un coup !
                                        QByteArray da(LED_ON, sizeof(LED_ON));
                                        RFIDport->write(da);
                                        //delay(200)
                                        QByteArray ba;
                                        while(!RFIDport->isOpen());
                                        ba = RFIDport->readAll();
                                        qDebug() << "reception LED_ON :" << ba;
                                      }
                                      
                                      //*******************************************
                                      //Turn on MiFare module LED subroutine
                                      void led_off(QSerialPort *RFIDport)
                                      {
                                      
                                         QByteArray da(LED_OFF, sizeof(LED_OFF));
                                         RFIDport->write(da);
                                         QByteArray ba;
                                         //delay(200)
                                         while(!RFIDport->isOpen());
                                         ba = RFIDport->readAll();
                                         qDebug() << "reception LED_OFF :" << ba;
                                      }
                                      
                                      

                                      Coté init dans le mainwindow j'ai rien changé ....

                                      en réponse console j'ai :

                                      Serial ttyUSB0(USB0) is opened
                                       Thread RFID lancé !
                                      

                                      donc le worker a bien été lancé ainsi que le thread RFID.

                                      Une idée ? J'ai oublié un truc ?

                                      J'ai essayé d'échanger Tx et Rx coté connectique mais rien ne se passe...
                                      et je devrais quand même avoir des lignes de debug coté worker qui indique le déroulement du ledtimer...

                                      J'essaye de coller au mieu à la "QT conforme" mais vu que mon projet est a cheval entre une IHM et de l'embarqué pur c'est pas simple...

                                      Merci pour votre aide ;)

                                      KroMignonK Offline
                                      KroMignonK Offline
                                      KroMignon
                                      wrote on last edited by KroMignon
                                      #18

                                      @jym92 said in Problème en lecture/écriture de badge RFID mifare classic avec Raspberry et CR038:

                                      Coté init dans le mainwindow j'ai rien changé ....

                                      Le problème est là à mon avis, est-ce ton thread est une instance de QThread?
                                      Est-ce que tu as bien supprimé ta classe RFIDthread qui ne sert à rien?

                                      //auto* rfThread = new RFIDthread();
                                      auto* rfThread = new QThread();
                                      

                                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                      1 Reply Last reply
                                      0
                                      • J jym92

                                        Bonjour,

                                        Tout d'abord je vous remercie pour vos conseils et je commence à petit à petit à saisir la logique un peu tordu de Qt ;p

                                        J'ai du coup modifier mon worker pour passer le port serie en private à la classe et j'ai mis en place le fonctionnement via le timer au lieu de la boucle infini.

                                        Cependant le timer ne démarre pas alors qu'au vu des lignes de debug tout semble bien se lancer sauf le timer ...

                                        voici le code du worker.h :

                                        #ifndef RFIDworker_H
                                        #define RFIDworker_H
                                        
                                        #include <QObject>
                                        #include <QtSerialPort>
                                        
                                        
                                        
                                        class RFIDworker : public QObject
                                        {
                                            Q_OBJECT
                                        
                                        public:
                                            explicit RFIDworker(QObject *parent= nullptr);
                                        
                                        
                                        public slots:
                                            void start();
                                            void stop();
                                        
                                        private slots:
                                           void checkRFID();
                                           void ledTimer();
                                        
                                        signals:
                                            void newTag(QString tagID, int tagValue);
                                        
                                        private:
                                           QSerialPort *RFIDserial;
                                           QTimer *m_timer;
                                           bool m_ledState;
                                        };
                                        
                                        //======================================================================
                                        //************             RFID CR038 fonctions :               ****** //
                                        //======================================================================
                                        
                                        //*******************************************//
                                        //Turn on MiFare module LED subroutine
                                        void led_on(QSerialPort *RFIDport);
                                        
                                        //*******************************************//
                                        //Turn on MiFare module LED subroutine
                                        void led_off(QSerialPort *RFIDport);
                                        

                                        et du worker.cpp :

                                        RFIDworker::RFIDworker(QObject *parent): QObject(parent)
                                            , RFIDserial(Q_NULLPTR)
                                            , m_timer(Q_NULLPTR)
                                            , m_ledState(false)
                                        {
                                        }
                                        
                                        void RFIDworker::start()
                                        {
                                            if(!m_timer)
                                                {
                                                    m_timer = new QTimer(this);
                                                    m_timer->setSingleShot(false);
                                                    m_timer->setInterval(400);
                                                    connect(m_timer, &QTimer::timeout, this, &RFIDworker::ledTimer);
                                                }
                                        
                                            if(!RFIDserial)
                                            {
                                                RFIDserial = new QSerialPort(this);
                                                // serial port initialistion
                                                // ----- INIT SERIAL RFID ----//
                                                RFIDserial->setPortName("ttyUSB0");
                                                RFIDserial->setBaudRate(QSerialPort::Baud19200);
                                                RFIDserial->setDataBits(QSerialPort::Data8);
                                                RFIDserial->setParity(QSerialPort::NoParity);
                                                RFIDserial->setStopBits(QSerialPort::OneStop);
                                                RFIDserial->setFlowControl(QSerialPort::NoFlowControl);
                                                RFIDserial->open(QIODevice::ReadWrite);
                                        
                                                connect(RFIDserial, &QSerialPort::readyRead, this, &RFIDworker::checkRFID);
                                        
                                                if (RFIDserial->isOpen() == true)
                                                {
                                                    qDebug() << "Serial ttyUSB0(USB0) is opened";
                                                }
                                                else
                                                {
                                                    qDebug() << "Connexion impossible RFID ! ";
                                                }
                                                // lancement timer
                                                m_timer->start();
                                        
                                        
                                            }
                                        }
                                        
                                        void RFIDworker::stop()
                                        {
                                            if(serialRFID && serialRFID->isOpen())
                                            {
                                                serialRFID->close();
                                            }
                                            if(m_timer && m_timer->isActive())
                                                    m_timer->stop();
                                        }
                                        
                                        void RFIDworker::ledTimer()
                                        {
                                            if(m_ledState)
                                                led_on(RFIDserial);
                                            else
                                                led_off(RFIDserial);
                                            m_ledState = !m_ledState;
                                            qDebug() << "passage dans Ledtimer";
                                        }
                                        
                                        void RFIDworker::checkRFID()
                                        {
                                            while(!RFIDserial->atEnd())
                                                {
                                                    qDebug() << "passage dans checkRFID";
                                                    //QByteArray rfIdRaw = RFIDserial->readAll();
                                                    // process data
                                                    /*
                                                    if(!tag.isEmpty())
                                                        emit newTag(tag, value);
                                                    */
                                                }
                                        }
                                        
                                        
                                        //======================================================================
                                        //************             RFID CR038 fonctions :               ****** //
                                        //======================================================================
                                        
                                        
                                        //******************************************
                                        //Turn on MiFare module LED subroutine
                                        void led_on(QSerialPort *RFIDport)
                                        {
                                          // on envoit tout d'un coup !
                                          QByteArray da(LED_ON, sizeof(LED_ON));
                                          RFIDport->write(da);
                                          //delay(200)
                                          QByteArray ba;
                                          while(!RFIDport->isOpen());
                                          ba = RFIDport->readAll();
                                          qDebug() << "reception LED_ON :" << ba;
                                        }
                                        
                                        //*******************************************
                                        //Turn on MiFare module LED subroutine
                                        void led_off(QSerialPort *RFIDport)
                                        {
                                        
                                           QByteArray da(LED_OFF, sizeof(LED_OFF));
                                           RFIDport->write(da);
                                           QByteArray ba;
                                           //delay(200)
                                           while(!RFIDport->isOpen());
                                           ba = RFIDport->readAll();
                                           qDebug() << "reception LED_OFF :" << ba;
                                        }
                                        
                                        

                                        Coté init dans le mainwindow j'ai rien changé ....

                                        en réponse console j'ai :

                                        Serial ttyUSB0(USB0) is opened
                                         Thread RFID lancé !
                                        

                                        donc le worker a bien été lancé ainsi que le thread RFID.

                                        Une idée ? J'ai oublié un truc ?

                                        J'ai essayé d'échanger Tx et Rx coté connectique mais rien ne se passe...
                                        et je devrais quand même avoir des lignes de debug coté worker qui indique le déroulement du ledtimer...

                                        J'essaye de coller au mieu à la "QT conforme" mais vu que mon projet est a cheval entre une IHM et de l'embarqué pur c'est pas simple...

                                        Merci pour votre aide ;)

                                        KroMignonK Offline
                                        KroMignonK Offline
                                        KroMignon
                                        wrote on last edited by
                                        #19

                                        @jym92 said in Problème en lecture/écriture de badge RFID mifare classic avec Raspberry et CR038:

                                        'essaye de coller au mieu à la "QT conforme" mais vu que mon projet est a cheval entre une IHM et de l'embarqué pur c'est pas simple...

                                        Le mode de fonctionnement de Qt peut sembler à première vue un peu étrange, mais c'est en fait très performant. Donc, pour de l'embarquer pas un soucis, bien au contraire.
                                        Je te conseille vivement de prendre le temps de lire et comprendre les articles suivants:

                                        • https://woboq.com/blog/how-qt-signals-slots-work.html
                                        • https://woboq.com/blog/how-qt-signals-slots-work-part2-qt5.html
                                        • https://woboq.com/blog/how-qt-signals-slots-work-part3-queuedconnection.html

                                        Ceci va t'aider à mieux cerner la philosophie de Qt et le pourquoi comment du mécanisme signals/slots.

                                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                        1 Reply Last reply
                                        1
                                        • J Offline
                                          J Offline
                                          jym92
                                          wrote on last edited by
                                          #20

                                          Effectivement tu avais raison, je n'avais pas supprimé mon fichier RFIDThread car je pensais qu'il été utile a lancement de la classe et l'appel au niveau du mainwindow était faux...

                                          voila mon appel au niveau de mainwindow :

                                          // ------------ Lancement du Thread RFID worker -----------------//
                                              auto* rfThread = new QThread();
                                              auto* rfWorker = new RFIDworker();
                                          
                                              // start RF ID Reader on thread start
                                              connect(rfThread, &QThread::started, rfWorker , &RFIDworker::start);
                                              // stop RF ID Reader on main application exit
                                              connect(qApp, &QApplication::aboutToQuit, rfWorker, &QObject::deleteLater);
                                              // delete thread on worker end
                                              connect(rfWorker, &QObject::destroyed, rfThread, [rfThread](QObject *)
                                              {
                                                  if(rfThread->isRunning())
                                                  {
                                                       rfThread->quit();
                                                       rfThread->wait();
                                                  }
                                                  rfThread->deleteLater();
                                              }
                                              , Qt::DirectConnection);  // needs "DirectConnection" to work
                                              // to be informed about new RF ID tag
                                              //connect(rfWorker,  &RFIDworker::newTag, this, &MyMainClass::newRfIdTag);
                                              // move worker object to worker  thread
                                              rfWorker->moveToThread(rfThread);
                                              // last but not least, start worker thread
                                              rfThread->start();
                                          

                                          Du coup dans mon Thread tout fonctionne comme je le veux, à savoir j'envois des commandes via le Timer et je reçois automatiquement mes réponses dans CheckRFID ;)

                                          Cependant un autre problème apparaît que je suspectais déjà,à savoir l'envoi et la réception de données sur mon port série USB0 brouille ma réception de donnés sur le port UART5 qui est en l'air mais normalement relié à un PIC.

                                          Voila comment je déclare la communication série avec le PIC dans mon mainwindow :

                                          //----------------------- Parametrage de la liaison serie -------------------------------------- //
                                              QList<QSerialPortInfo> listPsi; // liste des ports série existant
                                              listPsi = QSerialPortInfo::availablePorts(); // récupère les ports série disponibles
                                          
                                              for(int i=0 ; i<listPsi.size() ; i++)
                                               qDebug() << "Communiquer : " << listPsi.at(i).portName() <<" " << listPsi.at(i).description();
                                          
                                              serial = new QSerialPort(this);
                                          
                                              // se connecte au port série déja existant nommé "ttyAMA0"
                                          
                                              // remarque port serie (si uart0, uart4 et uart5 activé via config):
                                              // uart 0 = Ama0 pin8(tx) et 10(Rx)
                                              // USB0  // RFID PN532
                                              // uart 5 = Ama2 pin32 et 33 // PIC
                                              // ----- INIT SERIAL PIC ----//
                                              serial->setPortName("ttyAMA2");
                                              serial->setBaudRate(QSerialPort::Baud115200);
                                              serial->setDataBits(QSerialPort::Data8);
                                              serial->setParity(QSerialPort::NoParity);
                                              serial->setStopBits(QSerialPort::OneStop);
                                              serial->setFlowControl(QSerialPort::NoFlowControl);
                                              serial->open(QIODevice::ReadWrite);
                                          
                                              if (serial->isOpen() == true)
                                              {
                                                  qDebug() << "Serial ttyAMA2(uart5) is opened";
                                                  connect(serial, SIGNAL(readyRead()),this,SLOT(on_Received_Data()));
                                              }
                                              else
                                              {
                                                  qDebug() << "Connexion impossible PIC ! ";
                                              }
                                          
                                          

                                          et la reception des données je fais :

                                          // boucle activé sur reception de données serie :
                                          void MainWindow::on_Received_Data()
                                          {
                                              // ------- choses à faire - RX side -------
                                              qDebug() << "reception données :";
                                              QByteArray ba;
                                              ba = serial->readAll();
                                              ui->label_uart_pic->setText("Données reçues : " + ba );
                                              qDebug() << ba;
                                          
                                          }
                                          

                                          Le fonctionnement est quasi le meme que pour le rfid j'ai un timer qui tourne qui vérifie l'état d'un bouton poussoir et qui suivant son état allume une led et envoie un une commande au Pic qui lui répond.

                                          Une idée pour résoudre ce conflit au niveau des port séries ?
                                          Y'a pas moyen de d'interdire au mainwindow l'accés au port USB0 ?

                                          ce genre de problème est juste impensable coté C embarqué classique ;)
                                          ( on envoi/reçoit sur un port et un port en l'air reçoit des données...)

                                          Un grand merci pour ton aide @KroMignon !

                                          KroMignonK 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved