<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Non classé &#8211; Electronique et Informatique</title>
	<atom:link href="https://amaury-laurent.fr/category/non-classe/feed/" rel="self" type="application/rss+xml" />
	<link>https://amaury-laurent.fr</link>
	<description>Site web d&#039;Amaury LAURENT</description>
	<lastBuildDate>Sat, 28 Oct 2023 08:37:12 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.3.2</generator>

<image>
	<url>https://amaury-laurent.fr/wp-content/uploads/2015/09/favicon.png</url>
	<title>Non classé &#8211; Electronique et Informatique</title>
	<link>https://amaury-laurent.fr</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Écran multifonction pour simulateur de vol (MFD)</title>
		<link>https://amaury-laurent.fr/ecran-multifonction-pour-simulateur-de-vol-mfd/</link>
					<comments>https://amaury-laurent.fr/ecran-multifonction-pour-simulateur-de-vol-mfd/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Sat, 02 Oct 2021 19:46:51 +0000</pubDate>
				<category><![CDATA[Non classé]]></category>
		<guid isPermaLink="false">https://amaury-laurent.fr/?p=1271</guid>

					<description><![CDATA[<p>Introduction L&#8217;accès à certaines fonctionnalités embarqués sur un avion de combat (navigation, systèmes d&#8217;armes, désignateur, &#8230;) passe par un écran multifonctions (MultiFunction Display). Bien que certains simulateurs proposent un cockpit cliquable, il est toujours embêtant de devoir orienter le champ de vision à chaque fois que l&#8217;on souhaite effectuer une action. Du coup, l&#8217;utilisation d&#8217;un [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/ecran-multifonction-pour-simulateur-de-vol-mfd/">Écran multifonction pour simulateur de vol (MFD)</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Introduction</h1>
<p>L&rsquo;accès à certaines fonctionnalités embarqués sur un avion de combat (navigation, systèmes d&rsquo;armes, désignateur, &#8230;) passe par un écran multifonctions (<em><strong>M</strong>ulti<strong>F</strong>unction <strong>D</strong>isplay</em>). Bien que certains simulateurs proposent un cockpit cliquable, il est toujours embêtant de devoir orienter le champ de vision à chaque fois que l&rsquo;on souhaite effectuer une action. Du coup, l&rsquo;utilisation d&rsquo;un périphérique matériel augmente l&rsquo;immersion et améliore l&rsquo;expérience de jeu.</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/Screen_200617_160247-scaled.jpg"><img decoding="async" fetchpriority="high" class="aligncenter wp-image-1275 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/Screen_200617_160247.jpg" alt="" width="640" height="360" /></a></p>
<p>Les solutions commerciales existantes (<a href="http://www.thrustmaster.com/fr_FR/produits/mfd-cougar-pack" target="_blank" rel="noopener">ThrustMaster Cougar Pack</a>) ne m&rsquo;ayant pas impressionné, j&rsquo;ai décidé de concevoir un écran multifonction fonctionnant sur USB.</p>
<p>Le projet que je présente est conçu pour fonctionner avec DCS. Cependant, comme il utilise un écran HDMI et des contrôles type joystick, il n&rsquo;y a pas de raisons pour que ça ne marche pas avec d&rsquo;autres simulateurs.</p>
<h1>Principes de fonctionnement</h1>
<p>L&rsquo;idée consiste à configurer DCS pour envoyer l&rsquo;image des MFD gauche et droite sur deux écrans supplémentaires. Pour ce faire, il faut créer un fichier de configuration dans le dossier MonitorSetup du jeu et ajouter ces deux paramètres (il faut bien évidemment ajuster les offsets pour tomber dans les bons écrans) :</p>
<div class="snippetcpt-wrap" id="snippet-1272" data-id="1272" data-edit="" data-copy="/category/non-classe/feed/?snippet=ed1a2b5598&#038;id=1272" data-fullscreen="https://amaury-laurent.fr/code-snippets/mfd_display-lua/?full-screen=1">
				<pre class="prettyprint linenums lang-lua" title="MFD_Display.lua">_  = function(p) return p; end;
name = _('MFD_Display');
Description = 'Config maison'
Viewports =
{
     Center =
     {
          x = 1920;
          y = 0;
          width  = 1920;
          height = 1080;
          viewDx = 0;
          viewDy = 0;
          aspect = 1.6;
     }
}

LEFT_MFCD =
{
    x = 1920*2+(1024/2-768/2);
    y = 0;
    width  = 768;
    height = 768;
}

RIGHT_MFCD =
{
    x = 1920*2+1024+(1024/2-768/2);
    y = 0;
    width  = 768;
    height = 768;
}

UIMainView = Viewports.Center
GU_MAIN_VIEWPORT = Viewports.Center</pre>
			</div>
<p>L&rsquo;assignation des touches se fait simplement dans DCS, comme n&rsquo;importe quel autre périphérique d&rsquo;entrée.</p>
<p>Pour l&rsquo;affichage, j&rsquo;ai choisi un écran LCD 4:3 de 8 pouces. Il a une résolution de 1024&#215;768 :</p>
<p>​​<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/H7722be4a6fc64bfd84d52e6e3e1e65505.png"><img decoding="async" class="aligncenter wp-image-1299 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:768/h:1024/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/H7722be4a6fc64bfd84d52e6e3e1e65505.png" alt="" width="640" height="853" /></a></p>
<p>Son prix et sa taille en font une solution intéressante : <a href="https://fr.aliexpress.com/item/32325920866.html?spm=a2g0s.9042311.0.0.d0dd6c37EdzyS4​" target="_blank" rel="noopener">https://fr.aliexpress.com/item/32325920866.html?spm=a2g0s.9042311.0.0.d0dd6c37EdzyS4​</a></p>
<h1>L&rsquo;électronique</h1>
<h2>Conception</h2>
<p>Pour simplifier l&rsquo;intégration matérielle, j&rsquo;ai choisi d&rsquo;utiliser un petit microcontrôleur de chez Microchip capable de faire de l&rsquo;USB et de l&rsquo;I2C : le PIC18F25K50. Il communique avec 4 cartes filles qui s&rsquo;occupent chacune de 7 boutons.</p>
<p>La séparation en plusieurs cartes répond à deux impératifs :</p>
<ol>
<li>Rentrer dans une conception Autodesk EAGLE version gratuite</li>
<li>Diminuer les coûts de fabrication en réduisant la surface de circuit imprimé</li>
</ol>
<p>La carte mère sera montée au dos du MFD :<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/carte_mere.png"><img decoding="async" class="aligncenter wp-image-1292 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:183/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/carte_mere.png" alt="" width="300" height="183" /></a></p>
<p>Deux cartes en angle et deux cartes droites permettent de former un cadre autour de l&rsquo;écran LCD :</p>
<p>​<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/carte_l.png"><img decoding="async" class="aligncenter size-medium wp-image-1291" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:191/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/carte_l.png" alt="" width="300" height="191" /></a> <a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/carte_i.png"><img decoding="async" class="aligncenter size-medium wp-image-1290" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:173/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/carte_i.png" alt="" width="300" height="173" /></a>​</p>
<p>&nbsp;</p>
<h2>La carte mère</h2>
<p>La carte mère du MFD se contente de faire le lien entre les différentes cartes filles (I2C) et le PC (USB). Le schéma est donc des plus simples, il reprend celui de la <a href="https://amaury-laurent.fr/boite-a-boutons-pour-simulateurs/" target="_blank" rel="noopener">boite à boutons</a> ou de <a href="https://amaury-laurent.fr/interface-usb-hid/" target="_blank" rel="noopener">l&rsquo;interface HID</a>, mais avec un composant différent :</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/schema_carte_mere.png"><img decoding="async" class="aligncenter wp-image-1289 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:437/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/schema_carte_mere.png" alt="" width="640" height="273" /></a>​On retrouve une horloge, un circuit de reset, le connecteur USB, un connecteur pour l&rsquo;I2C et un connecteur de programmation. Pour changer mes habitudes, j&rsquo;ai réalisé mes cartes avec des composants à montage en surface (CMS) :<br />
<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/pcb_carte_mere.png"><img decoding="async" class="aligncenter wp-image-1296 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:185/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/pcb_carte_mere.png" alt="" width="300" height="185" /></a></p>
<h2>Les cartes filles</h2>
<p>Bien que 2 formes différentes soient nécessaires, elles ont toutes le même schéma (à la différence de l&rsquo;adresse). Il s&rsquo;agit d&rsquo;un multiplexeur 8 entrées tout ou rien vers I2C MCP23008. Les résistances de tirages sont intégrées dans la puce. Les cartes sont adressées par un pont à souder pour le bit de poids faible et câblé en dur à 1 pour les cartes en L (0 pour les cartes en I).</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/schema_carte_boutons.png"><img decoding="async" class="aligncenter wp-image-1297 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:280/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/schema_carte_boutons.png" alt="" width="640" height="175" /></a></p>
<p>Deux connecteurs I2C permettent de former une chaine avec les 4 cartes. Un troisième permet de relier la carte mère sur l&rsquo;une des cartes filles.</p>
<p>La configuration des boutons à bascules présents aux 4 coins du MFD oblige à avoir deux formes de cartes:</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/pcb_carte_l.png"><img decoding="async" class="aligncenter size-medium wp-image-1295" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:88/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/pcb_carte_l.png" alt="" width="300" height="88" /></a>​</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/pcb_carte_i.png"><img decoding="async" class="aligncenter size-medium wp-image-1294" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:95/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/pcb_carte_i.png" alt="" width="300" height="95" /></a>​</p>
<p>Les dimensions sont adaptées à la taille de l&rsquo;écran de 8 pouces et au boitier imprimé en 3D dessiné tout spécialement.</p>
<h2>Réalisation</h2>
<p>J&rsquo;ai sous-traité la fabrication des PCB (double couches) à <a href="https://www.nextpcb.com/" target="_blank" rel="noopener">NextPCB</a>.</p>
<p>Les soudures des composants CMS sont réalisées au fer à souder, avec une panne fine. Pour rendre cela possible, j&rsquo;ai choisi des boitiers SOIC (gros composants CMS, pas de 1.27mm) et des formats 0805 pour les résistances et condensateurs. Finalement, le composant le plus petit et le plus difficile à souder est la LED indiquant la mise sous tension.</p>
<p>NB : une bonne pince brucelles est nécessaire !</p>
<h1><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_105009-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1276 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_105009.jpg" alt="" width="640" height="360" /></a> <a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_105102-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1277 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_105102.jpg" alt="" width="640" height="360" /></a> <a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_185658-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1287 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_185658.jpg" alt="" width="640" height="360" /></a> <a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_185704-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1288 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_185704.jpg" alt="" width="640" height="360" /></a>Intégration mécanique</h1>
<p>J&rsquo;ai fait découper au LASER des tôles d&rsquo;inox pour réaliser les faces avant (<a href="https://www.metal-laser.com/" target="_blank" rel="noopener">https://www.metal-laser.com/</a>). Le boitier plastique qui accueille ​les cartes filles ainsi que les différentes touches sont imprimés en 3D. La conception mécanique et l&rsquo;intégration des cartes électroniques a été réalisée à l&rsquo;aide <a href="https://www.autodesk.fr/products/fusion-360/personal" target="_blank" rel="noopener">Fusion 360</a>. Cet outil permet de facilement faire converger les CAO électroniques et mécaniques.</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/montage.png"><img decoding="async" class="aligncenter wp-image-1293 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:198/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/montage.png" alt="" width="300" height="198" /></a></p>
<p>Il est important de pouvoir vérifier la profondeur du boitier plastique, notamment pour que les boutons poussoirs tombent en dessous des touches plastiques.<br />
<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_181757-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1279 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_181757.jpg" alt="" width="640" height="360" /></a> <a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_181811-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1280 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20210802_181811.jpg" alt="" width="640" height="360" /></a>​</p>
<p>L&rsquo;écran LCD est fixé (scotché ou collé) à l&rsquo;arrière du cadre. La face avant est également collée au boitier plastique.</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_183955-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1282 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_183955.jpg" alt="" width="640" height="360" /></a></p>
<h1>Le logiciel</h1>
<p>Une fois n&rsquo;est pas coutume, le code du microcontrôleur a été écrit en C à l&rsquo;aide de MikroC. Outre l&rsquo;initialisation de la puce et le driver des multiplexeurs, la boucle principale se contente de lire les 4 ports d&rsquo;entré sur l&rsquo;I2C et d&rsquo;envoyer le rapport USB HID.</p>
<div class="snippetcpt-wrap" id="snippet-1310" data-id="1310" data-edit="" data-copy="/category/non-classe/feed/?snippet=ed1a2b5598&#038;id=1310" data-fullscreen="https://amaury-laurent.fr/code-snippets/mfd-main/?full-screen=1">
				<pre class="prettyprint linenums lang-c_cpp" title="MFD Main">/**
* Version IO Expander MCP23018
**/

#include &quot;MCP23008.h&quot;

#define USB_BUFFER_LEN       4
#define NB_MCP               4

unsigned char readbuff[USB_BUFFER_LEN] absolute 0x500;
unsigned char writebuff[USB_BUFFER_LEN] absolute 0x540;

int reset_mcp23017 = 1;

void interrupt() {
    USB_Interrupt_Proc();        // USB servicing is done inside the interrupt
    USBIF_bit = 0;
}

// define callback function
void I2C1_TimeoutCallback(char errorCode) {
   if (errorCode == _I2C_TIMEOUT_RD) {
     //LED0 = 1;
     // do something if timeout is caused during read
   }

   if (errorCode == _I2C_TIMEOUT_WR) {
     //LED1 = 1;
     // do something if timeout is caused during write
   }

   if (errorCode == _I2C_TIMEOUT_START) {
     //LED0 = 1;
     // do something if timeout is caused during start
   }

   if (errorCode == _I2C_TIMEOUT_REPEATED_START) {
     //LED1 = 1;
     // do something if timeout is caused during repeated start
   }
   
   reset_mcp23017 = 1;
}
          
void main() {
    int i = 0;
    int cpt = 0;
    
    uint16_t temp;

    ANSELA = 0;
    ANSELB = 0;
    ANSELC = 0;
    SLRCON = 0;

    ADCON1 |= 0x0F;                         // Configure all ports with analog function as digital
    CM1CON0 |= 7;                           // Disable comparators

    TRISB = 0xff;
    TRISB.f2 = 0;
    LATB.f2 = 1;

    I2C1_Init(400000);         // initialize I2C communication
    
    // set timeout period and callback function
    I2C1_SetTimeoutCallback(40000, I2C1_TimeoutCallback);

    reset_mcp23017 = 1;

    FSEN_bit = 1;
    UPUEN_bit = 1;
    HID_Enable(&amp;readbuff,&amp;writebuff);
    
    // Enable USB device interrupt
    IPEN_bit = 1;
    USBIP_bit = 1;
    USBIE_bit = 1;
    GIEH_bit = 1;

    while (1) {
        if (reset_mcp23017) {
           LATB.f2 = 0;       //RESET MCP23017
           Delay_ms(250);
           LATB.f2 = 1;
           Delay_ms(250);

           for (i=0; i&lt;NB_MCP; i++) {
            MCPreset(i);
            Delay_ms(5);
           }
          reset_mcp23017 = 0;
        }

        memset(writebuff, 0x00, USB_BUFFER_LEN);
    
        for (i=0; i&lt;NB_MCP; i++) {
          temp = MCPread(i, GPIO);
          writebuff[i] = ~temp;
          Delay_ms(5);
          if(reset_mcp23017) break;
        }
        
        HID_Write(writebuff, USB_BUFFER_LEN);
        Delay_ms(5);
    }
}</pre>
			</div>
<p>&nbsp;</p>
<h1>Le premier test</h1>
<p>Un dock USB 3.1 peut servir pour gérer le HDMI et l&rsquo;USB simultanément, ce qui permet d&rsquo;avoir une unique prise USB occupée sur le PC. Si la configuration de DCS est correcte et que l&rsquo;écran est bien détecté, voici le résultat que l&rsquo;on peut obtenir :</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_184607-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1283 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_184607.jpg" alt="" width="640" height="360" /></a> <a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_184704-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1284 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_184704.jpg" alt="" width="640" height="360" /></a> <a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_184954-scaled.jpg"><img decoding="async" class="aligncenter wp-image-1286 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/10/20211002_184954.jpg" alt="" width="640" height="360" /></a></p>
<p>La même chose en vidéo :</p>
<p>&nbsp;</p>
<p><iframe title="Écran multifonction pour DCS World" width="640" height="360"  src="about:blank" data-opt-src="https://www.youtube.com/embed/rAcCKd2z3Fs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></p>
<p>&nbsp;</p>
<h1>Conclusion</h1>
<p>Il me reste encore à imprimer des touches propres et à finir l&rsquo;état de surface de la face avant. Pour le reste, le rendu est vraiment sympa. Reste à tester réellement sur une session de pilotage plus longue.</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/ecran-multifonction-pour-simulateur-de-vol-mfd/">Écran multifonction pour simulateur de vol (MFD)</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://amaury-laurent.fr/ecran-multifonction-pour-simulateur-de-vol-mfd/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Boite à boutons pour simulateurs</title>
		<link>https://amaury-laurent.fr/boite-a-boutons-pour-simulateurs/</link>
					<comments>https://amaury-laurent.fr/boite-a-boutons-pour-simulateurs/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Wed, 16 Jun 2021 16:48:31 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Réalisation]]></category>
		<category><![CDATA[buttonbox]]></category>
		<category><![CDATA[DCS Wolrd]]></category>
		<category><![CDATA[hid]]></category>
		<category><![CDATA[usb]]></category>
		<guid isPermaLink="false">https://amaury-laurent.fr/?p=1243</guid>

					<description><![CDATA[<p>Le retour de l&#8217;interface USB HID ! Introduction Quand les potes disent vouloir jouer à DCS World en multijoueurs, l&#8217;électronicien qui sommeil en moi se dit « Il me faut plus de boutons ! ». En effet, les périphériques de jeux habituels sont relativement peu pourvus en boutons, et démarrer un avion de chasse est un peu [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/boite-a-boutons-pour-simulateurs/">Boite à boutons pour simulateurs</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1></h1>
<h1>Le retour de l&rsquo;interface USB HID !</h1>
<h2>Introduction</h2>
<p>Quand les potes disent vouloir jouer à <a href="https://www.digitalcombatsimulator.com/fr/products/world/" target="_blank" rel="noopener">DCS World</a> en multijoueurs, l&rsquo;électronicien qui sommeil en moi se dit « Il me faut plus de boutons ! ». En effet, les périphériques de jeux habituels sont relativement peu pourvus en boutons, et démarrer un avion de chasse est un peu plus complexe que démarrer une Twingo. L&rsquo;idée a donc germée de concevoir une électronique vue comme un joystick et proposant des entrées tout ou rien et/ou analogiques. Il est ainsi possible de réaliser son tableau de bord, avec de vrais boutons, des étiquettes&#8230; Bref, on s&rsquo;y croirait.</p>
<h2>Conception de la carte</h2>
<h3>Spécifications</h3>
<p>Comme on ne change pas une équipe qui gagne, je suis reparti de ma première version de <a href="https://amaury-laurent.fr/interface-usb-hid/" target="_blank" rel="noopener">l&rsquo;interface USB HID</a>. Voici quelques éléments en vrac:</p>
<ul>
<li>Alimentation par le bus USB</li>
<li>MCU : PIC18F4550 cadencé à 48MHz par un quartz 24MHz</li>
<li>Carte compacte</li>
<li>pas de composants additionnels à prévoir pour les entrées tout ou rien</li>
<li>16 entrées ToR</li>
<li>8 entrées analogiques 10 bits</li>
</ul>
<p>Il me fallait écouler un vieux stock de PIC18F4550 en format DIP40, donc le CMS sera pour une prochaine réalisation. Les entrées se font sur des borniers à vis au pas de 2.54mm. Les résistances de pull-up internes au PIC permettent d&rsquo;exploiter directement les ports B et D en tout ou rien. Le port A est utilisé en entrées analogiques.</p>
<h3>Schéma et PCB</h3>
<p>Le schéma de la carte ne constitue en rien une révolution. On retrouve presque à l&rsquo;identique celui de ma première interface.</p>
<figure id="attachment_1245" aria-describedby="caption-attachment-1245" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_schematic.png"><img decoding="async" class="size-medium wp-image-1245" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:127/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_schematic.png" alt="" width="300" height="127" /></a><figcaption id="caption-attachment-1245" class="wp-caption-text">Le schéma de la button box</figcaption></figure>
<p>L&rsquo;implantation est par contre beaucoup plus compacte.</p>
<figure id="attachment_1255" aria-describedby="caption-attachment-1255" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_board.png"><img decoding="async" class="wp-image-1255 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:133/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_board.png" alt="" width="300" height="133" /></a><figcaption id="caption-attachment-1255" class="wp-caption-text">Le PCB de la button box</figcaption></figure>
<h2>Réalisation</h2>
<p>Pour une fois, j&rsquo;ai décidé de sous traiter la fabrication des circuits (au-delà d&rsquo;un exemplaire, la gravure à la fraiseuse n&rsquo;est pas franchement efficace). J&rsquo;ai donc envoyé tout ça chez les chinois (<a href="https://www.nextpcb.com/" target="_blank" rel="noopener">NextPCB</a> pour ne pas les citer). Le résultat est impeccable, pour un prix de revient d&rsquo;1.60€/pièce, port compris :</p>
<figure id="attachment_1246" aria-describedby="caption-attachment-1246" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_20210524_190610-scaled.jpg"><img decoding="async" class="size-medium wp-image-1246" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:169/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_20210524_190610.jpg" alt="" width="300" height="169" /></a><figcaption id="caption-attachment-1246" class="wp-caption-text">Les PCB fabriqués par les chinois de NextPCB</figcaption></figure>
<p>Seul petit bémol : la durée de livraison pour l&rsquo;expédition économique : compter plusieurs semaines. Place à la soudure !</p>
<figure id="attachment_1250" aria-describedby="caption-attachment-1250" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_20210526_191906-scaled.jpg"><img decoding="async" class="size-medium wp-image-1250" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:169/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_20210526_191906.jpg" alt="" width="300" height="169" /></a><figcaption id="caption-attachment-1250" class="wp-caption-text">La fabrication en série, c&rsquo;est un métier &#8230;</figcaption></figure>
<h2>Programmation</h2>
<p>Là encore, rien de révolutionnaire : le code est écrit en C avec <a href="https://www.mikroe.com/mikroc-pic" target="_blank" rel="noopener">MikroC for PIC</a>. Les PIC sont ensuite flashés en série grâce à un PicKit et <a href="https://www.microchip.com/en-us/development-tools-tools-and-software/embedded-software-center/mplab-integrated-programming-environment" target="_blank" rel="noopener">MPLAB IPE</a>.</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_20210527_214615-scaled.jpg"><img decoding="async" class="aligncenter size-medium wp-image-1252" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:169/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_20210527_214615.jpg" alt="" width="300" height="169" /></a></p>
<p>Le descripteur HID déclare donc 16 entrées switch et 8 axes analogiques:</p>
<div class="snippetcpt-wrap" id="snippet-1256" data-id="1256" data-edit="" data-copy="/category/non-classe/feed/?snippet=ed1a2b5598&#038;id=1256" data-fullscreen="https://amaury-laurent.fr/code-snippets/descripteur-uhi-pour-button-box/?full-screen=1">
				<pre class="prettyprint linenums lang-c_cpp" title="Descripteur HID pour Button Box">hid_rpt_desc =
  {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x15, 0x00,                    // LOGICAL_MINIMUM (0)
    0x09, 0x04,                    // USAGE (Joystick)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x05, 0x02,                    //   USAGE_PAGE (Simulation Controls)
    0x09, 0xbb,                    //   USAGE (Throttle)
    0x09, 0xc5,                    //   USAGE (Brake)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x02,                    //   REPORT_COUNT (2)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x01,                    //   USAGE_PAGE (Generic Desktop)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x09, 0x32,                    //     USAGE (Z)
    0x09, 0x33,                    //     USAGE (Rx)
    0x09, 0x34,                    //     USAGE (Ry)
    0x09, 0x35,                    //     USAGE (Rz)
    0x95, 0x06,                    //     REPORT_COUNT (6)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
    0x29, 0x10,                    //   USAGE_MAXIMUM (Button 16)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x10,                    //   REPORT_COUNT (16)
    0x55, 0x00,                    //   UNIT_EXPONENT (0)
    0x65, 0x00,                    //   UNIT (None)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
  };</pre>
			</div>
<p>Le rapport USB associé est le suivant:</p>
<table class="customTable">
<tbody>
<tr>
<th colspan="9">USB Report</th>
</tr>
<tr>
<th>octet 0</th>
<td colspan="8">Throttle</td>
</tr>
<tr>
<th>octet 1</th>
<td colspan="8">Brake</td>
</tr>
<tr>
<th>octet 2</th>
<td colspan="8">Axe X</td>
</tr>
<tr>
<th>octet 3</th>
<td colspan="8">Axe Y</td>
</tr>
<tr>
<th>octet 4</th>
<td colspan="8">Axe Z</td>
</tr>
<tr>
<th>octet 5</th>
<td colspan="8">Axe RX</td>
</tr>
<tr>
<th>octet 6</th>
<td colspan="8">Axe RY</td>
</tr>
<tr>
<th>octet 7</th>
<td colspan="8">Axe RZ</td>
</tr>
<tr>
<th>octet 8</th>
<td>DI 00</td>
<td>DI 01</td>
<td>DI 02</td>
<td>DI 03</td>
<td>DI 04</td>
<td>DI 05</td>
<td>DI 06</td>
<td>DI 07</td>
</tr>
<tr>
<th>octet 9</th>
<td>DI 08</td>
<td>DI 09</td>
<td>DI 10</td>
<td>DI 11</td>
<td>DI 12</td>
<td>DI 13</td>
<td>DI 14</td>
<td>DI 15</td>
</tr>
</tbody>
</table>
<h2>Utilisation</h2>
<p>Le câblage des entrées analogiques peut exploiter l&rsquo;alimentation de la carte (5V sur USB) pour utiliser des potentiomètres:</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_Analogic.png"><img decoding="async" class="aligncenter size-medium wp-image-1264" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:227/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_Analogic.png" alt="" width="300" height="227" /></a></p>
<p>Le câblage des boutons se fait entre la broche d&rsquo;entrée et la masse. La résistance de pull-up interne s&rsquo;occupe de polariser l&rsquo;entrée quand le bouton est ouvert.</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_Digital.png"><img decoding="async" class="aligncenter size-medium wp-image-1265" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:274/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_Digital.png" alt="" width="300" height="274" /></a></p>
<p>Une fois le tout branché et l&rsquo;USB relié au PC, Windows devrait voir un nouveau périphérique de jeu:</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_Windows.png"><img decoding="async" class="aligncenter size-medium wp-image-1267" src="https://ml9zfxsqktal.i.optimole.com/w:266/h:300/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/06/BUTTON_Windows.png" alt="" width="266" height="300" /></a></p>
<h2>Conclusion</h2>
<p>Il ne reste qu&rsquo;à faire la mécanique !</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/boite-a-boutons-pour-simulateurs/">Boite à boutons pour simulateurs</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://amaury-laurent.fr/boite-a-boutons-pour-simulateurs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Un FabLab à Chambéry !</title>
		<link>https://amaury-laurent.fr/fablab-a-chambery/</link>
					<comments>https://amaury-laurent.fr/fablab-a-chambery/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Fri, 12 May 2017 16:33:05 +0000</pubDate>
				<category><![CDATA[Non classé]]></category>
		<guid isPermaLink="false">http://amaury-laurent.fr/?p=814</guid>

					<description><![CDATA[<p>Un FabLab est en train de se monter à Chambéry ! Voici l&#8217;adresse du site web : http://leprototype.info/ Et la communauté Google+ : https://plus.google.com/communities/102420477003488972725 Le local est au 57 Faubourg Montmélian: N&#8217;hésitez pas à vous renseigner !</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/fablab-a-chambery/">Un FabLab à Chambéry !</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Un FabLab est en train de se monter à Chambéry !</p>
<p>Voici l&rsquo;adresse du site web : <a href="http://leprototype.info/" target="_blank" rel="noopener">http://leprototype.info/</a></p>
<p>Et la communauté Google+ : <a href="https://plus.google.com/communities/102420477003488972725" target="_blank" rel="noopener">https://plus.google.com/communities/102420477003488972725</a></p>
<p>Le local est au 57 Faubourg Montmélian:</p>
<p><iframe style="border: 0;"  src="about:blank" data-opt-src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d698.3029126513773!2d5.926184129259765!3d45.56618223758111!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x478ba8fb6e2ac8a3%3A0x89a183dfade1432d!2sFabLab+Chamb%C3%A9ry!5e0!3m2!1sfr!2sfr!4v1494606366196" width="800" height="400" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
<p>N&rsquo;hésitez pas à vous renseigner !</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/fablab-a-chambery/">Un FabLab à Chambéry !</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://amaury-laurent.fr/fablab-a-chambery/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Récepteur radio-modélisme sur USB</title>
		<link>https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/</link>
					<comments>https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/#comments</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Tue, 09 May 2017 21:24:57 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Réalisation]]></category>
		<guid isPermaLink="false">http://amaury-laurent.fr/?p=721</guid>

					<description><![CDATA[<p>Ou comment récupérer sur un PC les consignes émises par une radiocommande Introduction Quoi de plus normal pour un hacker que d&#8217;essayer de hacker tout ce qui bouge? C&#8217;est probablement l&#8217;idée qui m&#8217;a traversé l&#8217;esprit quand j&#8217;ai mis en route ma première radiocommande: comment l&#8217;utiliser pour piloter tout et n&#8217;importe quoi? Une solution serait de [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/">Récepteur radio-modélisme sur USB</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Ou comment récupérer sur un PC les consignes émises par une radiocommande</h1>
<h2>Introduction</h2>
<p>Quoi de plus normal pour un hacker que d&rsquo;essayer de hacker tout ce qui bouge?</p>
<p>C&rsquo;est probablement l&rsquo;idée qui m&rsquo;a traversé l&rsquo;esprit quand j&rsquo;ai mis en route ma première radiocommande: comment l&rsquo;utiliser pour piloter tout et n&rsquo;importe quoi? Une solution serait de concevoir intégralement un récepteur radio 2.4GHz et décoder le signal de la radiocommande. Cette solution permettrait de récupérer l&rsquo;intégralité des voies de la radio. Elle est par contre particulièrement complexe.</p>
<p>C&rsquo;est pourquoi, je vais vous proposer une solution détournée: récupérer les signaux de pilotage servomoteurs derrière un récepteur radio du commerce. Il suffit alors de lire les signaux modulés en largeur d&rsquo;impulsion pour avoir la valeur émise par la radio.</p>
<p>Le montage que je vous propose permet de numériser les signaux destinés aux servomoteurs de modélisme. Les valeurs acquises sont ensuite envoyées à un PC <em>via</em> une prise USB.</p>
<p>Grâce au protocole HID, le montage est vu par le système d&rsquo;exploitation (Windows, Linux, Mac) comme un joystick sans installer de pilotes particuliers.</p>
<p>Il ne reste plus qu&rsquo;à exploiter les valeurs pour l&rsquo;usage que vous aurez imaginé :</p>
<ul>
<li>Piloter un simulateur de vol sans fil</li>
<li>Piloter un système déporté (robot, caméra IP, &#8230;)</li>
<li>&#8230;</li>
</ul>
<h2>Un peu de théorie</h2>
<p>Un récepteur de modélisme sert à recevoir et décoder les ordres émis par la radiocommande et les envoyer aux actionneurs (servomoteurs, variateurs, &#8230;). Le pilotage des actionneurs de modélisme est standard:</p>
<ul>
<li>Ils reçoivent des signaux carrés d&rsquo;une période de 22 millisecondes</li>
<li>La largeur de l&rsquo;état haut varie entre 1ms et 2ms</li>
<li>1ms correspond à 0% (ou -100%)</li>
<li>2ms correspond à 100 %</li>
<li>L&rsquo;amplitude du signal est déterminée par la tension d&rsquo;alimentation du récepteur</li>
</ul>
<figure id="attachment_727" aria-describedby="caption-attachment-727" style="width: 400px" class="wp-caption aligncenter"><a class="fancybox" href="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG004.bmp"><img decoding="async" class="wp-image-727 size-full" src="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG004.bmp" alt="" width="400" height="240" /></a><figcaption id="caption-attachment-727" class="wp-caption-text">Signal à la sortie d&rsquo;un récepteur AR400 alimenté en 3.3V. Notez bien la période de 22ms entre chaque impulsion</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_724" aria-describedby="caption-attachment-724" style="width: 400px" class="wp-caption aligncenter"><a class="fancybox" href="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG001.bmp"><img decoding="async" class="size-full wp-image-724" src="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG001.bmp" alt="" width="400" height="240" /></a><figcaption id="caption-attachment-724" class="wp-caption-text">Impulsion 0% =&gt; environ 1ms</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_726" aria-describedby="caption-attachment-726" style="width: 400px" class="wp-caption aligncenter"><a class="fancybox" href="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG003.bmp"><img decoding="async" class="size-full wp-image-726" src="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG003.bmp" alt="" width="400" height="240" /></a><figcaption id="caption-attachment-726" class="wp-caption-text">Impulsion 100% =&gt; environ 2ms</figcaption></figure>
<p>Il s&rsquo;agit donc de signaux modulés en largeur d&rsquo;impulsion ou PWM (<em>Pulse Width Modulation</em>).</p>
<p>Pour information, la largeur d&rsquo;impulsion n&rsquo;est que de 10% de la période totale pour permettre au récepteur de générer jusqu&rsquo;à 10 voies séquentiellement:</p>
<p><a class="fancybox" href="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG004-1.bmp"><img decoding="async" class="aligncenter size-full wp-image-804" src="https://amaury-laurent.fr/wp-content/uploads/2017/05/IMAG004-1.bmp" alt="" width="400" height="240" /></a></p>
<p>Le fonctionnement du récepteur en est donc simplifié: il n&rsquo;a qu&rsquo;une impulsion à générer à la fois.</p>
<h2>Mise en application</h2>
<h3>Choix du matériel</h3>
<p>Le récepteur radio que j&rsquo;ai choisi pour ce montage est un <a class="fancybox-iframe" href="https://www.spektrumrc.com/Products/Default.aspx?ProdID=SPMAR400" target="_blank" rel="noopener noreferrer">Spektrum AR400</a>. Il s&rsquo;agit d&rsquo;un récepteur <a href="https://www.spektrumrc.com/Technology/DSM2.aspx" target="_blank" rel="noopener noreferrer">DSM2</a>/<a href="http://www.spektrumrc.com/Technology/DSMX.aspx" target="_blank" rel="noopener noreferrer">DSMX </a>4 voies dédié à l&rsquo;aéromodélisme. Il est en outre capable de gérer la télémétrie (future évolution du projet?).</p>
<p>Pour numériser les signaux PWM, je compte utiliser un microcontrôleur doté d&rsquo;une connexion USB. Mon affinité me pousse naturellement chez Microchip. J&rsquo;ai donc commencé le développement sur un <a class="fancybox-iframe" href="http://www.microchip.com/wwwproducts/en/PIC32MX795F512H#utm_source=MicroSolutions&amp;utm_medium=Link&amp;utm_term=FY16Q4&amp;utm_content=MCU32&amp;utm_campaign=Article" target="_blank" rel="noopener noreferrer">PIC32MX795F512H </a>que j&rsquo;avais sous la main. Malheureusement, il se trouve que l&rsquo;utilisation que je vais décrire dans cet article n&rsquo;est pas bien supportée par mon compilateur, spécifiquement sur cette famille de PIC32. En effet, le contrôleur d&rsquo;interruption ne semble pas bien configuré. Je suis donc passé sur un <a class="fancybox-iframe" href="http://www.microchip.com/wwwproducts/en/PIC32MX440F256H" target="_blank" rel="noopener noreferrer">PIC32MX440F256H</a>.</p>
<p>La carte de développement utilisée est une <a class="fancybox-iframe" href="https://www.olimex.com/Products/Duino/PIC32/PIC32-PINGUINO-MICRO/open-source-hardware" target="_blank" rel="noopener noreferrer">Pinguino Micro </a>de chez Olimex, reprogrammée avec le <a href="https://amaury-laurent.fr/wp-content/uploads/2017/05/mikrobootloader-start-usb-manual-v100.pdf">bootloader USB</a> de Mikroelektronika.</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2017/05/PIC32-PINGUINO-MICRO-01.jpg"><img decoding="async" class="aligncenter size-medium wp-image-737" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:228/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2017/05/PIC32-PINGUINO-MICRO-01.jpg" alt="" width="300" height="228" /></a>L&rsquo;idée est d&rsquo;utiliser les 4 modules <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/60001122G.pdf" target="_blank" rel="noopener noreferrer">Input Capture</a> disponibles dans le PIC32. Ces modules permettent de faire des mesures temporelles sur des signaux digitaux. J&rsquo;utilise donc un module par voie du récepteur.</p>
<h3>Câblage</h3>
<p>Le câblage électrique est des plus simple. La carte Pinguino est autonome. L&rsquo;alimentation électrique provient directement de la prise USB. Un régulateur 3.3V présent sur la carte permet d&rsquo;alimenter l&rsquo;AR400 avec une tension compatible PIC32 (ces derniers peuvent être chatouilleux sur certaines broches avec le 5V par exemple).</p>
<p>Sur l&rsquo;AR400, on note 5 rangées de 3 pins. De gauche à droite, on trouve:</p>
<ul>
<li>Association/Télémétrie</li>
<li>Gaz</li>
<li>Ailerons</li>
<li>Gouverne de profondeur</li>
<li>Gouverne de direction</li>
</ul>
<p>Ensuite, de haut en bas, on trouve:</p>
<ul>
<li>Signal</li>
<li>+Vcc</li>
<li>Gnd</li>
</ul>
<p>Voici donc le schéma de câblage (si l&rsquo;on peut appeler ça comme ça&#8230;)</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2017/05/schéma.png"><img decoding="async" class="aligncenter size-medium wp-image-743" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:185/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2017/05/schéma.png" alt="" width="300" height="185" /></a></p>
<h3>Le module Input Capture</h3>
<p>Ce module est présent dans la plupart des microcontrôleurs Microchip. Il permet de récupérer la valeur d&rsquo;un Timer sur un front de signal. Comme tous les modules d&rsquo;un microcontrôleur, il est possible de le configurer:</p>
<ul>
<li>Choix du premier front de déclenchement (montant ou descendant)</li>
<li>Mode de déclenchement (armement pour un front, sur les fronts montants, sur les fronts descendants, sur tous les fronts&#8230;)</li>
<li>Périodicité des interruptions (tous les fronts, tous les 2 fronts, &#8230;)</li>
<li>Pour les PIC32, choix de la taille du compteur (16 ou 32 bits)</li>
</ul>
<p>J&rsquo;ai choisi d&rsquo;utiliser un Timer sur 32 bits, de déclencher sur tous les fronts, de commencer par un front montant et d&rsquo;avoir une interruption à chaque déclenchement. Ce qui donne la configuration suivante (cf: <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/60001122G.pdf" target="_blank" rel="noopener noreferrer">datasheet du module Input Capture, page 6</a>):</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">IC1CONbits.ICM = 0b110; //Simple Capture Event mode – every edge, specified edge first and every edge thereafter
IC1CONbits.FEDGE = 1; //Capture rising edge first
IC1CONbits.C32 = 1; //32-bit timer resource capture
IC1CONbits.ICI = 0; //Interrupt on every capture event
IC1CONbits.ICSIDL = 0; Continue to operate in CPU Idle mode
 
//Dupplication de la configuration sur tous les modules Input Capture    
IC2CON = IC1CON;
IC3CON = IC1CON;
IC4CON = IC1CON;

</pre>
<p>Cependant, le module Input Capture ne fonctionne pas seul: il travail conjointement avec le Timer 2. Il convient donc de le configurer également:</p>
<ul>
<li>Source d&rsquo;horloge: interne</li>
<li>Pas de prescaler (avec une horloge à 80MHz, la valeur de comptage devrait être comprise entre 80000 (1ms) et 160000 (2ms), ce qui donne une résolution plus qu&rsquo;acceptable)</li>
<li>Timer sur 32 bits</li>
<li>Pas de GATE</li>
<li>Période de comptage 0xFFFFFFFF</li>
</ul>
<p>Ce qui donne la configuration suivante (cf: <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/61105F.pdf" target="_blank" rel="noopener noreferrer">datasheet du module timer, page 9</a>):</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">T2CONSET.f1 = 0; //Internal peripheral clock
T2CONSETbits.T32 = 1; //TMRx and TMRy form a 32-bit timer
T2CONSETbits.TGATE = 0; //Gated time accumulation is disabled
T2CONSETbits.TCKPS0 = 0; //1:1 prescale value
T2CONSETbits.TCKPS1 = 0;
T2CONSETbits.TCKPS2 = 0;
TMR2 = 0;
PR2 = 0xFFFFFFFF;
T2CONSETbits.ON = 1; //Module is enabled

</pre>
<p>&nbsp;</p>
<p>NB : tous les modules Input Capture du PIC32MX440 accèdent au Timer2.</p>
<h3>La routine d&rsquo;interruption</h3>
<p>La majorité du code contenu dans le microcontrôleur s&rsquo;exécute sur interruptions. Sur front montant, je lis et mémorise la valeur du Timer2. Sur front descendant, je calcul la durée de l&rsquo;impulsion en faisant la différence des valeurs courante et précédente du Timer2.</p>
<p>NB : Dès qu&rsquo;un évènement est capturé par un module Input Capture, il copie la valeur du registre TMR2 dans le registre ICxBUF, qui est en réalité une FIFO. Elle stocke les valeurs de comptage des derniers évènements acquis.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void IC1_ISR() iv IVT_INPUT_CAPTURE_1 ilevel 6 ics ICS_SOFT {
     unsigned long temp = 0;
     LATG.f6 = 1;
     sync = 1;
     TMR1 = 0; //reset timeout comm.
     temp = IC1BUF;
     IC1BUF = 0;
     if (toogle1 == 0) {
         ic1_start = temp;
         toogle1 = 1;
     }
     else {
         // value1 = CalculDelta(temp, ic1_start);
         
         // Calcul T2-T1, même si le timer déborde et repart à 0
         if (temp&lt;ic1_start) {
            // théoriquement impossible sauf en cas de débordement
            value1 = 4294967295-(ic1_start-temp)+1;
         }
         else value1 = temp-ic1_start;
         toogle1 = 0;
     }
     debug_toogle++;
     if (debug_toogle &gt;= 50) {
        debug_toogle = 0;
        LATD.f1 = !PORTD.f1;
     }
     IC1IF_bit = 0;
}

</pre>
<p>Je profite de la disposition du Timer 1 pour gérer un timeout: en cas de perte de la liaison radio, le signal PWM disparait et le Timer 1 n&rsquo;est plus remis à zéro. Le débordement du timer (environ en 200ms) indique une perte du signal. A noter également la gestion du débordement du Timer 2: à 80MHz sur 32 bits, il survient assez rapidement (53 secondes).</p>
<p>NB : La voie de pilotage des gaz génère tout le temps un signal. En cas de perte de la radiocommande, une impulsion de 1ms est envoyée pour remettre les gaz à 0.</p>
<p>Cette routine est dupliquée pour tous les modules Input Capture.</p>
<p><span style="color: #ff0000;">ATTENTION!</span> il ne faut pas utiliser de sous fonction commune aux 4 interruptions: elle créent un couplage nuisible au fonctionnement du programme.</p>
<p>NB : Il est impossible de remettre à 0 le flag ICxIF_bit tant que le registre ICxBUF n&rsquo;a pas été lu intégralement.</p>
<h3>La communication USB</h3>
<p>Dans un premier temps, j&rsquo;ai choisi de remonter les valeurs des voies sur un PC <em>via</em> un bus USB. Le plus simple à gérer pour Windows est un périphérique HID compatible joystick. J&rsquo;ai donc récupéré et nettoyé le descripteur USB de mon <a href="https://amaury-laurent.fr/2016/02/09/joystick-usb-sur-pic32/">simulateur de Joystick</a>. Le nouveau descripteur gère 4 axes (X, Y, Rx et Ry) sur 16 bits.</p>
<p>Voici le descripteur :</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">{
    0x05, 0x01,                        // USAGE_PAGE (Generic Desktop)
    0x09, 0x04,                        // USAGE (Joystick)
    0xa1, 0x01,                        // COLLECTION (Application)
    0x09, 0x01,                        //   USAGE (Pointer)
    0xa1, 0x00,                        //   COLLECTION (Physical)
    0x09, 0x30,                        //     USAGE (X)
    0x09, 0x31,                        //     USAGE (Y)
    0x09, 0x34,                        //     USAGE (Ry)
    0x09, 0x33,                        //     USAGE (Rx)
    0x15, 0x00,                        //     LOGICAL_MINIMUM (0)
    0x27, 0xff, 0xff, 0x00, 0x00,    //     LOGICAL_MAXIMUM (65535)
    0x75, 0x10,                        //     REPORT_SIZE (16)
    0x95, 0x04,                        //     REPORT_COUNT (4)
    0x81, 0x02,                        //     INPUT (Data,Var,Abs)
    0xc0,                            //     END_COLLECTION
    0xc0                            // END_COLLECTION
}

</pre>
<p>&nbsp;</p>
<p>Le rapport USB envoyé au PC est décrit de la manière suivante:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef union {
    char bytes[8];
    struct {
        unsigned int x_value;
        unsigned int y_value;
        unsigned int rx_value;
        unsigned int ry_value;
    };
} T_USB_Report;

</pre>
<p>La boucle principale de programme est donc très simple: elle récupère les 4 valeurs, leur soustrait 80000 et les divise par 1.22. On obtient ainsi une valeur comprise entre 0 et 65573. Il convient de borner les valeurs finales obtenues en cas de dépassement de la gamme (&lt;0 ou &gt;65535). Les valeurs sont ensuite stockées dans le rapport USB et envoyées au PC.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">while (1) {
    MyReport.x_value = (value1-MIN_PERIOD)/1.22;
    MyReport.y_value = (value2-MIN_PERIOD)/1.22;
    MyReport.rx_value = (value3-MIN_PERIOD)/1.22;
    MyReport.ry_value = (value4-MIN_PERIOD)/1.22;
    HID_Write(MyReport.bytes, sizeof(MyReport));
    delay_ms(10);
}

</pre>
<p>Ainsi, il devient possible de récupérer sous Windows les 4 voies de la radiocommande, en USB et sans driver spécifique:</p>
<figure id="attachment_728" aria-describedby="caption-attachment-728" style="width: 264px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2017/05/parametres.png"><img decoding="async" class="size-medium wp-image-728" src="https://ml9zfxsqktal.i.optimole.com/w:264/h:300/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2017/05/parametres.png" alt="" width="264" height="300" /></a><figcaption id="caption-attachment-728" class="wp-caption-text">Assistant de configuration pour manette de jeux</figcaption></figure>
<h2>Le programme complet</h2>
<p>Voici le programme complet fonctionnel:</p>
<div class="source">
<pre class="EnlighterJSRAW" data-enlighter-language="c">
#include "USBdsc.c"
#define MIN_PERIOD        80000.0
 
typedef union {
    char bytes[8];
    struct {
        unsigned int x_value;
        unsigned int y_value;
        unsigned int rx_value;
        unsigned int ry_value;
    };
} T_USB_Report;
 
T_USB_Report MyReport;
 
int debug_toogle = 0;
 
unsigned long int ic1_start = 0;
unsigned long int value1 = 0;
int toogle1 = 0;
 
unsigned long int ic2_start = 0;
unsigned long int value2 = 0;
int toogle2 = 0;
 
unsigned long int ic3_start = 0;
unsigned long int value3 = 0;
int toogle3 = 0;
 
unsigned long int ic4_start = 0;
unsigned long int value4 = 0;
int toogle4 = 0;
 
int sync = 0;
 
char ReadBuffer[64], WriteBuffer[64];
 
unsigned long int CalculDelta (unsigned long int T2, unsigned long int T1) {
    // Calcul T2-T1, même si le timer déborde et repart à 0
    if (T2&lt;T1) {
       // théoriquement impossible sauf en cas de débordement
       return 4294967295-(T1-T2)+1;
    }
    else return T2-T1;
}
 
void IC1_ISR() iv IVT_INPUT_CAPTURE_1 ilevel 6 ics ICS_SOFT {
     unsigned long temp = 0;
     LATG.f6 = 1;
     sync = 1;
     TMR1 = 0; //reset timeout comm.
     temp = IC1BUF;
     IC1BUF = 0;
     if (toogle1 == 0) {
         ic1_start = temp;
         toogle1 = 1;
     }
     else {
         // value1 = CalculDelta(temp, ic1_start);
         
         // Calcul T2-T1, même si le timer déborde et repart à 0
         if (temp&lt;ic1_start) {
            // théoriquement impossible sauf en cas de débordement
            value1 = 4294967295-(ic1_start-temp)+1;
         }
         else value1 = temp-ic1_start;
         toogle1 = 0;
     }
     debug_toogle++;
     if (debug_toogle &gt;= 50) {
        debug_toogle = 0;
        LATD.f1 = !PORTD.f1;
     }
     IC1IF_bit = 0;
}
 
void IC2_ISR() iv IVT_INPUT_CAPTURE_2 ilevel 5 ics ICS_SOFT {
     unsigned long temp = 0;
     temp = IC2BUF;
     IC2BUF = 0;
     if (toogle2 == 0) {
         ic2_start = temp;
         toogle2 = 1;
     }
     else {
         // value2 = CalculDelta(temp, ic2_start);
         
         // Calcul T2-T1, même si le timer déborde et repart à 0
         if (temp&lt;ic2_start) {
            // théoriquement impossible sauf en cas de débordement
            value2 = 4294967295-(ic2_start-temp)+1;
         }
         else value2 = temp-ic2_start;
         toogle2 = 0;
     }
     IC2IF_bit = 0;
}
 
void IC3_ISR() iv IVT_INPUT_CAPTURE_3 ilevel 4 ics ICS_SOFT {
     unsigned long temp = 0;
     temp = IC3BUF;
     IC3BUF = 0;
     if (toogle3 == 0) {
         ic3_start = temp;
         toogle3 = 1;
     }
     else {
         // value3 = CalculDelta(temp, ic3_start);
         
         // Calcul T2-T1, même si le timer déborde et repart à 0
         if (temp&lt;ic3_start) {
            // théoriquement impossible sauf en cas de débordement
            value3 = 4294967295-(ic3_start-temp)+1;
         }
         else value3 = temp-ic3_start;
         toogle3 = 0;
     }
     IC3IF_bit = 0;
}
 
void IC4_ISR() iv IVT_INPUT_CAPTURE_4 ilevel 3 ics ICS_SOFT {
     unsigned long temp = 0;
     temp = IC4BUF;
     IC4BUF = 0;
     if (toogle4 == 0) {
         ic4_start = temp;
         toogle4 = 1;
     }
     else {
         // value4 = CalculDelta(temp, ic4_start);
         // Calcul T2-T1, même si le timer déborde et repart à 0
         if (temp&lt;ic4_start) {
            // théoriquement impossible sauf en cas de débordement
            value4 = 4294967295-(ic4_start-temp)+1;
         }
         else value4 = temp-ic4_start;
         toogle4 = 0;
     }
     IC4IF_bit = 0;
}
 
void USB_ISR() iv IVT_USB_1 ilevel 7 ics ICS_SRS {
     USB_Interrupt_Proc();
     USBIF_bit = 0;
}
 
void TMR1_ISR() iv IVT_TIMER_1 ilevel 1 ics ICS_SOFT {
     LATG.f6 = 0;
     /*
     value1 = 120000;
     value2 = value1;
     value3 = value1;
     value4 = value1;
     */
     sync = 0;
     TMR1 = 0;
     T1IF_bit = 0;
}
 
void ClearBuffer (char * buffer, int buffer_len) {
     int i = 0;
     for (i=0; i&lt;buffer_len; i++) *(buffer+i) = 0;
}
 
void main() {
 
    toogle1 = 0;
    toogle2 = 0;
    toogle3 = 0;
    toogle4 = 0;
    ic1_start = 0;
    ic2_start = 0;
    ic3_start = 0;
    ic4_start = 0;
    value1 = 0;
    value2 = 0;
    value3 = 0;
    value4 = 0;
    debug_toogle = 0;
 
    AD1PCFG = 0xFFFF;
    JTAGEN_bit = 0;
    CHECON = 0x32;
    ODCB = 0;
    TRISD = 0xffff;
    TRISD.f1 = 0;
    TRISG.f6 = 0;
    LATG.f6 = 0;
    LATD.f1 = 0;
 
    IC1CONbits.ICM = 0b110;
    IC1CONbits.FEDGE = 1;
    IC1CONbits.C32 = 1;
    IC1CONbits.ICI = 0;
    IC1CONbits.ICSIDL = 0;
    
    IC2CON = IC1CON;
    IC3CON = IC1CON;
    IC4CON = IC1CON;
 
    T2CONSET.f1 = 0;
    T2CONSETbits.T32 = 1;
    T2CONSETbits.TGATE = 0;
    T2CONSETbits.TCKPS0 = 0;
    T2CONSETbits.TCKPS1 = 0;
    T2CONSETbits.TCKPS2 = 0;
    TMR2 = 0;
    PR2 = 0xFFFFFFFF;
    T2CONSETbits.ON = 1;
    
    PR1 = 65535;
    TMR1 = 0;
    T1CONSETbits.TCKPS0 = 1;
    T1CONSETbits.TCKPS1 = 1;
    T1CONSETbits.TGATE = 0;
    T1CONSETbits.SIDL = 0;
    T1CONSETbits.TCS = 0;
    T1CONSETbits.ON = 1;
 
    IC1IP0_bit = 0;
    IC1IP1_bit = 1;
    IC1IP2_bit = 1;
 
    IC2IP0_bit = 1;
    IC2IP1_bit = 0;
    IC2IP2_bit = 1;
 
    IC3IP0_bit = 0;
    IC3IP1_bit = 0;
    IC3IP2_bit = 1;
 
    IC4IP0_bit = 1;
    IC4IP1_bit = 1;
    IC4IP2_bit = 0;
    
    USBIP0_bit = 1;
    USBIP1_bit = 1;
    USBIP2_bit = 1;
    
    T1IP0_bit = 1;
    T1IP1_bit = 0;
    T1IP2_bit = 0;
 
    
    USBIE_bit = 1;
    IC1IE_bit = 1;
    IC2IE_bit = 1;
    IC3IE_bit = 1;
    IC4IE_bit = 1;
    T1IE_bit = 1;
    
    EnableInterrupts();
 
    HID_Enable(ReadBuffer, WriteBuffer);
    
    IC1CONbits.ON = 1;
    IC2CONbits.ON = 1;
    IC3CONbits.ON = 1;
    IC4CONbits.ON = 1;
 
    T4CONSETbits.ON = 1;
    
    while (1) {
          MyReport.x_value = (value1-MIN_PERIOD)/1.22;
          MyReport.y_value = (value2-MIN_PERIOD)/1.22;
          MyReport.rx_value = (value3-MIN_PERIOD)/1.22;
          MyReport.ry_value = (value4-MIN_PERIOD)/1.22;
          HID_Write(MyReport.bytes, sizeof(MyReport));
          delay_ms(10);
    }
}

</pre>
</div>
<h2> Conclusion</h2>
<p>Ce montage assez simple à réaliser permet de récupérer dans un microcontrôleur, puis sur un PC, les valeurs de 4 voies radiocommandées.</p>
<p>L&rsquo;utilisation du protocole HID permet de connecter le système sur n&rsquo;importe quel PC ou autre RaspberryPi/LattePanda/BeagleBoard/&#8230;</p>
<p>Il devient donc possible de commander à longue distance un dispositif autonome. Les idées ne vous manqueront pas, j&rsquo;en suis sûr 😉</p>
<p>[metaslider id=771]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/">Récepteur radio-modélisme sur USB</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>LINX 3.0 &#8211; Déploiement d&#8217;une application LabVIEW sur Raspberry Pi</title>
		<link>https://amaury-laurent.fr/linx-3-0-deploiement-dune-application-labview/</link>
					<comments>https://amaury-laurent.fr/linx-3-0-deploiement-dune-application-labview/#comments</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Mon, 05 Dec 2016 17:02:00 +0000</pubDate>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Informatique]]></category>
		<category><![CDATA[Microcontrôleur]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Digilent]]></category>
		<category><![CDATA[LabVIEW]]></category>
		<category><![CDATA[Linux RT]]></category>
		<category><![CDATA[LINX]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Raspbian]]></category>
		<guid isPermaLink="false">http://amaury-laurent.fr/?p=639</guid>

					<description><![CDATA[<p>LabVIEW permet de développer rapidement un petit programme: on dessine le diagramme, on exécute et voilà. Cependant, LabVIEW permet de faire bien plus. Une application embarquée va être amenée à fonctionner de manière autonome, dans un lieux potentiellement inaccessible. Il est alors indispensable que l&#8217;application soit téléchargée dans la cible et démarre automatiquement. Déployer son [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/linx-3-0-deploiement-dune-application-labview/">LINX 3.0 &#8211; Déploiement d&rsquo;une application LabVIEW sur Raspberry Pi</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a href="https://amaury-laurent.fr/index.php/2016/12/03/linx-3-0-programmer-raspberry-pi-labview/">LabVIEW permet de développer rapidement un petit programme</a>: on dessine le diagramme, on exécute et voilà.</p>
<p>Cependant, LabVIEW permet de faire bien plus. Une application embarquée va être amenée à fonctionner de manière autonome, dans un lieux potentiellement inaccessible. Il est alors indispensable que l&rsquo;application soit téléchargée dans la cible et démarre automatiquement.</p>
<h1>Déployer son application en mode autonome</h1>
<p>Une fois le programme mis au point, il est possible de le déployer à demeure dans la cible. Un petit peu comme on flasherait une programme dans un microcontrôleur. Pour ce faire, il faut créer une spécification de construction de type <strong>Real Time Application</strong> (bien que cette dernière n&rsquo;ai pas le déterminisme d&rsquo;une vrai application RT, du fait des limitations du Raspberry Pi).</p>
<figure id="attachment_627" aria-describedby="caption-attachment-627" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/rtexe.png"><img decoding="async" class="wp-image-627 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:118/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/rtexe.png" alt="rtexe" width="300" height="118" /></a><figcaption id="caption-attachment-627" class="wp-caption-text">Ajouter une spécification de construction</figcaption></figure>
<p>Un assistant de configuration s&rsquo;ouvre. La première page vous permet de nommer votre application et de choisir dans quel dossier elle sera construite.</p>
<figure id="attachment_628" aria-describedby="caption-attachment-628" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/info.png"><img decoding="async" class="wp-image-628 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:201/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/info.png" alt="info" width="300" height="201" /></a><figcaption id="caption-attachment-628" class="wp-caption-text">Les informations générales de votre application</figcaption></figure>
<p>La section la plus importante est la suivante: Source Files. Elle permet entre autre de choisir le VI de démarrage. Il s&rsquo;agit du premier VI lancé par le Run-Time au démarrage de l’application. Autrement dit, il s&rsquo;agit du Main de l&rsquo;application.</p>
<figure id="attachment_629" aria-describedby="caption-attachment-629" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/source_file.png"><img decoding="async" class="wp-image-629 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:201/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/source_file.png" alt="source_file" width="300" height="201" /></a><figcaption id="caption-attachment-629" class="wp-caption-text">Définir le VI principal de l&rsquo;application et les ressources nécessaires</figcaption></figure>
<p>Une autre page intéressant est celle concernant les options avancées. On y trouve notamment la possibilité de compiler l&rsquo;application en mode Debug, qui permet de connecter LabVIEW à l&rsquo;application compilée pour la debugguer <em>in situ.</em></p>
<figure id="attachment_630" aria-describedby="caption-attachment-630" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/advanced.png"><img decoding="async" class="wp-image-630 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:201/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/advanced.png" alt="advanced" width="300" height="201" /></a><figcaption id="caption-attachment-630" class="wp-caption-text">Quelques options avancées de l&rsquo;application</figcaption></figure>
<p>Une fois la spécification de construction terminée, ne cliquez pas directement sur Build, mais plutôt sur <strong>OK</strong>. Enregistrez ensuite l&rsquo;intégralité du projet. En effet, la configuration de la spécification de construction est sauvée dans le fichier .lvproj lui-même. La spécification apparait alors dans le projet. Il est possible de la compiler <em>via</em> le menu du clic droit en choisissant <strong>Build</strong>.</p>
<figure id="attachment_631" aria-describedby="caption-attachment-631" style="width: 280px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/build.png"><img decoding="async" class="wp-image-631 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:280/h:300/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/build.png" alt="build" width="280" height="300" /></a><figcaption id="caption-attachment-631" class="wp-caption-text">Lancer la compilation</figcaption></figure>
<p>Une fenêtre faisant apparaitre la progression de la compilation s&rsquo;ouvre:</p>
<figure id="attachment_632" aria-describedby="caption-attachment-632" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/build_in_progress.png"><img decoding="async" class="wp-image-632 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:163/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/build_in_progress.png" alt="build_in_progress" width="300" height="163" /></a><figcaption id="caption-attachment-632" class="wp-caption-text">La compilation de l&rsquo;application peut prendre un certain temps</figcaption></figure>
<p>Quand la compilation est terminée, cliquer sur Done.</p>
<figure id="attachment_633" aria-describedby="caption-attachment-633" style="width: 300px" class="wp-caption aligncenter"><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/build_termine.png"><img decoding="async" class="wp-image-633 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:166/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/12/build_termine.png" alt="build_termine" width="300" height="166" /></a><figcaption id="caption-attachment-633" class="wp-caption-text">Une fois terminé, l&rsquo;application est prête à être déployée</figcaption></figure>
<p>A ce stade, l&rsquo;application n&rsquo;est pas encore dans le Raspberry Pi. LabVIEW a juste généré le fichier binaire exécutable. Pour télécharger l&rsquo;application dans la cible et faire en sorte qu&rsquo;elle démarre automatiquement à la mise sous tension, il fait repasser par le menu du clic droit et choisir <strong>Run as startup</strong>.</p>
<p>LabVIEW télécharge alors le binaire dans le Raspberry Pi et configure ce dernier pour le lancer au démarrage. Un popup apparait alors pour vous proposer de redémarrer la cible. Acceptez et votre application devrait se lancer an quelques dizaines de secondes.</p>
<h1>Conclusion</h1>
<p>Une application compilée sera plus économe en ressources systèmes. Elle peut démarrer automatiquement, sans le recours à LabVIEW pour lancer le code. Cependant, il n&rsquo;y a plus d&rsquo;interface graphique, donc certaines fonctions sont inopérantes: les popups, les message d&rsquo;erreurs, &#8230; Il faut donc trouver d&rsquo;autres solutions pour communiquer, mais cela sera l&rsquo;objet d&rsquo;un autre article.</p>
<p>Bon dév à tous !</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/linx-3-0-deploiement-dune-application-labview/">LINX 3.0 &#8211; Déploiement d&rsquo;une application LabVIEW sur Raspberry Pi</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://amaury-laurent.fr/linx-3-0-deploiement-dune-application-labview/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Bienvenue sur la toile</title>
		<link>https://amaury-laurent.fr/bienvenue-sur-la-toile/</link>
					<comments>https://amaury-laurent.fr/bienvenue-sur-la-toile/#comments</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Sat, 28 Nov 2015 16:13:19 +0000</pubDate>
				<category><![CDATA[Non classé]]></category>
		<guid isPermaLink="false">http://vps200917.ovh.net/?p=332</guid>

					<description><![CDATA[<p>Bienvenue au nouveau site web d&#8217;Alexandre LEFEVRE, un ancien collègue de Polytech&#8217; Annecy-Chambéry ! http://wodric.com/ &#160; Bon vent 😉</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/bienvenue-sur-la-toile/">Bienvenue sur la toile</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Bienvenue au nouveau site web d&rsquo;Alexandre LEFEVRE, un ancien collègue de Polytech&rsquo; Annecy-Chambéry !</p>
<p><a href="http://wodric.com/" target="_blank" rel="noopener">http://wodric.com/</a></p>
<p>&nbsp;</p>
<p>Bon vent 😉</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/bienvenue-sur-la-toile/">Bienvenue sur la toile</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://amaury-laurent.fr/bienvenue-sur-la-toile/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
