Partage
  • Partager sur Facebook
  • Partager sur Twitter

Port série lecture - écriture avec unity3D

    6 décembre 2021 à 1:33:28

    Bonjour à tous.

    Cela fait quelques jours que je me casse la tête sur cela...

    Je voudrais communiquer avec un lecteur avaleur RFID (KYT1121) avec Unity3D (bien meilleurs perfs graphique que visual studio)

    A l'origine j'avais fait le code en visual basique et ca fonctionne parfaitement depuis plus de 3 ans. Cependant, le passage en c# me pose pas mal de soucis. Le soucis à l'origine de ce post est que je peux envoyer une trame (1 0 0 3 2 67 49 54 3 70) sur le port série, mais je n'arrive pas a voir la réponse du lecteur qui devrait être : 1 0 0 7 2 67 49 54 0 0 1 0 3 67

    using UnityEngine;
    using System.IO.Ports;
    using UnityEngine.UI;
    using System.Threading;
    using System;
    public class PortSerieAvaleur : MonoBehaviour
    {
    
        SerialPort serial1;
        public string Port;
        public int Vitesse;
        public int Parite;
        public int NbBit;
        public int StopBit;
        public string Num_badge;
        public float timer1;
        public float Preset1_Tick_Lecture;
        public float timer2;
        public float Preset2_Tick_RazBadge;
        public Text Champ_num_badge;
        public Sprite LecteurHS;
        public Sprite LecteurStandBy;
        public Sprite LecteurOK;
        public Image LecteurImage;
        public bool position;
        private Thread receiveThread;
    
        // Start is called before the first frame update
        void Start()
        {
            serial1 = new SerialPort();     
            serial1.PortName = Port;
            serial1.BaudRate = Vitesse;
            serial1.DataBits = NbBit;
            serial1.ReadTimeout = 100;
            if (StopBit == 0){
                serial1.StopBits = StopBits.None;
            }   else if (StopBit == 1){
                serial1.StopBits = StopBits.One;
            }   else if (StopBit == 2){
                serial1.StopBits = StopBits.Two;
            }
            if (Parite == 0){
                serial1.Parity = Parity.None;
            } else if(Parite == 1){
                serial1.Parity = Parity.Even;
            } else if(Parite == 2){
                serial1.Parity = Parity.Odd;
            }
    
            serial1.Handshake = Handshake.None;
            serial1.RtsEnable = true;
            serial1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
        }
    
        public void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Thread lecture_badge = new Thread(Read); //Création du thread de lecture
            lecture_badge.Start(); //Démarrage du thread
        }
     
        public void Read()
        {
            if (serial1.IsOpen && serial1.BytesToRead > 0) Num_badge = serial1.ReadLine(); 
            Thread.CurrentThread.Abort(); 
        }
    
        private byte XORChecksum(byte[] trame)
        {
            int loops;
            byte checksum;
            int taille = trame.Length;
            checksum = 0;
            for (loops = 0; loops <= trame.Length - 1; loops++)
                checksum = (byte) (checksum ^ trame[loops]);
            return checksum;
        }
        bool Position()
        {
            byte[] trame;
            byte[] trame2;
            trame2 = new byte[] { 0, 0, 3, 2, 67, 49, 54, 3 };
            trame = new byte[] { 1, 0, 0, 3, 2, 67, 49, 54, 3, XORChecksum(trame2) };
            serial1.Write(trame, 0, trame.Length);
            Debug.Log("trame envoyée : " + trame[0] + " " + trame[1]+ " " + trame[2]+ " " + trame[3]+ " " + trame[4]+ " " + trame[5]+ " " + trame[6]+ " " + trame[7]+ " " + trame[8]+ " " + trame[9]) ;
            return true;
        }
    
    
        void Update()
        {
            timer1+=Time.deltaTime;
            if ( timer1 >= Preset1_Tick_Lecture){
                if (serial1.IsOpen){
                    Debug.Log("COM ouvert");
                    LecteurImage.sprite = LecteurStandBy;
                    try{
                            if (position){
                                position = false;
                                Num_badge = serial1.ReadLine();
    
                            }else{
                                position = Position();
                            }
                        
                    }catch (System.IO.IOException ex){
                        Debug.Log("Pas de lecteur detecté");
                        serial1.Close();
    
                        
                    }catch (TimeoutException ex){
                        Debug.Log("En attente d'un badge");
                    }
                } else {
                    Debug.Log("COM non ouvert");
                    LecteurImage.sprite = LecteurHS;
                    try{
                        serial1.Open();
                    }catch (System.IO.IOException ex){
                        Debug.Log("Pas de lecteur sur le port COM");
                        
                    }
                }
                timer1 = 0;
            }
        }
    
        void FixedUpdate()
        {
            if (Time.frameCount % 120 == 0)
            {
                System.GC.Collect();
            }
        }
    }
    

    Si quelqu'un peut me filer un coup de main svp :)

    -
    Edité par Elda 6 décembre 2021 à 8:23:43

    • Partager sur Facebook
    • Partager sur Twitter
      6 décembre 2021 à 14:04:35

      Salut,

      Je vois plusieurs problème dans ton code, déjà pourquoi est-ce que tu as un thread de lecture comme tu l'appelles?

      Dans cette fonction Read qui est appelé dans ton thread:

          public void Read()
          {
              if (serial1.IsOpen && serial1.BytesToRead > 0) Num_badge = serial1.ReadLine();
              Thread.CurrentThread.Abort();
          }
       

      Ce code est appelé une seule fois (donc l'abort ne sert à rien du coup), et manipuler un port série dans plusieurs thread (sans synchro) ce n'est pas trop conseillé.

      Tu devrais regardé ce qui est fait ici: https://docs.microsoft.com/fr-fr/dotnet/api/system.io.ports.serialport.datareceived?view=dotnet-plat-ext-6.0

      Et ReadLine ne fonctionnera que si ta ligne (donc on suppose que ce sont des caractere et pas du binaire?) fini par un '\n' ou en tout cas ce que tu as mis dans NewLine.


      Elda a écrit:

      avec Unity3D (bien meilleurs perfs graphique que visual studio)


      Euh là je te suis pas.. C'est quoi l'idée? Juste lire un ID et l'afficher ? Ça tu peux le faire dans une console, ou même une appli winform/wpf si tu veux une interface graphique.

      Pourquoi utiliser Unity ? En plus de ça tu peux pas comparer Unity et Visual Studio ce sont deux choses totalement différentes (un moteur de jeu et un IDE) qui en plus sont faite pour fonctionner ensemble.

      Je serai toi, je regarderai de plus prés comment fonctionne les ports COM en C#, et je ferai une appli console qui fait le minimum de communication pour valider le fonctionnement.

      PS: Appeler le GC.Collect manuellement c'est inutile dans 99.99% des cas (et ça ne fait que ralentir le soft).

      • Partager sur Facebook
      • Partager sur Twitter
      Fatalement vôtre
        6 décembre 2021 à 22:43:39

        Bonjour,

        Merci pour ta réponse.

        En fait j'ai déjà essayé pas mal de choses dont le lien que tu as mis au dessus, mais sans résultat. Je pensais que le fait d'utiliser un thread pour la lecture allait me limiter les arrêts du au fait que je n'avais pas de \n (l'appli figeait, je ne savais pas trop pourquoi).

        Dans tous les cas, je n'arrive jamais dans le 

        public void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) {}

        même lorsque je mets un simple Debug.Log("reception"); dans la fonction , je n'ai rien.

        Pour que le lecteur envoie quelque chose, je dois l'interroger obligatoirement. il n'envoi rien sinon.

        Pour ce qui est de mes préférences d'utiliser unity, j'ai peut être tord mais vu que j'utilise pas mal d'animations... Dans tous les cas puisque ce n'est pas la question et que je veux éviter les hors sujet on ne va plus en parler :)

        Et pour ce qui est du GC.Collect, j'ai vu sur un autre site que c'était une bonne pratique, n'étant pas expert, j'ai juste appliqué et pour le moment je n'ai rien vu en bien ou en mal ^^ Mais je prends note.

        • Partager sur Facebook
        • Partager sur Twitter
          7 décembre 2021 à 8:23:49

          Salut,

          Avant d'aller plus loin, je te conseille d'utiliser une logiciel de com série (comme hterm) pour debug ta com et vérifier que tu n'as pas de souci à ce niveau là.

          Une fois que tu es sûr des trames à envoyer et recevoir, tu pourra essayer d'aller plus loin (idéalement poste une capture d'écran).

          Et même si tu veux utiliser Unity pour ton projet, je te conseille quand même de faire un projet console de base qui :

          • Ouvre le port
          • Envoie la trame d'interrogation
          • Lit la trame de retour

          Ça te permettra de t'abstraire des scripts (avec les start/update) et la notion de temps. Parce que honnêtement je t'avoue que ta fonctionne Update je n'arrive pas à comprendre ce qu'elle fait avec tous ces if. Est-ce qu'au moins tu es sûr qu'elle envoie la trame d’interrogation ?

          PS: Prend l'habitude d'utiliser le débugueur et les points d'arrêt plutôt que les logs pour débuguer, tu gagnera tu temps ;)

          • Partager sur Facebook
          • Partager sur Twitter
          Fatalement vôtre
            7 décembre 2021 à 10:03:55

            Je suis d'accord à 100% avec @ D.Fate.

            De plus, pour faire de l'animation "2D" même relativement complexe, WPF fait largement l'affaire. Pas besoin d'installer tout un moteur de jeu pour faire 2/3 animations de textes qui tourne.

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              7 décembre 2021 à 15:11:15

              Pour la lecture du port, tu utilises 2 méthodes qui se télescopent:

              avec l'événement DataReceivedHandler, tu fais une réception asynchrone (l'événement se déclenche quand il y a des données à lire (un nombre d'octets non déterminé et pouvant changer entre 2 événements)

              ou avec le ReadLine() de la ligne 100 de façon "synchrone" qui attend de lire une ligne (donc dans ton cas, à changer en Read probablement)

              De plus selon la doc de ton lecteur (p15 de https://www.lettoricarte.it/wp-content/uploads/2020/05/kyt11XXREV_L.pdf ) il y a un échange d'acquittement après l'envoi d'une commande Commande  -> ACK(NAK) -> ENQ ->[traitement] -> Réponse -> ACK(NAK)

              • Partager sur Facebook
              • Partager sur Twitter
                8 décembre 2021 à 18:42:59

                Merci à tous pour vos réponses.

                Pour ce qui est de la comm entre le lecteur et le pc, j'ai déjà fait l'application complète sous VB.net et ça fonctionne très bien depuis des années. Mais les besoins ont changé et par soucis d'uniformité nous avons retenu Unity par rapport à visual studio. Seulement, unity fonctionne en c# et visiblement c# et VB n'ont pas tout a fait le même fonctionnement sur ce qui concerne le port COM.

                Le code au dessus n'est qu'une petite partie pour justement faire des essais et il y a pas mal de choses qui doivent dégager je l'accorde.

                Je vais commencer par suivre le premier conseil a savoir tout virer de ce qui est inutile en mode console effectivement.

                La partie avec tous les IF est une reprise d'un lecteur serie qui ne fait qu'envoyer un code lorsque le badge s'approche du lecteur. Je n'ai pas trouvé de moyen simple de faire un readLine() sans planter l'application si aucun badge n'est lu (ca fige). Du coup j'ai mis un timeout de 100ms mais qui me fait remonter une exception que je traite par un simple 

                }catch (TimeoutException ex){
                                    Debug.Log("En attente d'un badge");
                                }

                Peut être que c'est ici qu'il faille que j'utilise un thread dédié en fait. Mais cela ne concerne pas ce lecteur.

                Pour ce qui est de WPF, je ne connaissais pas du tout. Je me renseignerais dessus certainement, mais pour le moment nous avons d'autres projets avec Unity et comme il fallait commencer avec un projet dessus....

                Enfin, effectivement le lecteur attends un ack après chaque trame qu'il envoie. Le cycle est donc :

                Appli transmet un ordre pour savoir si il y a un badge présent => lecteur renvoie la commande => l'appli acquitte => le lecteur envoie la réponse... Cependant, tant que je ne recevais pas une réponse de la part du lecteur, je ne suis pas allé plus loin.

                Et pour la présence des 2 lectures, c'est un oubli de suppression au niveau du readLine(), j'ai juste voulu tester des fois que, mais avec ce lecteur c'est forcement avec le DataReceivedHandler

                Je vais donc commencer par faire un essai simple sous visual studio en c# et si jamais je reste bloqué je reviendrais vers vous. Merci encore

                -
                Edité par Elda 8 décembre 2021 à 18:45:39

                • Partager sur Facebook
                • Partager sur Twitter
                  8 décembre 2021 à 19:24:56

                  Dans ton cas, tu vas avoir plusieurs type de DataReceivedHandler je pense, selon où tu te situes dans la communication; du moins il faut que tu saches ce que tu es censé recevoir et renvoyer selon la réponse reçue.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 décembre 2021 à 21:36:21

                    >j'ai déjà fait l'application complète sous VB.net et ça fonctionne très bien depuis des années.

                    VB.NET et C# utilise le Framework .NET pour accéder au système, un code écrit en VB.NET qui fonctionne à 99,99% de chance de fonctionner de la même manière en C#. Seule la syntaxe change. Et vous pouvez très facilement mixer du VB.NET et du C#, tant que vous ne faites pas entrer dans la boucle Unity3D qui n'est pas "que" .NET.

                    >Mais les besoins ont changé et par soucis d'uniformité nous avons retenu Unity par rapport à visual studio.

                    Vous comparez des choux et des carottes. L'éditeur de code par défaut d'Unity3D, c'est Visual Studio !!!

                    https://docs.unity3d.com/2021.2/Documentation/Manual/VisualStudioIntegration.html

                    Visual Studio n'est qu'un IDE. Si vous n'arrivez pas à vos fin avec Visual Studio, le problème est entre la chaise et le clavier.

                    >Seulement, unity fonctionne en c#

                    Nope.

                    Unity3D, le moteur est en C++, les scripts sont en C# mais ils sont retranscrit en C++ pour les plateformes ne "supportant" pas .NET. JavaScript a été très longtemps le langage de script d'Unity3D. En utilisant Unity3D, vous ajoutez une couche d'abstraction/complexité.

                    >et visiblement c# et VB n'ont pas tout a fait le même fonctionnement sur ce qui concerne le port COM.

                    Très très peu probable car ils utilisent les mêmes librairies (les BCL .NET). Plus probablement une erreur dans votre conversion VB.NET -> C#.

                    >A l'origine j'avais fait le code en visual basique

                    Attention, VB(6), c'est pas du tout la même chose que VB.NET.

                    Vous êtes sûr que "XORChecksum(trame2)" donne bien 70 ?

                    Tenter une ouverture de port COM à chaque Update, c'est pas très bien. En plus, vous avez un temps limité d'exécution dans cette méthode, sortez ce truc d'Update.

                    Idem pour le ReadLine et le Write dans Update, c'est pas fait pour !!!

                    >Je n'ai pas trouvé de moyen simple de faire un readLine() sans planter l'application si aucun badge n'est lu (ca fige).

                    Avez-vous utilisé les appels asynchrones, cela permet de ne pas avoir besoin de thread supplémentaire juste pour de simple Read et Write.

                    Franchement, je ne vois pas pourquoi vous ne vous contentez pas de faire une simple "conversion" de VB.NET vers C#, il existe toute une palanqué d'outil qui le font pour vous.

                    https://converter.telerik.com/

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                      9 décembre 2021 à 21:09:32

                      Merci pour votre réponse.

                      Le choix d'Unity comme je le disais précédement n'est pas fait pour le lecture de badge, mais parce qu'on aimerait faire de l'animation 3D et le remplacement de notre application de lecture de badge série était une façon de se familiariser avec l'éditeur (même si l'IDE reste presque le même car j'utilise VScode au lieu de VS).

                      Comme dit plus haut, je ne connaissais pas le WPF et j'ai donc choisi ce que je "connaissais" déjà un peu.

                      Lorsque je parle de visual basic (et non basique comme j'ai pu le marquer....) je fais bien référence à VB.NET et non VB6. J'ai déjà essayé de passer l'application avec le convertisseur, mais il n'arrive pas a la convertir. Du coup j'ai voulu reprendre à 0 toujours dans l'optique de se familiariser .

                      Je ne prétend pas du tout être un grand développeur, je suis automaticien de métier et les notions élémentaires pour certains ne le sont pas forcement pour moi. 

                      Dans l'UPDATE je ne fais pas d'ouverture de port en continu

                       timer1+=Time.deltaTime;
                              if ( timer1 >= Preset1_Tick_Lecture){
                                  if (serial1.IsOpen){
                      else {
                      try{
                      serial1.Open();

                      Si au bout de X secondes, si le port série est ouvert, alors je fais quelque chose, sinon j'essaie d'ouvrir le port série, sinon je fais rien.

                      Vous êtes sûr que "XORChecksum(trame2)" donne bien 70 ?

                      Sur à 100%, testé en VB et C#. Ayant le matériel et l'ancien programme, j'ai pu controler tout ça

                      Pour le temps dans l'update, je ne savais pas que c'était limité, il me semblait que c'était le code exécuté en boucle un peu à la manière d'un Arduino avec la fonction loop().

                      Avez-vous utilisé les appels asynchrones, cela permet de ne pas avoir besoin de thread supplémentaire juste pour de simple Read et Write.

                      C'est bien la le problème, je n'arrive pas a mettre en œuvre 

                      public void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
                          

                      en fait, même quand j'essaye un type de lecteur qui n'a pas besoin d'être interrogé pour envoyé des trames (pour le coup avec un \n en fin de chaine) la fonction ci dessus ne s'exécute jamais. lorsque je fais juste le code minimal de ce lien :  https://docs.microsoft.com/fr-fr/dotnet/api/system.io.ports.serialport.datareceived?view=dotnet-plat-ext-6.0    je n'obtiens rien

                      Même lorsque je fais le code ci dessus avec cette modif :

                          private static void DataReceivedHandler(
                                              object sender,
                                              SerialDataReceivedEventArgs e)
                          {
                              Debug.Log("DataReceive");
                          }

                      Je n'ai rien dans la console.

                      J'ai essayé de faire ce code dans visual studio en mode console...... Il ne reconnait pas le type serialport malgré le using System.IO.Ports; (qui au passage, me dit qu'il sert a rien...) je deviens chèvre sans blague! j'ai essayé de vérifié que j'avais bien .NET4.8, core 5.0 (testé en 3.1). j'ai essayé d'ajouter la DLL aux références.... j'avoue que la je ne comprends pas du tout... Alors que sous Unity, je n'ai pas de soucis pour utiliser System.IO.Ports.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        10 décembre 2021 à 8:33:15

                        Salut,

                        Y'a moyen que tu mette ton projet console à disposition ? Ce sera plus simple pour t'aider.

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Fatalement vôtre
                          10 décembre 2021 à 11:51:32

                          Pour le test fait avec le code minimal, tu as bien adapté la configuration du port (numéro du port, baud, start, stop, ...) par rapport à ton lecteur ?

                          Tu as essayé le code vb.net équivalent (il suffit de changer le langage en haut de la page pour avoir le code équivalent VB)

                          Tu as redémarré le PC, des fois que le port soit planté

                          • Partager sur Facebook
                          • Partager sur Twitter
                            10 décembre 2021 à 13:58:18

                            >mais parce qu'on aimerait faire de l'animation 3D

                            Ok, j'ai pas plus simple pour intégrer des animations 3D à une application, va pour Unity3D.

                            >même si l'IDE reste presque le même car j'utilise VScode au lieu de VS

                            Là, c'est que vous ne maîtrisez pas tout ce qu'apporte Visual Studio en plus par rapport à VS Code "nu".

                            >et j'ai donc choisi ce que je "connaissais" déjà un peu.

                            Évitez de faire des choix par ignorance. ;-)

                            >J'ai déjà essayé de passer l'application avec le convertisseur, mais il n'arrive pas a la convertir.

                            Pouvez-vous nous poster une partie "significative" du code VB.NET, le code C# généré, les éventuelles erreurs indiquées par le convertisseur et les erreurs à la compilation du code généré ?

                            Il y a de gros chance que le problème ne soit pas dans la conversion mais dans la configuration de l'outil ou du projet cible.

                            >Dans l'UPDATE je ne fais pas d'ouverture de port en continu

                            Oups, mal lu.

                            Mais le temps à consacrer à l'exécution à Update est limité car elle est appelée à chaque frame et pour tous les game object de la scène, donc pas d'entrée/sortie. Unity regorge de primitives pour éviter ces problèmes, comme les coroutines, etc...

                            >Sur à 100%, testé en VB et C#. Ayant le matériel et l'ancien programme, j'ai pu controler tout ça

                            Ca aurait été mieux de dire que vous avez vérifié avec le débogueur. Le débogueur est votre ami, vraiment.

                            >il me semblait que c'était le code exécuté en boucle un peu à la manière d'un Arduino avec la fonction loop().

                            Oui, mais n'oubliez pas les contraintes d'affichage.

                            >C'est bien la le problème, je n'arrive pas a mettre en œuvre

                            Pour les appels asynchrones, je pensais plus à ReadAsync et WriteAsync :

                            https://stackoverflow.com/questions/24041378/c-sharp-async-serial-port-read

                            https://stackoverflow.com/questions/33226414/correct-implementation-of-async-serialport-read

                            Quelle version du framework .NET votre version d'Unity3D est sensé émulé/bridgé ?

                            >je deviens chèvre sans blague! j'ai essayé de vérifié que j'avais bien .NET4.8, core 5.0

                            Attention, en fonction de la version du frameworl, l'assembly contenant la classe "SerialPort", change :

                            https://docs.microsoft.com/fr-fr/dotnet/api/system.io.ports.serialport?view=netframework-4.8

                            => Assembly: System.dll

                            https://docs.microsoft.com/fr-fr/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-6.0

                            =>Assembly: System.IO.Ports.dll

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                              10 décembre 2021 à 21:14:46

                              Bonjour à tous et merci pour vos réponses,

                              voici le code de l'ancienne application (sur pastebin)

                              https://pastebin.com/31T3EuUB (form1)

                              https://pastebin.com/pcCJe23U (module1)

                              https://pastebin.com/nt5uZx7t (cls_ini)

                              Je sais bien que c'est pas la plus belle des applis, mais le fonctionnement est nickel! C'est avec cela que ça tourne sans problème.

                              En gros l'appli prend n'importe quel type de lecteur parmis 3 type :

                              RS232-ASCII => donne le code badge des qu'il est présenté sous forme de chaine de caractere

                              RS232-Avaleur => le fameux avec qui j'essaye de causer

                              USB-BC => un type similaire a l'avaleur mais sans la partie mécanique a faire bouger, il suffit juste de demander la lecture en continu

                              La partie qui nous interesse le plus est celle la : Form1.vb ligne 389 à 455

                                  Public Sub PortSerie_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles PortSerie.DataReceived
                                      PortSerieOQP = True
                              
                                      'si on travail avec le lecteur avaleur
                                      If TypeLecteur = "RS232-AVALEUR" Then
                                          Dim enqEnvoye As Boolean = False
                                          Dim longueurTrame As Integer = 0
                                          Dim data(30) As Byte 'octets reçus du lecteur avaleur
                                          Thread.Sleep(10) 'attente de la réception des données
                                          file = My.Computer.FileSystem.OpenTextFileWriter("c:\temp\traceLB.log", True)
                                          Dim datetimefr As String = DateTime.Now.ToString("dd/MM/yyyy") + " " + DateTime.Now.ToString("HH:mm") + " : "
                                          Try
                                              PortSerie.Read(data, 0, 30) 'mise en place des octets reçus dans la variable data
                              
                                              Dim tramerecue As String = "Trame reçue : " + CStr(data(0)) + " " + CStr(data(1)) + " " + CStr(data(2)) + " " + CStr(data(3)) + " " + CStr(data(4)) + " " + CStr(data(5)) + " " + CStr(data(6)) + " " + CStr(data(7)) + " " + CStr(data(8)) + " " + CStr(data(9)) + " " + CStr(data(10)) + " " + CStr(data(11)) + " " + CStr(data(12)) + " " + CStr(data(13)) + " " + CStr(data(14)) + " " + CStr(data(15)) + " " + CStr(data(16)) + " " + CStr(data(17)) + " " + CStr(data(18)) + " " + CStr(data(19))
                              
                                              file.WriteLine(datetimefr + tramerecue + vbCrLf)
                              
                                          Catch ex As Exception
                                              'MsgBox("ERREUR COMMUNICATION LECTEUR")
                                              Try
                                                  file.WriteLine(datetimefr + ex.Message + vbCrLf)
                                                  PortSerie.Close()
                                              Catch ex2 As Exception
                              
                                              End Try
                              
                                              Return
                                          End Try
                                          file.Close()
                              
                                          TraceEvenement("Trame reçue : " + CStr(data(0)) + " " + CStr(data(1)) + " " + CStr(data(2)) + " " + CStr(data(3)) + " " + CStr(data(4)) + " " + CStr(data(5)) + " " + CStr(data(6)) + " " + CStr(data(7)) + " " + CStr(data(8)) + " " + CStr(data(9)) + " " + CStr(data(10)) + " " + CStr(data(11)) + " " + CStr(data(12)) + " " + CStr(data(13)) + " " + CStr(data(14)) + " " + CStr(data(15)) + " " + CStr(data(16)) + " " + CStr(data(17)) + " " + CStr(data(18)) + " " + CStr(data(19)) + " ", "INFO")
                                          'Dim trameRecu As String = ""
                                          'Dim traduction As String = ""
                                          If data(0) = 21 Then 'si la trame n'est pas acquité par le lecteur de badge, la réponse commencera pas 21 sur l'octet 0
                                          ElseIf data(0) = 6 And enqEnvoye = False Then 'si la trame est valide, alors la réponse sera 6 sur le premier octet
                                              PortSerie.Write(Chr(5)) 'envoie de l'enquery pour valider la trame précedente
                                              TraceEvenement("Trame envoyée : " + CStr(Chr(5)), "INFO")
                                              enqEnvoye = True
                                          Else
                                              If data(5) = 67 And data(6) = 49 And data(7) = 54 Then 'si la trame reçue provient de la commande C16 alors on regarde la position du badge
                                                  positionbadge = CStr(data(11))
                                              End If
                                              If data(5) = 82 And data(6) = 54 And data(7) = 49 Then 'si la trame reçue provient de la commande R61
                                                  If data(8) = 35 And data(9) = 5 Then 'si la réponse est 0x3505 alors le badge est illisible
                                                      tentative += 1
                                                  Else
                                                      codeBadgeHexa = CStr(Hex(data(14))) + CStr(Hex(data(13))) + CStr(Hex(data(12))) + CStr(Hex(data(11))) 'sinon on converti le code badge hexa en décimal
                                                      TraceEvenement("Numéro de badge HEX : " + codeBadgeHexa, "INFO")
                                                      Dim l As Long
                                                      l = data(14)
                                                      NumBadgePhysique = l * 16777216 + data(13) * 65536 + data(12) * 256 + data(11)
                                                      presenceBadge = True
                                                      TraceEvenement("Numéro de badge DEC : " + NumBadgePhysique, "INFO")
                                                      If NumBadgePhysique <> 0 Then
                                                          etat = 3
                                                      End If
                                                  End If
                                              End If
                                              Try
                                                  PortSerie.Write(Chr(6))
                                              Catch ex As Exception
                                                  Return
                                                  'MsgBox("ERREUR DE COMMUNICATION")
                                              End Try
                                          End If
                                      End If


                              juste pour l'exemple, je viens de tester la conversion (et de tous les fichiers) et ça marche, alors que j'avais déjà essayé avant avec ce même site de conversion :/ par contre je n'ai pas encore fait le test, je verrais demain.

                              Pour le code version mini de chez mini : (COM11 9600 8 bits 1 stop pas de parité)

                              using System;
                              using System.IO.Ports;
                              
                              class PortDataReceived
                              {
                                  public static void Main()
                                  {
                                      SerialPort mySerialPort = new SerialPort("COM11");
                              
                                      mySerialPort.BaudRate = 9600;
                                      mySerialPort.Parity = Parity.None;
                                      mySerialPort.StopBits = StopBits.One;
                                      mySerialPort.DataBits = 8;
                                      mySerialPort.Handshake = Handshake.None;
                                      mySerialPort.RtsEnable = true;
                              
                                      mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                              
                                      mySerialPort.Open();
                              
                                      //Console.WriteLine("Press any key to continue...");
                                      //Console.WriteLine();
                                      //Console.ReadKey();
                                      //mySerialPort.Close();
                                  }
                              
                                  private static void DataReceivedHandler(
                                                      object sender,
                                                      SerialDataReceivedEventArgs e)
                                  {
                                      SerialPort sp = (SerialPort)sender;
                                      string indata = sp.ReadExisting();
                                      Console.WriteLine("Data Received:");
                                      Console.Write(indata);
                                  }
                              }

                              Et ça me dit :

                              Ce qui est drôle, c'est que ça me dit aussi que le using System.IO.Ports est inutile (je ne comprends pas!!!!)

                              Lorsque je veux ajouter une référence, je ne trouve pas System.IO.Ports

                              Merci pour le temps que vous passer la dessus

                              • Partager sur Facebook
                              • Partager sur Twitter
                                12 décembre 2021 à 11:35:56

                                Vous avez pas mal de code "non trivial", je vous conseille d'utiliser GitHub ou GitLab pour simplifier le partage du code.

                                Je ne vois rien qui poserait problème à une conversion automatique, sauf, peut-être les "Handles"

                                https://stackoverflow.com/questions/794332/migrating-handles-from-vb-net-to-c-sharp

                                (Notez les simplifications en C# (syntaxical sugar) qu'indique la réponse)

                                Ces "Handles" correspondent aux problèmes que vous indiquez mais vous semblez bien maitriser la version "de base", c'est pour ça qu'on n'a du mal à déterminer comment régler facilement votre problème.

                                Il y a pas mal d'archaïsme (les valeur en dure, les .ini, les delegate, etc...) dans votre code VB.NET mais c'est pas le sujet (cela ne semble pas être en lien avec votre problème actuel mais attention, les archaïsmes à un moment donné, ça par en sucette).

                                >je viens de tester la conversion (et de tous les fichiers) et ça marche,

                                Les réglages par défaut ou le convertisseur lui-même ont peut-être changés.

                                Comme je l'ai déjà indiqué, la configuration de votre projet change en fonction du Framework cible de votre projet.

                                Le message d'erreur semble montrer une version postérieure à .NET 4.8. Etes vous sur d'avoir le framework cible de votre application installée sur votre machine de développement ?

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                  14 décembre 2021 à 13:00:54

                                  tu dois avoir choisi un projet en Core et non pas en Framework NET.
                                  Adapte la cible; ou passe par Nuget pour ajouter la référence

                                  -
                                  Edité par umfred 14 décembre 2021 à 13:01:06

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    23 décembre 2021 à 18:25:04

                                    Bonjour bonjour,

                                    Merci pour vos réponses et désolé de ne pas avoir fait de retour plus tôt, j'étais sur d'autres problèmes.

                                    Alors du coup j'ai fait un bout de code en C# .net winform sous visual studio et ça tourne nickel :

                                    using System;
                                    using System.Collections.Generic;
                                    using System.ComponentModel;
                                    using System.Data;
                                    using System.Drawing;
                                    using System.Linq;
                                    using System.Text;
                                    using System.Threading.Tasks;
                                    using System.Windows.Forms;
                                    using System.IO.Ports;
                                    using System.Threading;
                                    
                                    namespace WindowsFormsApp1
                                    {
                                        public partial class Form1 : Form
                                        {
                                            SerialPort mySerialPort = new SerialPort("COM9");
                                            static string valeur="";
                                            static string NumBadgePhysique = "";
                                            static string codeBadgeHexa = "";
                                            static bool dmdAck = false;
                                            static string pos = "";
                                    
                                            public Form1()
                                            {
                                                InitializeComponent();
                                            }
                                    
                                            private void Form1_Load(object sender, EventArgs e)
                                            {
                                                
                                    
                                                mySerialPort.BaudRate = 38400;
                                                mySerialPort.Parity = Parity.None;
                                                mySerialPort.StopBits = StopBits.One;
                                                mySerialPort.DataBits = 8;
                                                mySerialPort.Handshake = Handshake.None;
                                                mySerialPort.RtsEnable = true;
                                    
                                                mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                                    
                                                mySerialPort.Open();
                                            }
                                    
                                            private static void DataReceivedHandler(
                                                            object sender,
                                                            SerialDataReceivedEventArgs e)
                                            {
                                                Thread.Sleep(100);
                                                SerialPort sp = (SerialPort)sender;
                                                int bytetoread = sp.BytesToRead;
                                                int[] decimales = new int[bytetoread];
                                                for (int i = 0; i < bytetoread; i++)
                                                {
                                                    decimales[i] = sp.ReadByte();
                                                    valeur += $"{decimales[i]} ";
                                                }
                                    
                                                if (decimales.Length > 14)
                                                {
                                                    if (decimales[5] == 82 & decimales[6] == 54 & decimales[7] == 49)
                                                    {
                                                        codeBadgeHexa = System.Convert.ToString(decimales[14]) + System.Convert.ToString(decimales[13]) + System.Convert.ToString(decimales[12]) + System.Convert.ToString(decimales[11]);
                                                        long l;
                                                        l = decimales[14];
                                                        NumBadgePhysique = Convert.ToString(l * 16777216 + decimales[13] * 65536 + decimales[12] * 256 + decimales[11]);
                                    
                                                    }
                                                    if (decimales[5] == 67 & decimales[6] == 49 & decimales[7] == 54)
                                                    {
                                                        if (decimales[11] == 0)
                                                        {
                                                            pos = "absent";
                                                        }
                                                        if (decimales[11] == 1)
                                                        {
                                                            pos = "En position";
                                                        }
                                                        if (decimales[11] == 4)
                                                        {
                                                            pos = "Dans la fente";
                                                        }
                                                        if (decimales[11] == 5)
                                                        {
                                                            pos = "en chemin";
                                                        }
                                                        if (decimales[11] == 2)
                                                        {
                                                            pos = "trop loin";
                                                        }
                                                    }
                                                }
                                    
                                                //if (decimales[0] == 1)
                                                //{
                                                //    dmdAck = true;
                                                //}
                                    
                                    
                                            }
                                    
                                            bool Position()
                                            {
                                                byte[] trame;
                                                byte[] trame2;
                                                trame2 = new byte[] { 0, 0, 3, 2, 67, 49, 54, 3 };
                                                trame = new byte[] { 1, 0, 0, 3, 2, 67, 49, 54, 3, XORChecksum(trame2) };
                                                mySerialPort.Write(trame, 0, trame.Length);
                                                listBox1.Items.Add("trame envoyée : " + trame[0] + " " + trame[1] + " " + trame[2] + " " + trame[3] + " " + trame[4] + " " + trame[5] + " " + trame[6] + " " + trame[7] + " " + trame[8] + " " + trame[9]);
                                                Thread.Sleep(100);
                                                enq();
                                                return true;
                                            }
                                    
                                            bool LectureRFID()
                                            {
                                                byte[] trame;
                                                byte[] trame2;
                                                trame2 = new byte[] { 0, 0, 3, 2, 82, 54, 49, 3 };
                                                trame = new byte[] { 1, 0, 0, 3, 2, 82, 54, 49, 3, XORChecksum(trame2) };
                                                mySerialPort.Write(trame, 0, trame.Length);
                                                listBox1.Items.Add("trame envoyée : " + trame[0] + " " + trame[1] + " " + trame[2] + " " + trame[3] + " " + trame[4] + " " + trame[5] + " " + trame[6] + " " + trame[7] + " " + trame[8] + " " + trame[9]);
                                                Thread.Sleep(100);
                                                enq();
                                                return true;
                                            }
                                            bool Rentrer()
                                            {
                                                byte[] trame;
                                                byte[] trame2;
                                                trame2 = new byte[] { 0, 0, 3, 2, 67, 51, 53, 3 };
                                                trame = new byte[] { 1, 0, 0, 3, 2, 67, 51, 53, 3, XORChecksum(trame2) };
                                                mySerialPort.Write(trame, 0, trame.Length);
                                                listBox1.Items.Add("trame envoyée : " + trame[0] + " " + trame[1] + " " + trame[2] + " " + trame[3] + " " + trame[4] + " " + trame[5] + " " + trame[6] + " " + trame[7] + " " + trame[8] + " " + trame[9]);
                                                Thread.Sleep(100);
                                                enq();
                                                return true; 
                                            }
                                    
                                            bool Restitution()
                                            {
                                                byte[] trame;
                                                byte[] trame2;
                                                trame2 = new byte[] { 0, 0, 3, 2, 67, 51, 54, 3 };
                                                trame = new byte[] { 1, 0, 0, 3, 2, 67, 51, 54, 3, XORChecksum(trame2) };
                                                mySerialPort.Write(trame, 0, trame.Length);
                                                listBox1.Items.Add("trame envoyée : " + trame[0] + " " + trame[1] + " " + trame[2] + " " + trame[3] + " " + trame[4] + " " + trame[5] + " " + trame[6] + " " + trame[7] + " " + trame[8] + " " + trame[9]);
                                                Thread.Sleep(100);
                                                enq();
                                                return true;
                                            }
                                    
                                            bool Aspirer()
                                            {
                                                byte[] trame;
                                                byte[] trame2;
                                                trame2 = new byte[] { 0, 0, 3, 2, 67, 51, 55, 3 };
                                                trame = new byte[] { 1, 0, 0, 3, 2, 67, 51, 55, 3, XORChecksum(trame2) };
                                                mySerialPort.Write(trame, 0, trame.Length);
                                                listBox1.Items.Add("trame envoyée : " + trame[0] + " " + trame[1] + " " + trame[2] + " " + trame[3] + " " + trame[4] + " " + trame[5] + " " + trame[6] + " " + trame[7] + " " + trame[8] + " " + trame[9]);
                                                Thread.Sleep(100);
                                                enq();
                                                return true;
                                            }
                                    
                                    
                                    
                                    
                                    
                                    
                                            bool enq()
                                            {
                                                byte[] trame;
                                                byte[] trame2;
                                                trame = new byte[] { 5 };
                                                mySerialPort.Write(trame, 0, trame.Length);
                                                listBox1.Items.Add("trame envoyée : " + trame[0]);
                                                return true;
                                            }
                                    
                                            bool ack()
                                            {
                                                byte[] trame;
                                                byte[] trame2;
                                                trame = new byte[] { 6 };
                                                mySerialPort.Write(trame, 0, trame.Length);
                                                listBox1.Items.Add("trame envoyée : " + trame[0]);
                                                return true;
                                            }
                                    
                                            private byte XORChecksum(byte[] trame)
                                            {
                                                int loops;
                                                byte checksum;
                                                int taille = trame.Length;
                                                checksum = 0;
                                                for (loops = 0; loops <= trame.Length - 1; loops++)
                                                    checksum = (byte)(checksum ^ trame[loops]);
                                                return checksum;
                                            }
                                    
                                            private void button1_Click(object sender, EventArgs e)
                                            {
                                                LectureRFID();
                                            }
                                    
                                            private void button2_Click(object sender, EventArgs e)
                                            {
                                                enq();
                                    
                                            }
                                    
                                            private void timer1_Tick(object sender, EventArgs e)
                                            {
                                                if (valeur != "")
                                                {
                                                    listBox1.Items.Add(valeur);
                                                    valeur = "";
                                                }
                                                label1.Text = NumBadgePhysique;
                                                if (dmdAck)
                                                {
                                                    dmdAck = false;
                                                    ack();
                                                }
                                                label2.Text = pos;
                                            }
                                    
                                            private void button3_Click(object sender, EventArgs e)
                                            {
                                                Aspirer();
                                            }
                                    
                                            private void button4_Click(object sender, EventArgs e)
                                            {
                                                Restitution();
                                            }
                                    
                                            private void button5_Click(object sender, EventArgs e)
                                            {
                                                Rentrer();
                                            }
                                    
                                    
                                    
                                            private void button6_Click_1(object sender, EventArgs e)
                                            {
                                                Position();
                                            }
                                        }
                                    }
                                    

                                    j'ai physiquement le resultat exacte qu'il me faut. (même si des fois je vois des choses étranges sur le port serie...)

                                    Par contre, lorsque je recopie le minimum dans unity, ca ne veut rien savoir... je n'obtiens jamais rien en lecture. Les commandes passent (j'arrive a piloter le lecteur) mais je n'arrive jamais au 

                                    Debug.Log("biiiiiiip");



                                    Voici le code Unity

                                    using UnityEngine;
                                    using System.IO.Ports;
                                    using UnityEngine.UI;
                                    using System.Threading;
                                    using System;
                                    public class PortSerieAvaleur : MonoBehaviour
                                    {
                                    
                                        SerialPort serial1;
                                        public string Port;
                                        public int Vitesse;
                                        public int Parite;
                                        public int NbBit;
                                        public int StopBit;
                                        public string Num_badge;
                                            public bool Permut;
                                        public float timer1;
                                        public float Preset1_Tick_Lecture;
                                        public float timer2;
                                        public float Preset2_Tick_RazBadge;
                                        public Text Champ_num_badge;
                                        public Sprite LecteurHS;
                                        public Sprite LecteurStandBy;
                                        public Sprite LecteurOK;
                                        public Image LecteurImage;
                                        public bool position;
                                        private Thread receiveThread;
                                    
                                        static string valeur = "";
                                        static string NumBadgePhysique = "";
                                        static string codeBadgeHexa = "";
                                        static bool dmdAck = false;
                                        static string pos = "";
                                    
                                        public string pvaleur = "";
                                        public string pNumBadgePhysique = "";
                                        public string pcodeBadgeHexa = "";
                                        public bool pdmdAck = false;
                                        public string ppos = "";
                                    
                                    
                                        // Start is called before the first frame update
                                        void Start()
                                        {
                                            serial1 = new SerialPort();     
                                            serial1.PortName = Port;
                                            serial1.BaudRate = Vitesse;
                                            serial1.DataBits = NbBit;
                                            serial1.ReadTimeout = 100;
                                            if (StopBit == 0){
                                                serial1.StopBits = StopBits.None;
                                            }   else if (StopBit == 1){
                                                serial1.StopBits = StopBits.One;
                                            }   else if (StopBit == 2){
                                                serial1.StopBits = StopBits.Two;
                                            }
                                            if (Parite == 0){
                                                serial1.Parity = Parity.None;
                                            } else if(Parite == 1){
                                                serial1.Parity = Parity.Even;
                                            } else if(Parite == 2){
                                                serial1.Parity = Parity.Odd;
                                            }
                                    
                                            serial1.Handshake = Handshake.None;
                                            serial1.RtsEnable = true;
                                            serial1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                                        }
                                    
                                       
                                    
                                    
                                    
                                    
                                        private byte XORChecksum(byte[] trame)
                                        {
                                            int loops;
                                            byte checksum;
                                            int taille = trame.Length;
                                            checksum = 0;
                                            for (loops = 0; loops <= trame.Length - 1; loops++)
                                                checksum = (byte) (checksum ^ trame[loops]);
                                            return checksum;
                                        }
                                        bool Position()
                                        {
                                            byte[] trame;
                                            byte[] trame2;
                                            trame2 = new byte[] { 0, 0, 3, 2, 67, 49, 54, 3 };
                                            trame = new byte[] { 1, 0, 0, 3, 2, 67, 49, 54, 3, XORChecksum(trame2) };
                                            serial1.Write(trame, 0, trame.Length);
                                            Debug.Log("longueur trame : " + trame.Length);
                                            Debug.Log("trame envoyée : " + trame[0] + " " + trame[1]+ " " + trame[2]+ " " + trame[3]+ " " + trame[4]+ " " + trame[5]+ " " + trame[6]+ " " + trame[7]+ " " + trame[8]+ " " + trame[9]) ;
                                            enq();
                                            return true;
                                        }
                                        bool enq()
                                        {
                                            byte[] trame;
                                            byte[] trame2;
                                            trame = new byte[] { 5 };
                                            serial1.Write(trame, 0, trame.Length);
                                            Debug.Log("trame envoyée : " + trame[0]);
                                            return true;
                                        }
                                    
                                        void Update()
                                        {
                                            timer1+=Time.deltaTime;
                                    
                                                pvaleur = valeur;
                                                pNumBadgePhysique = NumBadgePhysique;
                                                pcodeBadgeHexa = pcodeBadgeHexa;
                                                pdmdAck = pdmdAck;
                                                ppos = ppos;
                                    
                                    
                                            if ( timer1 >= Preset1_Tick_Lecture){
                                                if (serial1.IsOpen){
                                                    Debug.Log("COM ouvert");
                                                    LecteurImage.sprite = LecteurStandBy;
                                                    try{
                                                            if (position){
                                    
                                                            position = false;
                                                            }else{
                                                                position = Position();
                                                            }
                                                        
                                                    }catch (System.IO.IOException ex){
                                                        Debug.Log("Pas de lecteur detecté");
                                                        serial1.Close();
                                    
                                                        
                                                    }catch (TimeoutException ex){
                                                        Debug.Log("En attente d'un badge");
                                                    }
                                                } else {
                                                    Debug.Log("COM non ouvert");
                                                    LecteurImage.sprite = LecteurHS;
                                                    try{
                                                        serial1.Open();
                                                    }catch (System.IO.IOException ex){
                                                        Debug.Log("Pas de lecteur sur le port COM");
                                                        
                                                    }
                                                }
                                                timer1 = 0;
                                            }
                                        }
                                    
                                        private static void DataReceivedHandler(
                                                        object sender,
                                                        SerialDataReceivedEventArgs e)
                                        {
                                            Debug.Log("biiiiiiip");
                                            Thread.Sleep(100);
                                            SerialPort sp = (SerialPort)sender;
                                            int bytetoread = sp.BytesToRead;
                                            int[] decimales = new int[bytetoread];
                                            for (int i = 0; i < bytetoread; i++)
                                            {
                                                decimales[i] = sp.ReadByte();
                                                valeur += $"{decimales[i]} ";
                                            }
                                    
                                            if (decimales.Length > 14)
                                            {
                                                if (decimales[5] == 82 & decimales[6] == 54 & decimales[7] == 49)
                                                {
                                                    codeBadgeHexa = System.Convert.ToString(decimales[14]) + System.Convert.ToString(decimales[13]) + System.Convert.ToString(decimales[12]) + System.Convert.ToString(decimales[11]);
                                                    long l;
                                                    l = decimales[14];
                                                    NumBadgePhysique = Convert.ToString(l * 16777216 + decimales[13] * 65536 + decimales[12] * 256 + decimales[11]);
                                    
                                                }
                                                if (decimales[5] == 67 & decimales[6] == 49 & decimales[7] == 54)
                                                {
                                                    if (decimales[11] == 0)
                                                    {
                                                        pos = "absent";
                                                    }
                                                    if (decimales[11] == 1)
                                                    {
                                                        pos = "En position";
                                                    }
                                                    if (decimales[11] == 4)
                                                    {
                                                        pos = "Dans la fente";
                                                    }
                                                    if (decimales[11] == 5)
                                                    {
                                                        pos = "en chemin";
                                                    }
                                                    if (decimales[11] == 2)
                                                    {
                                                        pos = "trop loin";
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    

                                    Si quelqu'un veut encore se casser la tête la dessus, je peux même faire une prise de main via TeamViewer avec une cam sur le lecteur pour les plus courageux ^^

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      23 décembre 2021 à 19:30:12

                                      il est où l'endroit où tu indiques que tu utilises le port com9 (ou autre) (autrement dit, où tu indiques Port="COM9")

                                      Sinon il semblerait que Mono (utilisé par Unity) ne prend pas en charge les événements de réception du port série; donc il faudrait créer une tâche qui lise en continu (avec un timeout) le port série (polling).

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        23 décembre 2021 à 20:24:08

                                        C'est la lecture d'un fichier ini d'un autre script qui s'occupe d'écrire le port com.

                                        Le soucis c'est que si je fais du readLine() je n'aurais jamais rien puisque les trames attendues n'ont pas de \n :/

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          23 décembre 2021 à 22:08:25

                                          C'est donc une limitation du Framework sous-jacent pour le système hôte du moteur Unity.

                                          Un exemple de contournement datant de 2019 :

                                          stackoverflow.com/questions/26591189/c-sharp-serialport-eventhandler-in-unity


                                          EDIT :

                                          >Le soucis c'est que si je fais du readLine() ...

                                          Utilisez soit des Read asynchrone (si le Framework le supporte réellement) ou des Read avec TimeOut.

                                          https://stackoverflow.com/questions/24041378/c-sharp-async-serial-port-read

                                          https://docs.microsoft.com/fr-fr/dotnet/api/system.io.ports.serialport.readtimeout?view=dotnet-plat-ext-6.0

                                          -
                                          Edité par bacelar 23 décembre 2021 à 22:19:44

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                            27 décembre 2021 à 15:44:09

                                            Bonjour,

                                            En fait j'ai bien l'impression qu'Unity n'a que le readline de disponible et donc je suis dans l'impasse avec ce lecteur.

                                            Avec un lecteur ASCII classique ça fonctionne pas mal avec ce code :

                                            using System.Collections;
                                            using System.Collections.Generic;
                                            using UnityEngine;
                                            using System.IO.Ports;
                                            using UnityEngine.UI;
                                            using System.Threading;
                                            using System;
                                            public class PortSerieASCII : MonoBehaviour
                                            {
                                            
                                                SerialPort serial1;
                                                public string Port;
                                                public int Vitesse;
                                                public int Parite;
                                                public int NbBit;
                                                public int StopBit; 
                                                public string Num_badge;
                                                public bool Permut;
                                                public float timer1;
                                                public float Preset1_Tick_Lecture;
                                                public float timer2;
                                                public float Preset2_Tick_RazBadge;
                                                public Text Champ_num_badge;
                                                public Sprite LecteurHS;
                                                public Sprite LecteurStandBy;
                                                public Sprite LecteurOK;
                                                public Image LecteurImage;
                                            
                                                // Start is called before the first frame update
                                                void Start()
                                                {
                                                    serial1 = new SerialPort();     
                                                    serial1.PortName = Port;
                                                    serial1.BaudRate = Vitesse;
                                                    serial1.DataBits = NbBit;
                                                    serial1.ReadTimeout = 100;
                                                    if (StopBit == 0){
                                                        serial1.StopBits = StopBits.None;
                                                    }   else if (StopBit == 1){
                                                        serial1.StopBits = StopBits.One;
                                                    }   else if (StopBit == 2){
                                                        serial1.StopBits = StopBits.Two;
                                                    }
                                                    if (Parite == 0){
                                                        serial1.Parity = Parity.None;
                                                    } else if(Parite == 1){
                                                        serial1.Parity = Parity.Even;
                                                    } else if(Parite == 2){
                                                        serial1.Parity = Parity.Odd;
                                                    }
                                                
                                            
                                                }
                                              
                                                public void SetPort(string PortAConfig)
                                                {
                                                    Port = PortAConfig;
                                                }
                                            
                                                void Update()
                                                {
                                                    timer1+=Time.deltaTime;
                                                    if ( timer1 >= Preset1_Tick_Lecture){
                                                        if (serial1.IsOpen){
                                                            Debug.Log("COM ouvert");
                                                            LecteurImage.sprite = LecteurStandBy;
                                                            try{
                                                                    
                                                                    Num_badge = serial1.ReadLine();
                                                                    Debug.Log(Num_badge);
                                                                    if (Num_badge.Length == 9){Num_badge = "0"+Num_badge;}
                                                                    LecteurImage.sprite = LecteurOK;
                                                                    timer2 = 0;
                                                                
                                                            }catch (System.IO.IOException ex){
                                                                Debug.Log("Pas de lecteur detecté");
                                                                serial1.Close();
                                            
                                                                
                                                            }catch (TimeoutException ex){
                                                                Debug.Log("En attente d'un badge");
                                                            }
                                                        } else {
                                                            Debug.Log("COM non ouvert");
                                                            LecteurImage.sprite = LecteurHS;
                                                            try{
                                                                serial1.Open();
                                                            }catch (System.IO.IOException ex){
                                                                Debug.Log("Pas de lecteur sur le port COM");
                                                                
                                                            }
                                                        }
                                                        timer1 = 0;
                                                    }
                                                    timer2+=Time.deltaTime;
                                                    if (timer2 >= Preset2_Tick_RazBadge){
                                                        timer2 = 0;
                                                        Num_badge = "";
                                                        if (serial1.IsOpen){
                                                        LecteurImage.sprite = LecteurStandBy;
                                                        }
                                                    }
                                                    Champ_num_badge.text = Num_badge;
                                                }
                                            }
                                            

                                            Afin de ne pas resté bloqué ou d'utiliser un thread pour la lecture, j'utilise le timeout a 100ms. C'est assez réactif pour ce dont j'en ai besoin.

                                            Par contre, puisque l'autre n'a pas de \n, je pense que je vais m'orienter vers un arduino qui s'occupera de la gestion du lecteur et renverra les infos utiles avec un \n directement. Après tout, la partie enquery et ack peuvent être traité directement dans l'arduino. De plus, ca fera un lecteur USB en prime ^^ voir Ethernet si j'utilise un esp32-poe

                                            En tout cas merci pour le temps passé sur le sujet :)

                                            Bonnes fêtes de fin d'années.

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              27 décembre 2021 à 21:09:53

                                              Pourquoi les "contournements" indiqués ne conviennent pas  ???
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                3 janvier 2022 à 13:21:22

                                                en remplaçant le ReadLine par un Read(buffer, start,count) avec un peu de gestion du buffer si nécessaire; ça devrait aussi fonctionner
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Port série lecture - écriture avec unity3D

                                                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                • Editeur
                                                • Markdown