Page 1 sur 1

[Arduino] 2 Accès à la mémoire partagée

Publié : dim. août 09, 2015 9:46 am
par Topper Harley.
Bonjour

Voilà la suite. Je vous rappelle que je ne suis pas un pro, ni en C++, ni en électronique.
Aussi, il est possible que ce qui suit ne soit pas la manière la plus propre ou la plus efficace de parvenir à notre but.
N'hésitez donc pas à poster vos commentaires, questions, critiques et avis à la suite de cet article.


Précédemment, nous avons vu de quelle façon BMS nous permettrait d'accéder à certains paramètres de vols, via la mémoire partagée, et de quelle façon nous pouvions y accéder (les API de Windows).
Dans cet article, nous allons mettre en pratique ce que nous avons appris précédemment. A la fin de l'article, vous pourrez afficher le paramètre de vol qui vous intéresse.
Posons le problème : BMS écrit des données dans la mémoire partagée, nous devons récupérer ces données. Pour cela il nous faut donc un programme, et nous allons l'écrire. Écrire le programme peut sembler ardu, mais au final ça semble être la façon la plus simple d'accéder à notre but : afficher des paramètres du cockpit sur un support externe. Et vous allez voir, dans le principe cela est assez simple.

Je vous propose, pour écrire ce programme, d'utiliser le langage C++, et il sera plus simple que nous ayons le même IDE. J'ai opté pour Microsoft Visual Express 2010C++. Vous pouvez le télécharger à partir de l'adresse http://go.microsoft.com/?linkid=9709949 A l’issue du chargement, l'exécutable vous permet de choisir les options avant de télécharger le programme proprement dit. Pour ce que nous voulons faire, inutile d'installer Silverlight ni SQL server. Le reste de l'installation ne pose aucun problème particulier. En cas de doute, vous pouvez consulter la page http://apais.developpez.com/tutoriels/c ... 0-express/
Notez enfin que vous avez une période de 30 jours pendant laquelle il vous est demandé d'enregistrer le programme. Cela est gratuit.

Au terme de l'installation de Visual c++express, vous aurez une nouvelle icône sur le bureau.

Lancez le programme, cliquez sur Nouveau projet et choisissez Application console Win32. Dans le champ Nom en bas de l'écran, inscrivez Win32_con_BMSsharedmemory et cliquez sur OK.Sur la boîte de dialogue suivante, cliquer sur Terminer.

Image

Une structure d'application console est crée. Cela comprend des fichiers entête (stdafx.h, targetvar.h) et des fichiers sources (stdafx.cpp et Win32_con_BMSsharedmemory.cpp).
Par défaut, Win32_con_BMSsharedmemory.cpp est ouvert.

Pour un premier temps, modifiez le programme de cette façon :

Inscrivez les lignes suivantes entre l'accolade ouverte et return 0;

Code : Tout sélectionner

printf ("Hello World !"); getchar();

Image

Exécutez le programme en appuyant sur a touche de fonction F5. Une console devrait apparaître avec le texte "Hello World !".

Image

A présent, tout est réuni pour écrire le programme qui nous permettra d'accéder à la mémoire partagée.
1. Copiez le fichier "flight Data.h" (que vous trouverez à C:\Falcon BMS 4.32\Docs\BMS Manuals\Other Documentation) dans les fichiers d’entête de votre projet. Pour cela, le plus simple est de le copier dans votre projet (par défaut à Mes Documents\Visual Studio 2010\Projects\Win32_con_BMSsharedmemory), puis dans l'explorateur de solutions (fenêtre de gauche) cliquez avec le bouton droit sur Fichiers d'entête, et choisissez successivement Ajouter / Element Existant, désignez le fichier Flight Data.h puis cliquez sur Ajouter. Le fichier doit apparaitre dans le dossier des fichiers d'en-tête.
2. Copiez le code ci-dessous (faites un copier-coller) dans le fichier principal du programme (Win32_con_BMSsharedmemory.cpp)

Code : Tout sélectionner

#include "stdafx.h" #include <windows.h> #include "flightData.h" #include <iostream> using namespace std; HANDLE gSharedMemHandle = NULL; void* gSharedMemPtr = NULL; int main (void){ FlightData* flightData; do{ gSharedMemHandle = OpenFileMapping(FILE_MAP_READ, TRUE, TEXT("FalconSharedMemoryArea")); system("CLS"); printf ("Unable to open file. Is Falcon Running?\n"); }while (!gSharedMemHandle); gSharedMemPtr = MapViewOfFile(gSharedMemHandle, FILE_MAP_READ, 0, 0, 0); flightData = (FlightData*)gSharedMemPtr; while (TRUE){ system("CLS"); cout << "Fuel Flow : " << flightData->fuelFlow << "\n"; } // Close shared memory area if (gSharedMemPtr){ UnmapViewOfFile(gSharedMemPtr); gSharedMemPtr = NULL; } CloseHandle (gSharedMemHandle); return EXIT_SUCCESS; }
Le programme est prêt. la ligne

Code : Tout sélectionner

cout << "Fuel Flow : " << flightData->fuelFlow << "\n";
va afficher le FuelFlow.
Exécutez le programme (F5). La console apparait et affiche le texte "Unable to open file. Is Falcon Running?". Normal : il faut exécuter Falcon BMS et se mettre envol, si vous voulez récupérer les valeurs du Fuel Flow.

Image

Si vous avez un autre écran que votre écran principal, déplacez la fenêtre sur cet autre écran sinon, la fenêtre sera masquée par BMS. Dans ce cas, utilisez le mode fenêtré.
Chargez une mission quelconque, et vous verrez qu'en temps réel, votre programme affiche le Fuel Flow tel qu'il est affiché dans BMS.

Image

Les données que BMS nous rend disponible sont décrites dans le fichier "flight Data.h".
Dans Visual Express, cliquez sur Affichage de Classe (en bas de la fenêtre de gauche), ouvrez FlightData et parcourez toutes les données disponibles. prenez par exemple la ligne
float currentHeading;
Cela signifie que la donnée currentHeading (indiquant le cap) est de type float (nombre à virgule, [pour faire simple]).

Image

Donc, en modifiant la ligne

Code : Tout sélectionner

cout << "Fuel Flow : " << flightData->fuelFlow << "\n";
en

Code : Tout sélectionner

cout << "Cap : " << flightData->currentHeading << "\n";
Vous afficherez le cap.

Image

Voilà, c'est presque fini.

Il reste le "cas" des énumérations : certaines données sont de type booléennes (c'est à dire 0 ou 1), elles renseignent notamment de l'état de certains voyants. Ces données booléennes sont regroupées dans des énumérations (d'où le nom enum). Dans la classe FlightData, il ya a : LightBits, LightBits2, LightBits3, HsiBits.
Nous savons comment accéder à une donnée de FlightData, (en faisant FlightData-> ), mais l'accès à un bit particulier doit passer par une opération logique :

Par exemple, nous voulons connaitre l'état de la valeur CONFIG (le voyant Stores config, caution panel) dans l'enum LightBits. Ce voyant peut avoir l'état allumé ou éteint, et dans le fichier "Flight Data.h", on voit qu'il a la valeur 0x40. le 0x40 est une valeur hexadécimale, en décimal, cela vaut 64 et en binaire 1000000. On peut donc déduire que le 7° bit de LightBits donne l'état du voyant Config.
Lorsqu'il est à 0, le voyant est éteint.
Lorsqu'il est à 1, le voyant est allumé.

Et pour vérifier si le 7° bit de FlightData->LightBits est à un, on va utiliser l'opérateur & (ET) qui retourne 1 si deux bits de même poids (placés au même endroit) sont égaux à 1.

Ca parait un peu compliqué, mais c'est très simple. Pour mettre en application, remplacez la ligne

Code : Tout sélectionner

cout << "Cap : " << flightData->currentHeading << "\n";
par les lignes

Code : Tout sélectionner

bool a = flightData->lightBits & flightData->CONFIG; cout << "Config : " << a << " ";
Et le programme affichera 1 lorsque le voyant CONFIG est allumé et 0 lorsqu'il ne l'est pas. (dans le cockpit, actionnez l'interrupteur STORE CONFIG pour le basculer en CAT I ou CAT III pour éclairer le voyant.


Dans le prochain article, nous allons découvrir "Arduino" (plus précisément Arduino UNO ça coûte environ 20€). C'est un circuit imprimé open source, avec un microcontrôleur que nous allons programmer via le PC.