Annonce

Réduire
Aucune annonce.

Cockpit maison avec Arduino (comment faire) ?

Réduire
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • #1
    Toutes les variables ont-elles été définies?
    Les variables sont-elles utilisées selon leur type correct? Je vois déjà une erreur dans le premier code:
    Code:
    void EnvoyerDonneesX_Plane (char DonneesDeReference[], float Donnees_A_Communiquer)
    définit le deuxième paramètre "Donnees_A_Communiquer" comme un float, mais
    Code:
    [B]const int BOUTON_RADIO_COM_2 = 3;
    RadiosActive = BOUTON_RADIO_COM_2;
            EnvoyerDonneesX_Plane ("sim/cockpit/radios/nav_com_adf_mode", RadiosActive);[/B]
    utilise ce deuxième paramètre comme un entier.

    "CarteEthernetUDP" est-elle bien définie comme une instance EthernetUDP?

    Pour incrémenter la variable i, on n'écrit pas "i = i + 1" mais i++".

    Quand on envoie une Dataref, il faut compléter le texte de la Dataref par des espaces, CHAR(32), ce qui est fait, mais il faut également marquer la fin du message par un caractère nul, CHAR(0), ce qui manque.
    Ce caractère doit être présent au début du dernier groupe de 4 bytes/octets, c'est-à-dire :
    Nombre total de caractères du message = 500 => insérer un caractère nul en position 500-4+1=497.
    Il faut donc ajouter une instruction
    Code:
    PaquetUDP_Donnees [497] = char (0);
    avant d'envoyer le paquet.


    Modification : j'ai déduit le numéro 497 du site b58.svglobe.com mais, j'aurais plutôt mis 496 car l'indice commence à zéro. A essayer...
    Dernière modification par FlyingBaldy, 23 juillet 2014, 16h04. Motif: position incertaine du caractère de fin de message
    XP11.41 - WIN 7 - i7 - GTX970

    Commentaire


    • #1
      Envoyé par FlyingBaldy Voir le message
      ...Pour incrémenter la variable i, on n'écrit pas "i = i + 1" mais i++"....
      C'est équivalent, le résultat sera le même. Si l'on veut chipoter il vaut mieux utiliser ++i puisque cela indique au compilateur dès le début que ce sera une opération d'incrémentation qu'il va falloir exécuter. Dans le cas d'un entier ça ne change pas grand-chose, mais ça peut avoir des impacts avec d'autres types, c'est donc une bonne habitude à prendre.

      PhM
      X-Plane 9.70 & 11.5r1 / W10 / AMD Ryzen 7 2700 / 8Go RAM / Sapphire R9 390 Nitro 8Go / Sapphire HD7870 GHz 2Go / Samsung LN40C530 / Oculus DK2 / LeapMotion / Saitek X56 / Thrustmaster Pendular Rudder

      Commentaire


      • #1
        Bonjour FlyingBaldy,

        Je ne peux que commencer qu'en vous remerciant pour votre précieuse aide !

        Envoyé par FlyingBaldy Voir le message
        Toutes les variables ont-elles été définies?
        Les variables sont-elles utilisées selon leur type correct? Je vois déjà une erreur dans le premier code:
        Code:
        void EnvoyerDonneesX_Plane (char DonneesDeReference[], float Donnees_A_Communiquer)
        définit le deuxième paramètre "Donnees_A_Communiquer" comme un float, mais
        Code:
        [B]const int BOUTON_RADIO_COM_2 = 3;
        RadiosActive = BOUTON_RADIO_COM_2;
                EnvoyerDonneesX_Plane ("sim/cockpit/radios/nav_com_adf_mode", RadiosActive);[/B]
        utilise ce deuxième paramètre comme un entier.
        Alors voilà ce que je viens de faire.

        J'ai dupliqué et modifié le code de la procédure « EnvoyerDonneesX_Plane » pour les « float » et les « int » en ajoutant la ligne suggérée « PaquetUDP_Donnees [496] = char (0);», mais je ne suis vraiment pas sûr de l'avoir placé au bon endroit. Cela donne :

        Pour les « float » :

        //************************************************** ***************************
        // FONCTION EnvoyerDonneesX_Plane
        //************************************************** ***************************
        void EnvoyerDonneesX_Plane (char DonneesDeReference [], float Donnees_A_Communiquer)
        // Send PaquetUDP_Donnees ( PaquetUDP_Donnees and ValeurFormat1Float)
        {
        CodeSituation = 49;
        int n = 0;
        while (DonneesDeReference [n])
        {
        PaquetUDP_Donnees [n] = DonneesDeReference [n];
        n = n + 1;
        }
        for (int i = n; i < 500; i = i + 1)
        {
        PaquetUDP_Donnees [i] = char (32);
        }
        CarteEthernetUDP.beginPacket (X_PLANE_ADRESSE_IP, X_PLANE_ADRESSE_UDP);
        CarteEthernetUDP.write ("DREF0");
        TemponComUDP.ValeurFormat1Float = Donnees_A_Communiquer;
        for (int i = 0; i < 4; i = i + 1)
        {
        CarteEthernetUDP.write (TemponComUDP.ValeurFormat4Byte [i]);
        }
        PaquetUDP_Donnees [496] = char (0);
        CarteEthernetUDP.write (PaquetUDP_Donnees);
        CarteEthernetUDP.endPacket ();
        }
        //************************************************** ***************************
        Pour les « int » :

        //************************************************** ***************************
        // FONCTION EnvoyerDonneesX_Plane
        //************************************************** ***************************
        void EnvoyerDonneesX_Plane (char DonneesDeReference [], int Donnees_A_Communiquer)
        // Send PaquetUDP_Donnees ( PaquetUDP_Donnees and ValeurFormat1Float)
        {
        CodeSituation = 49;
        int n = 0;
        while (DonneesDeReference [n])
        {
        PaquetUDP_Donnees [n] = DonneesDeReference [n];
        n = n + 1;
        }
        for (int i = n; i < 500; i = i + 1)
        {
        PaquetUDP_Donnees [i] = char (32);
        }
        CarteEthernetUDP.beginPacket (X_PLANE_ADRESSE_IP, X_PLANE_ADRESSE_UDP);
        CarteEthernetUDP.write ("DREF0");
        for (int i = 0; i < 4; i = i + 1)
        {
        TemponComUDP.ValeurFormat4Byte [i] = Donnees_A_Communiquer;
        CarteEthernetUDP.write (TemponComUDP.ValeurFormat4Byte [i]);
        }
        PaquetUDP_Donnees [496] = char (0);
        CarteEthernetUDP.write (PaquetUDP_Donnees);
        CarteEthernetUDP.endPacket ();
        }
        //************************************************** ***************************
        À l'exécution dans X-Plane, après l'appel de cette procédure (« int »), j'ai le message d'erreur suivant et plantage et sortie de X-Plane :


        POUR INFO

        I could not aplly the 'DREF' message!

        i recieved 500 bytes but needed 504 bytes!

        (inet.cpp:785)
        J'ai essayé avec la ligne « PaquetUDP_Donnees [497] = char (0);», mais :


        POUR INFO

        I could not aplly the 'DREF' message!

        i recieved 501 bytes but needed 504 bytes!

        (inet.cpp:785)
        J'ai essayé avec les lignes suivantes, mais avec le même résultat :

        Code:
        PaquetUDP_Donnees [498] = char (0);
        PaquetUDP_Donnees [499] = char (0);
        PaquetUDP_Donnees [500] = char (0);
        Avec cette dernière ligne, avec le « 500 », je n'ai pas de message d'erreur, mais il n'y a aucun changement dans X-Plane à l'utilisation de la procédure « EnvoyerDonneesX_Plane » pour la sélection de la radio.

        Selon les codes sources observés, j'ai noté qu'il y a une variante entre 500 et 501 pour la taille de « PaquetUDP_Donnees » :

        Code:
        char PaquetUDP_Donnees [500];
        et

        Code:
        char PaquetUDP_Donnees [501];
        Alors, avec :

        Code:
        PaquetUDP_Donnees [496] = char (0);
        PaquetUDP_Donnees [497] = char (0);
        Message d'erreur, et avec :

        Code:
        PaquetUDP_Donnees [500] = char (0);
        Je n'ai pas de message d'erreur, mais il n'y a aucun changement dans X-Plane à l'utilisation de la procédure « EnvoyerDonneesX_Plane ».

        Est-ce que tout cela donne une piste à suivre ?

        Envoyé par FlyingBaldy Voir le message
        "CarteEthernetUDP" est-elle bien définie comme une instance EthernetUDP?
        Oui :

        Code:
        // Objet EthernetUDP pour envoyer et recevoir des paquets UDP.
        EthernetUDP CarteEthernetUDP;
        Envoyé par FlyingBaldy Voir le message
        Pour incrémenter la variable i, on n'écrit pas "i = i + 1", mais i++".
        Là, je pense que nous pourrions avoir une grande discussion, mais pour résumer, je cherche à écrire un code source qui se lie le plus possible comme du français écrit, pour une part, c'est pédagogique pour les non-informaticiens programmeurs et d'autre part, pour ne pas passer son temps a déchiffrer le code source, mais le lire, littéralement. Le « i++ » et autre trucage du C et C++, me rend dingue avec ces raccourcis de paresseux du clavier. Mais bon, les goûts sont dans la nature, mais les miens ne vont pas dans cette direction.


        Envoyé par FlyingBaldy Voir le message
        Quand on envoie une Dataref, il faut compléter le texte de la Dataref par des espaces, CHAR(32), ce qui est fait, mais il faut également marquer la fin du message par un caractère nul, CHAR(0), ce qui manque.
        Ce caractère doit être présent au début du dernier groupe de 4 bytes/octets, c'est-à-dire :
        Nombre total de caractères du message = 500 => insérer un caractère nul en position 500-4+1=497.
        Il faut donc ajouter une instruction
        Code:
        PaquetUDP_Donnees [497] = char (0);
        avant d'envoyer le paquet.

        Modification : j'ai déduit le numéro 497 du site b58.svglobe.com, mais, j'aurais plutôt mis 496 car l'indice commence à zéro. A essayer...
        Merci d'apporter les explications avec la solution, éventuellement je comprendrai 100% du code source d'origine du site d'Arduino Cockpit Simulator et une plus petite partie de X-Plane.

        L'ami René
        Tous pour un et un pour tous !
        L'ami René
        Tous pour un et un pour tous !

        Ordi-1 : Intel i7-12700K 5GHz, RAM 128 Go, nVidia RTX 3080 10G, Téléviseur 55" 3840x2160, 3 écrans 1920x1080, Manettes Saitek X56.
        Linux Debian 13, X11, X-Plane 12.4.4-b2, Little NavMap v3.0.18, pilote nVidia 550.163.1.

        Ordi-2 : Intel i7-12700KF 5GHz, RAM 48 Go, Asus GeForce STRIX-GTX 1060 6G, 2 x Écran 1920x1080.
        Linux Kubuntu 26.04, XHSI 2.0 Beta 12 Alfa 5, pilote nVidia 535.309.

        Commentaire


        • #1
          Il va falloir que tu comprennes le format des données à envoyer plutôt que de tâtonner et d'essayer au petit bonheur, ça sera plus facile au final. Je ne peux pas faire grand chose car je n'ai jamais utilisé ce système, et je n'ai pas d'ethernet pour arduino.

          J'ai vu une chose intéressante au tout début de la page d'information dans X-Plane :

          NOTE: GO TO THE SETTINGS MENU, OPTIONS AND WARNINGS SCREEN, AND TURN ON THE "OUTPUT NET-ERROR FILE" (or similar) to have X-Plane dump the data that it is being given to the error.out file. This will slow down the sim a little, and take up some drive space, but you can leave it on for a little while as you get started, so that if your dtata transfer does NOT work, you can quit X-Plane, open the error.out file with a text editor, and see what (if any) error messages X-Plane is giving you.
          Il doit donc y avoir une option pour recevoir les erreurs dans un fichier texte et pouvoir les consulter pour déterminer ce qui ne va pas, ça serait peut-être une bonne idée d'autoriser cette option.

          PhM
          X-Plane 9.70 & 11.5r1 / W10 / AMD Ryzen 7 2700 / 8Go RAM / Sapphire R9 390 Nitro 8Go / Sapphire HD7870 GHz 2Go / Samsung LN40C530 / Oculus DK2 / LeapMotion / Saitek X56 / Thrustmaster Pendular Rudder

          Commentaire


          • #1
            Bonjour PhM,

            Voici avec quel genre de texte, je dois comprendre tous les rouages et subtilités de X-Plane (ou tout autre texte non francophone, on ne se refait pas à 52 ans). Ce qui suit est la traduction de Google de ton texte anglais :

            NOTE : Pour le MENU paramètres, OPTIONS et écran de mises en garde et tourner à sur le « fichier de NET-erreur de sortie » (ou similaire) d'avoir X-Plane vider les données qu'il est envisagé du fichier error.out. Cela va ralentir un peu de la carte sim et occupent peu d'espace disque, mais vous pouvez le laisser sur pendant un petit moment que vous vous lancer, afin que si votre transfert de dtata ne fonctionne pas, vous pouvez quitter X-Plane, ouvrez le fichier error.out avec un éditeur de texte et voir ce qui (le cas échéant) messages d'erreur X-Plane est de vous donner.
            Je fais du mieux que je peux, mais avec ce genre de texte, il est difficile d'y comprendre quelque chose par moment, il faut en convenir !

            Il me semble qu'il y a un dicton qui dit « Devant l'impossible, nul n'est tenu ! ». J'ai des qualités et des défauts, et être anglophone n'est fait pas partie, pas dans cette vie-ci. J'en suis le premier à le regretter ! Dyslexique de naissance, à 18 ans, j'étais analphabète, alors que je lis et écris tous les jours, c'est déjà du gros boulot. Il faudrait laisser une chance au coureur...

            L'ami René
            Tous pour un et un pour tous !
            L'ami René
            Tous pour un et un pour tous !

            Ordi-1 : Intel i7-12700K 5GHz, RAM 128 Go, nVidia RTX 3080 10G, Téléviseur 55" 3840x2160, 3 écrans 1920x1080, Manettes Saitek X56.
            Linux Debian 13, X11, X-Plane 12.4.4-b2, Little NavMap v3.0.18, pilote nVidia 550.163.1.

            Ordi-2 : Intel i7-12700KF 5GHz, RAM 48 Go, Asus GeForce STRIX-GTX 1060 6G, 2 x Écran 1920x1080.
            Linux Kubuntu 26.04, XHSI 2.0 Beta 12 Alfa 5, pilote nVidia 535.309.

            Commentaire


            • #1
              Essayer de tout traduire, étant donnée la qualité des traducteurs en ligne, n'est pas dans ce cas la bonne solution je pense. J'ai été vérifier dans X-Plane, simplement en me référant à ces mots extraits du texte précédent :

              "SETTINGS MENU" "OPTIONS AND WARNINGS" "OUTPUT NET-ERROR FILE"

              Et il y a une option "dump net data to log.txt" que l'on peut sélectionner. Je ne l'ai pas essayée puisque je n'ai rien qui passe par le chemin UDP X-Pplane, je sais donc pas si ça va être une optin utile dans ton cas.

              Cliquez sur l'image pour la voir en taille réelle 

Nom : 		Options.jpg 
Affichages :	1 
Taille :		104,6 Ko 
ID : 			457914

              PhM
              X-Plane 9.70 & 11.5r1 / W10 / AMD Ryzen 7 2700 / 8Go RAM / Sapphire R9 390 Nitro 8Go / Sapphire HD7870 GHz 2Go / Samsung LN40C530 / Oculus DK2 / LeapMotion / Saitek X56 / Thrustmaster Pendular Rudder

              Commentaire


              • #1
                Bonjour PhM,

                Envoyé par PhM Voir le message
                Essayer de tout traduire, étant donnée la qualité des traducteurs en ligne, n'est pas dans ce cas la bonne solution je pense.
                Je pense la même chose. Et il y a mille et une autres façons d'apprendre sur un sujet...

                Il m'arrive de comme vous l'écris « de tâtonner et d'essayer au petit bonheur », mais c'est après avoir utilisé les règles strictes trouvées au fils de mes recherches.

                Mais vous qui avez une solution par câble USB et sans utiliser l'UDP, vous pourriez fournir un exemple complet pour un paramètre comme :

                Code:
                sim/cockpit/radios/nav_com_adf_mode int y int for a multifunction receiver...0-5 for nav1,nav2,com1,com2,adf1,adf2.
                Et nous, nous pourrions recycler cet exemple complet avec toutes les autres lignes du fichier « DataRefs.txt ».

                Ça, ce serait simple !

                Vous, vous êtes un expert. Nous, nous sommes des apprentis et c'est en observant les experts que les apprentis deviennent avec le temps, plus qu'apprenti, mais si vous nous cachez votre travail, l'on n'apprend pas et l'on reste apprenti.

                Avec les exemples du site « Arduino Cockpit Simulator », j'ai fais beaucoup de chemin et j'ai déjà produit quelques codes source complets et fonctionnels (kit pour télécommander X-Plane) et d’ailleurs est pièce jointe, vous trouverez le brouillon de mon code pour télécommande et afficheur LCD pour Arduino et X-Plane.


                Cliquez sur l'image pour la voir en taille réelle 

Nom : 		ArduinoMegaEthernetLCD20x4-0.jpg 
Affichages :	2 
Taille :		90,7 Ko 
ID : 			457919

                L'ami René
                Tous pour un et un pour tous !
                TeleURC600_LCD_07.zip Code source Arduino
                Motorola-URC600 (avec texte 5).odg.zip Fichier LibreOffice Draw
                Motorola-URC600 (avec texte 5).pdf Fichier PDF
                Dernière modification par Lami, 24 juillet 2014, 15h15. Motif: Ajout de l'image
                L'ami René
                Tous pour un et un pour tous !

                Ordi-1 : Intel i7-12700K 5GHz, RAM 128 Go, nVidia RTX 3080 10G, Téléviseur 55" 3840x2160, 3 écrans 1920x1080, Manettes Saitek X56.
                Linux Debian 13, X11, X-Plane 12.4.4-b2, Little NavMap v3.0.18, pilote nVidia 550.163.1.

                Ordi-2 : Intel i7-12700KF 5GHz, RAM 48 Go, Asus GeForce STRIX-GTX 1060 6G, 2 x Écran 1920x1080.
                Linux Kubuntu 26.04, XHSI 2.0 Beta 12 Alfa 5, pilote nVidia 535.309.

                Commentaire


                • #1
                  Bon on va reprendre, calmement.
                  • Je n'ai rien en USB.
                  • Ce que j'ai fait est avec ethernet et en dehors des paquets UDP X-Plane.
                  • Je n'ai donc pas de réponse toute faite à : "apporte une solution qui marche pour mon problème".
                  • J'essaye (maladroitement) de te communiquer une méthodologie pour parvenir à tes fins.
                  • Dans ton cas il faut absolument, en premier lieu, comprendre le format des paquets X-Plane.

                  J'ai été voir dans le document fourni avec X-Plane, j'ai vu ceci :

                  5-character MESSAGE PROLOUGE (to indicate the type of message) and then a DATA INPUT STRUCTURE (containing the message data that you want to send or receive)
                  Donc un message est composé de :
                  • Une zone "prolounge" (drôle de nom) de cinq caractères.
                  • Une zone de données.

                  En regardant où "prolounge" est cité j'ai trouvé ceci :
                  The first 4 chars are the message type, the 5th char is internal-use INDEX-BYTE for X-Plane (you can enter 0 here when sending data)
                  Donc un "prolounge" est composé de :
                  • Un nom de quatre caractères.
                  • Un index de un octet.

                  J'ai ensuite cherché un exemple que tu avais donné, à savoir "DREF" :
                  DREF SET DATAREF STRUCTURE:
                  struct dref_struct{
                  xflt var; xchr dref_path[strDIM];};
                  C'est particulièrement mal formatté, une fois arrangé on comprend un peu mieux :
                  Code:
                  struct dref_struct
                  {
                      xflt var;
                      xchr dref_path[strDIM]
                  };
                  On voit donc qu'il faut un xflt et un tableau de xchr. C'est bien du Austin, pourquoi faire simple quand on peu faire compliqué avec des noms de variables sortis du chapeau, ça ressemble à un flottant et des caractères. On en a la confirmation plus haut dans le document X-Plane :
                  XCHR (character, in local byte-order for the machine you are on)
                  XFLT
                  (4-byte ints and floats, in local byte-order for the machine you are on)
                  A ben encore du Austin, nommer quelque chose qui fait penser à float mais permettre d'y mettre des entiers . On apprend aussi qu'il faut faire attention à ce qu'il appelle le "byte-order", plus connu comme "endian-ness" (ça vient de Guliver, les big-endians et little-endians), donc ce qui vient du PC devrait être en little-endian, pour l'arduino je ne sais pas. Il va falloir vérifier et s'assurer que tout est dans le bon ordre.

                  Encore un point à éclaircir, que vaut strDIM, on trouve ça dans le document X-Plane :
                  strDIM is 500
                  Donc notre zone de données ressemble à :
                  Code:
                  struct dref_struct
                  {
                      float var;
                      char  dref_path[500];
                  };
                  Reste plus qu'à mettre ensemble tous les morceaux pour composer le message complet pour un DREF :
                  Code:
                  struct DrefMessage
                  {
                      char        Name[4];
                      char        Index;
                      dref_struct DrefData;
                  };
                  
                  // ou bien, ce qui est équivalent :
                  
                  struct DrefMessage
                  {
                      char  Name[4];
                      char  Index;
                      float Var;
                      char  DrefPath[500];
                  };
                  On pourrait faire plus flexible, et moins sujet à des erreurs mais pour un début ça devrait aller.

                  Pour un premier test on pourrait faire quelque chose comme :
                  Code:
                  DrefMessage MyMessage;
                  
                  strcpy(MyMessage.Name,"DREF");
                  
                  // même si strcpy l'a déjà fait
                  MyMessage.Index = 0;
                  
                  MyMessage.Var = 0.0f;
                  
                  strcpy(MyMessage.DrefPath,"sim/weather/barometer_current_inhg");
                  
                  // et envoyer MyMessage sur le réseau avec la fonction qui fait ça sur arduino.
                  Je n'ai rien compilé, encore moins essayé. C'est plus un gros début de piste pour arriver au but, j'espère que ça aidera.

                  PhM
                  X-Plane 9.70 & 11.5r1 / W10 / AMD Ryzen 7 2700 / 8Go RAM / Sapphire R9 390 Nitro 8Go / Sapphire HD7870 GHz 2Go / Samsung LN40C530 / Oculus DK2 / LeapMotion / Saitek X56 / Thrustmaster Pendular Rudder

                  Commentaire


                  • #1
                    Bonjour PhM,

                    Merci pour tant d'efforts pour m'aider !

                    Envoyé par PhM Voir le message
                    Bon on va reprendre, calmement.
                    • Je n'ai rien en USB.
                    • Ce que j'ai fait est avec ethernet et en dehors des paquets UDP X-Plane.
                    Est-ce que tu pourrais détailler un peu (tu utilises quoi comme contrôleur (ports entrées/sorties, unité de traitement) environnement de programmation, etc.) ?

                    Est-ce qu'il t'arrive de travailler avec X-Plane et des cartes Arduino ?

                    Envoyé par PhM Voir le message
                    • Je n'ai donc pas de réponse toute faite à : "apporte une solution qui marche pour mon problème".
                    • J'essaye (maladroitement) de te communiquer une méthodologie pour parvenir à tes fins.
                    J'ai des forces et des faiblesses, ne pas en tenir compte fait perdre à tous les points de vue. Je ne deviendrai pas anglophone cette année, mais j'ai d'autres forces...

                    Envoyé par PhM Voir le message
                    • Dans ton cas il faut absolument, en premier lieu, comprendre le format des paquets X-Plane.
                    Je veux bien, mais cela semble très laborieux !

                    Envoyé par PhM Voir le message
                    ...
                    Donc un message est composé de :
                    • Une zone "prolounge" (drôle de nom) de cinq caractères.
                    • Une zone de données.
                    Mais où trouver la liste complète et détaillée de ces noms, même en anglais, elle me serait utile ?

                    Pour le moment, je suis dans le noir avec ces noms de 5 lettres et note que c'est bien la première foi que j'en entends parler. Pas étonnant que je tâtonne.

                    Envoyé par PhM Voir le message
                    En regardant où "prolounge" est cité j'ai trouvé ceci :

                    Donc un "prolounge" est composé de :
                    • Un nom de quatre caractères.
                    • Un index de un octet.
                    Alors là, on part pas du bon pied, c'est 4 ou c'est 5 lettres ou il est question de deux choses séparées ? En partant, tu me perds.

                    Envoyé par PhM Voir le message
                    J'ai ensuite cherché un exemple que tu avais donné, à savoir "DREF" :

                    C'est particulièrement mal formaté, une fois arrangé on comprend un peu mieux :
                    Code:
                    struct dref_struct
                    {
                        xflt var;
                        xchr dref_path[strDIM]
                    };
                    On voit donc qu'il faut un xflt et un tableau de xchr. C'est bien du Austin, pourquoi faire simple quand on peu faire compliqué avec des noms de variables sortis du chapeau, ça ressemble à un flottant et des caractères. On en a la confirmation plus haut dans le document X-Plane :

                    A ben encore du Austin, nommer quelque chose qui fait penser à float mais permettre d'y mettre des entiers . On apprend aussi qu'il faut faire attention à ce qu'il appelle le "byte-order", plus connu comme "endian-ness" (ça vient de Guliver, les big-endians et little-endians), donc ce qui vient du PC devrait être en little-endian, pour l'arduino je ne sais pas. Il va falloir vérifier et s'assurer que tout est dans le bon ordre.

                    Encore un point à éclaircir, que vaut strDIM, on trouve ça dans le document X-Plane :

                    Donc notre zone de données ressemble à :
                    Code:
                    struct dref_struct
                    {
                        float var;
                        char  dref_path[500];
                    };
                    Reste plus qu'à mettre ensemble tous les morceaux pour composer le message complet pour un DREF :

                    Code:
                    struct DrefMessage
                    {
                        char        Name[4];
                        char        Index;
                        dref_struct DrefData;
                    };
                    Alors, c'est 4 lettres pour les noms, mais où sont passé les « "prolounge" (drôle de nom) de cinq caractères. » ?

                    Envoyé par PhM Voir le message
                    Code:
                    // ou bien, ce qui est équivalent :
                    
                    struct DrefMessage
                    {
                        char  Name[4];
                        char  Index;
                        float Var;
                        char  DrefPath[500];
                    };
                    On pourrait faire plus flexible, et moins sujet à des erreurs mais pour un début ça devrait aller.
                    OK, si l'on reste avec des noms de variable aussi peu explicite et que l'on doit déchiffrer à chaque lecture, je ne m'en sortirai pas.

                    De plus, dans ce qui précède, il semble y avoir des bouts de code redondant, ce qui complique la lecture et la compréhension de l'ensemble.

                    Envoyé par PhM Voir le message
                    Pour un premier test on pourrait faire quelque chose comme :

                    Code:
                    DrefMessage MyMessage;
                    
                    strcpy(MyMessage.Name,"DREF");
                    
                    // même si strcpy l'a déjà fait
                    MyMessage.Index = 0;
                    
                    MyMessage.Var = 0.0f;
                    
                    strcpy(MyMessage.DrefPath,"sim/weather/barometer_current_inhg");
                    
                    // et envoyer MyMessage sur le réseau avec la fonction qui fait ça sur arduino.
                    Je n'ai rien compilé, encore moins essayé. C'est plus un gros début de piste pour arriver au but, j'espère que ça aidera.

                    PhM
                    Ici, ce qui me rendrait vraiment service pour comprendre, c'est de clarifier et définir une structure de données et des noms de variable plus explicite, sans utiliser de diminutif et sans utiliser des termes anglais ou à la Austin.

                    Si tu veux bien m'aider, ce que je propose, c'est de synthétiser, clarifier et redéfinir en un seul bloc de code tout ce qui précède ?

                    J'ai déjà deux manières qui fonctionne pour gérer le paramètre « barometer » de X-Plane, alors je préférerais travaille sur un paramètre ou j'ai un problème et c'est avec « nav_com_adf_mode » :

                    sim/cockpit/radios/nav_com_adf_mode int y int for a multifunction receiver...0-5 for nav1,nav2,com1,com2,adf1,adf2.
                    Voici pour le moment ma synthèse et compréhension de tout ce qui précède, sous la forme du bloc de code don je parle (je suis persuadé que je n'ai pas tout compris et qu'il y a des erreurs, mais c'est pour ne pas te donner tout le travaille a faire... Voir pièce jointe) :

                    Code:
                    //*****************************************************************************
                    // Déclaration des structure de données.
                    //*****************************************************************************
                    struct StructureMessagePourX_Plane
                    {
                      char  NomDuParametreX_Plane [4];
                      char  Index;
                      float ValeurDuParametreX_Plane;
                      char  TexteParametreX_Plane [500];
                    };
                    //*****************************************************************************
                    
                    //*****************************************************************************
                    // Création en mémoire des objets pour les interfaces des périphériques.
                    //*****************************************************************************
                    // Ensemble des données pour communiquer un message X-Plane.
                    StructureMessagePourX_Plane MessagePourX_Plane;
                    ...
                    //*****************************************************************************
                    
                    //*****************************************************************************
                    // FONCTION EnvoyerDonneesX_Plane
                    //*****************************************************************************
                    void EnvoyerDonneesX_Plane (StructureMessagePourX_Plane MessagePourX_Plane)
                    {
                      CarteEthernet.beginPacket (X_PLANE_ADRESSE_IP, X_PLANE_ADRESSE);
                      CarteEthernet.write (MessagePourX_Plane);
                      CarteEthernet.endPacket ();
                    }
                    //*****************************************************************************
                    
                    //*****************************************************************************
                    // FONCTION MessagePourX_Plane
                    //*****************************************************************************
                    void MessagePourX_Plane (Texte_X_Plane, ValeurDuParametreX_Plane)
                    {
                      MessagePourX_Plane.NomDuParametreX_Plane = "????";
                      MessagePourX_Plane.Index = 0;// ????
                      MessagePourX_Plane.TexteParametreX_Plane = Texte_X_Plane;
                      MessagePourX_Plane.ValeurDuParametreX_Plane = float (ValeurDuParametre);
                    
                      EnvoyerDonneesX_Plane (MessagePourX_Plane);
                    }
                    //*****************************************************************************
                    
                    ...
                      if (BoutonsX_Plane (BOUTON_1))
                      {
                        RadiosActive = BOUTON_RADIO_NAV_1;
                        MessagePourX_Plane ("sim/cockpit/radios/nav_com_adf_mode", RadiosActive);
                      }
                      if (BoutonsX_Plane (BOUTON_2))
                      {
                        RadiosActive = BOUTON_RADIO_COM_1;
                        MessagePourX_Plane ("sim/cockpit/radios/nav_com_adf_mode", RadiosActive);
                      }
                    ...
                    Merci d'avance si tu acceptes ma proposition !

                    En pièce jointe une ébauche de code source en langage C pour Arduino.

                    L'ami René
                    Tous pour un et un pour tous !
                    PhM_01.zip
                    L'ami René
                    Tous pour un et un pour tous !

                    Ordi-1 : Intel i7-12700K 5GHz, RAM 128 Go, nVidia RTX 3080 10G, Téléviseur 55" 3840x2160, 3 écrans 1920x1080, Manettes Saitek X56.
                    Linux Debian 13, X11, X-Plane 12.4.4-b2, Little NavMap v3.0.18, pilote nVidia 550.163.1.

                    Ordi-2 : Intel i7-12700KF 5GHz, RAM 48 Go, Asus GeForce STRIX-GTX 1060 6G, 2 x Écran 1920x1080.
                    Linux Kubuntu 26.04, XHSI 2.0 Beta 12 Alfa 5, pilote nVidia 535.309.

                    Commentaire


                    • #1
                      J'ai bien compris les différents types de données et de formats.

                      En envoi (X-Plane vers extérieur), seul le message DATA est possible.
                      Le format est "DATA<" suivi de groupes de 36 bytes (octets).
                      Chaque groupe est composé d'un premier élément de 4 bytes qui correspond à un index (celui affiché dans le panneau des entrées/sorties de X-Plane).
                      Les 8 autres éléments de 4 bytes correspondent à une des données de cet index.

                      En réception, plusieurs messages sont possibles.
                      Chaque message doit commencer par le type de message en 4 lettres suivies d'un zéro (DREF0 pour une Dataref, DATA0 pour une donnée, CMND0 pour une commande...).
                      Le reste du message varie en fonction du type de message:
                      CMND : ajouter le texte de la commande
                      DATA : même format que pour l'envoi (mais élément = -999 si on ne veut pas le modifier) : un groupe de 36 bytes par donnée
                      DREF : [la valeur (un élément de 4 bytes)] + [le nom de la Dataref suivi du nombre d'espaces = CHAR(32) nécessaire pour que le total de caractères fasse 500] + [le caractère NULL= CHAR(0) ]
                      et ainsi de suite cela permet aussi de déclencher des pannes, ajouter des véhicules...).


                      Je suis toutefois bloqué depuis des jours avec un dernier problème: X-Plane reçoit bien mes messages mais n'en tient pas du tout compte.
                      J'explique: voici un programme qui envoie une commande (allumer les feux de taxi).
                      Code:
                      #include <SPI.h>
                      #include <Ethernet.h>
                      #include <EthernetUdp.h>
                      //-----------------------------
                      byte mac[] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};     // mettre à jour selon l'adresse MAC de votre shield Arduino (étiquette au dos de la carte)
                      IPAddress ip (192, 168, 1, 254) ;                     // Adresse IP choisie pour Arduino 
                      IPAddress ipx (192, 168, 1, 6);                        // mettre à jour selon l'adresse IP de votre PC 
                      unsigned int localPort = 49001;                       // port pour recevoir les paquets UDP de X-Plane
                      unsigned int  XP = 49000;                              // port pour envoyer les paquets UDP vers X-Plane
                      EthernetUDP Udp;                                         // instance EthernetUDP pour envoyer/recevoir les paquets UDP
                      
                      void setup()  
                      { 
                        Ethernet.begin(mac,ip);                               // démarrage liaison Ethernet 
                        Udp.begin(localPort);                                  //..et UDP:
                      }
                                 
                      void loop()
                      {
                             Udp.beginPacket(ipx, XP);
                             Udp.write("CMND0");
                             Udp.write("sim/lights/taxi_lights_on");
                             Udp.endPacket();
                      
                             delay(5000);                                         // attente 5 secondes avant nouvel envoi de la commande
                       }
                      X-Plane reçoit bien chaque commande car il affiche le message "Got a transmission from someone talking to a master machine, is external IOS from address 198.162.1.254 3.4 seconds ago, sending CMND." dans les fenêtres 'Net Connections'.
                      Le 3.4 est actualisé tous les dixièmes de secondes et croît jusqu'à la valeur fixée dans le programme (5 secondes).
                      X-Plane comprend qu'il reçoit un message de la bonne adresse IP (celle de la carte Arduino) et il comprend le message (d'autres essais avec un message UDP DREF0 se traduisent bien par "sending DREF").
                      Il comprend donc qu'il a affaire à une commande mais il ne fait rien.?!

                      Je suis dégoûté (pour quelques jours).
                      Si quelqu'un a la solution...
                      XP11.41 - WIN 7 - i7 - GTX970

                      Commentaire


                      • #1
                        As-tu essayé avec le dataref au lieu de la commande ? (DREF0 et sim/cockpit2/switches/taxi_light_on)

                        PhM
                        Dernière modification par PhM, 26 juillet 2014, 13h50.
                        X-Plane 9.70 & 11.5r1 / W10 / AMD Ryzen 7 2700 / 8Go RAM / Sapphire R9 390 Nitro 8Go / Sapphire HD7870 GHz 2Go / Samsung LN40C530 / Oculus DK2 / LeapMotion / Saitek X56 / Thrustmaster Pendular Rudder

                        Commentaire


                        • #1
                          Envoyé par FlyingBaldy Voir le message
                          ...DREF : [la valeur (un élément de 4 bytes)] + [le nom de la Dataref suivi du nombre d'espaces = CHAR(32) nécessaire pour que le total de caractères fasse 500] + [le caractère NULL= CHAR(0) ]...
                          Attention, si le tableau est défini avec 500 caractères le zéro final est compris dans ce nombre, donc 499 caratères et un zéro final.

                          PhM
                          X-Plane 9.70 & 11.5r1 / W10 / AMD Ryzen 7 2700 / 8Go RAM / Sapphire R9 390 Nitro 8Go / Sapphire HD7870 GHz 2Go / Samsung LN40C530 / Oculus DK2 / LeapMotion / Saitek X56 / Thrustmaster Pendular Rudder

                          Commentaire


                          • #1
                            Oui j'ai essayé avec DREF et le résultat est identique (message reconnu par X-Plane : "j'ai reçu un message DREF de l'adresse IP 192.168.1.254 il y a x.x secondes") mais rien ne se passe.
                            Pour les 500 caractères, je définis par exemple DONNEES[501], avec DONNEES[0] à DONNEES[499]=CHAR(32) puis DONNEES[500]=CHAR(0). Je remplace ensuite Les x premiers caractères par ceux du texte de la Dataref.

                            C'est fou, X-Plane reconnaît l'adresse IP de la carte, reconnaît le type de message, reconnaît la longueur du message (sinon il proteste en disant qu'il a reçu x bytes alors qu'il attendait y bytes) et rien ne se passe!

                            Je continue à essayer le message CMND0 car il n'y a pas de problème de format, ni de valeur à envoyer.
                            Les commandes pourraient être différentes des vôtres car je travaille avec Xp 9.7 mais ce n'est pas le problème ici.

                            C'est rageant, je suis à 2 doigts du "bonheur"!
                            XP11.41 - WIN 7 - i7 - GTX970

                            Commentaire


                            • #1
                              Bonjour FlyingBaldy,

                              Un point positif, chez-moi ça fonctionne avec le paramètre :
                              Code:
                                CarteEthernetUDP.write ("CMND0");
                              Et voici les bouts codes utilisés :

                              Code:
                              //*****************************************************************************
                              // Inclusion des librairies utilisées.
                              //*****************************************************************************
                              ...
                              #include <Ethernet.h>
                              #include <EthernetUdp.h>
                              #include <SPI.h>
                              ...
                              //*****************************************************************************
                              // Déclaration des autres constantes de travail.
                              //*****************************************************************************
                              // Constante pour la communication Ethernet adresses et ports :
                              // Adresse MAC de la carte Ethernet Arduino. À personnaliser.
                              byte ADRESSE_MAC [] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE};
                              // Adresse IP de la carte Ethernet Arduino. Personnalisez la pour ne pas avoir
                              // à la modifier fréquemment dans l'onglet « Données » de X-Plane.
                              IPAddress ARDUINO_ADRESSE_IP (192, 168, 2, 14);
                              // Adresse IP de l'ordinateur maître qui exécute X-Plane. Vous la trouverez 
                              // dans X-Plane - Paramètres - Connexions réseau, dans la troisième ligne.
                              IPAddress X_PLANE_ADRESSE_IP (192, 168, 2, 2);
                              // Port pour recevoir des données de X-Plane.
                              unsigned int ARDUINO_ADRESSE_UDP = 49001;
                              // Port pour envoyer des données a X-Plane.
                              unsigned int X_PLANE_ADRESSE_UDP = 49000;
                              //*****************************************************************************
                              ...
                              //*****************************************************************************
                              // Déclaration des variables globales.
                              //*****************************************************************************
                              // Bascule pour allumer/étindre toutes les lumières extérieures.
                              boolean LumieresAllumees = NON;
                              
                              char PaquetUDP_Donnees [500];
                              
                              // Recoit la valeur du/des régimes moteurs.
                              float ThrottleValeur = 0;
                              // Unions permettent le même emplacement de mémoire auquel on doit accéder en 
                              // tant que types de données différents.
                              // Dans ce cas-ci, comme des byte et lire comme float. Voir plus à :
                              // http://b58.svglobe.com/data.html
                              union
                              {
                                char ValeurFormat4Byte [4];
                                float ValeurFormat1Float;
                              } TemponComUDP;
                              ...
                              //*****************************************************************************
                              
                              //*****************************************************************************
                              // FONCTION EnvoyerCommandeX_Plane
                              //*****************************************************************************
                              void EnvoyerCommandeX_Plane (char Donnees_A_Communiquer [])
                              {
                                CodeSituation = 50;
                                CarteEthernetUDP.beginPacket (X_PLANE_ADRESSE_IP, X_PLANE_ADRESSE_UDP);
                                CarteEthernetUDP.write ("CMND0");
                                CarteEthernetUDP.write (Donnees_A_Communiquer);
                                CarteEthernetUDP.endPacket ();
                              }
                              //*****************************************************************************
                              
                              //*****************************************************************************
                              // FONCTION SETUP = Code d'initialisation.
                              //*****************************************************************************
                              void setup ()
                              ...
                                // Pour la carte Ethernet et les cartes Mega et Due.
                                pinMode (53, OUTPUT);
                              
                                // Identification IP (par DHCP)
                                // Lancer la connexion Ethernet : DHCP
                                Ethernet.begin (ADRESSE_MAC);
                                Ethernet.begin (ADRESSE_MAC, ARDUINO_ADRESSE_IP);
                                CarteEthernetUDP.begin (ARDUINO_ADRESSE_UDP);
                              ...
                              //*****************************************************************************
                              
                              //*****************************************************************************
                              // FONCTION loop = Boucle sans fin = coeur du programme.
                              //*****************************************************************************
                              void loop ()
                              ...
                                      if (LumieresAllumees)
                                      {
                                        CodeSituation = 51;
                                        LumieresAllumees = NON;
                                        EnvoyerCommandeX_Plane ("sim/lights/landing_lights_off");
                                        EnvoyerCommandeX_Plane ("sim/lights/beacon_lights_off");
                                        EnvoyerCommandeX_Plane ("sim/lights/nav_lights_off");
                                        EnvoyerCommandeX_Plane ("sim/lights/strobe_lights_off");
                                        EnvoyerCommandeX_Plane ("sim/lights/taxi_lights_off");
                                      }
                                      else
                                      {
                                        CodeSituation = 52;
                                        LumieresAllumees = OUI;
                                        EnvoyerCommandeX_Plane ("sim/lights/landing_lights_on");
                                        EnvoyerCommandeX_Plane ("sim/lights/beacon_lights_on");
                                        EnvoyerCommandeX_Plane ("sim/lights/nav_lights_on");
                                        EnvoyerCommandeX_Plane ("sim/lights/strobe_lights_on");
                                        EnvoyerCommandeX_Plane ("sim/lights/taxi_lights_on");
                                      }
                                      delay (500);
                              ...
                              Si j'ai oublié quelque chose, me le signaler pour que je vous le fournisse !

                              Si vous aviez un capteur infrarouge VS1838B (TSOP1838), nous pourrions tester du code en commun.

                              Réf. :
                              http://www.electrodragon.com/product...1838-receiver/
                              http://www.amazon.com/NEOMART-Raspbe.../dp/B00CW8WUGA
                              http://www.dipmicro.com/store/VS1838B
                              http://dx.com/p/hx1838-pc638-diy-uni...-20-pcs-158341

                              L'ami René
                              Tous pour un et un pour tous !
                              L'ami René
                              Tous pour un et un pour tous !

                              Ordi-1 : Intel i7-12700K 5GHz, RAM 128 Go, nVidia RTX 3080 10G, Téléviseur 55" 3840x2160, 3 écrans 1920x1080, Manettes Saitek X56.
                              Linux Debian 13, X11, X-Plane 12.4.4-b2, Little NavMap v3.0.18, pilote nVidia 550.163.1.

                              Ordi-2 : Intel i7-12700KF 5GHz, RAM 48 Go, Asus GeForce STRIX-GTX 1060 6G, 2 x Écran 1920x1080.
                              Linux Kubuntu 26.04, XHSI 2.0 Beta 12 Alfa 5, pilote nVidia 535.309.

                              Commentaire


                              • #1
                                Bonjour,

                                Voici, sous la forme du code Arduino d'une structure où en est ma réflexion et compréhension de la structure des messages pour communiquer avec X-Plane, son initialisation et utilisation :

                                Code:
                                struct StructureMessagePourX_Plane
                                {
                                  char TypeDeMessageX_Plane [4];// Choix : CMND, DATA, DREF.
                                  char Index;// Choix : 0 ou <.
                                  union
                                  {
                                    char ValeurFormat4Byte [4];// Sous la forme de 4 octets.
                                    float ValeurFormat1Float;// Sous la forme d'un flottant.
                                  } ValeurDuParametreX_Plane;// Utilisez la fonction de conversion « float ».
                                  char TexteMessageX_Plane [495];// Texte du paramètre.
                                  char FinDuMessageX_Plane;// Pour recevoir le caractère de fin du message char (0).
                                };
                                ...
                                StructureMessagePourX_Plane MessagePourX_Plane;
                                ...
                                MessagePourX_Plane.TypeDeMessageX_Plane = "CMND";
                                MessagePourX_Plane.Index = 0;
                                
                                for (int i = 0; i < 495; i = i + 1)
                                {
                                  MessagePourX_PlaneDataRef [i] = char (32);
                                }
                                
                                MessagePourX_Plane.FinDuMessageX = char (0);
                                ...
                                
                                MessagePourX_Plane.TexteMessageX_Plane = "sim/cockpit/radios/nav_com_adf_mode";// Pour sélectionner la radio pouvant être modifiée.
                                MessagePourX_Plane.ValeurFormat1Float = float (2);// Pour activer la radio adf1.
                                
                                EnvoyerDonneesX_Plane (MessagePourX_Plane); // Et finalement, tout le message à envoyer.
                                ...
                                Me corriger là où je me trompe et me compléter là où j'ai un manque.

                                L'ami René
                                Tous pour un et un pour tous !
                                L'ami René
                                Tous pour un et un pour tous !

                                Ordi-1 : Intel i7-12700K 5GHz, RAM 128 Go, nVidia RTX 3080 10G, Téléviseur 55" 3840x2160, 3 écrans 1920x1080, Manettes Saitek X56.
                                Linux Debian 13, X11, X-Plane 12.4.4-b2, Little NavMap v3.0.18, pilote nVidia 550.163.1.

                                Ordi-2 : Intel i7-12700KF 5GHz, RAM 48 Go, Asus GeForce STRIX-GTX 1060 6G, 2 x Écran 1920x1080.
                                Linux Kubuntu 26.04, XHSI 2.0 Beta 12 Alfa 5, pilote nVidia 535.309.

                                Commentaire

                                Chargement...
                                X