<?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>Microcontrôleur &#8211; Electronique et Informatique</title>
	<atom:link href="https://amaury-laurent.fr/category/realisation/microcontroleur/feed/" rel="self" type="application/rss+xml" />
	<link>https://amaury-laurent.fr</link>
	<description>Site web d&#039;Amaury LAURENT</description>
	<lastBuildDate>Wed, 16 Jun 2021 16:50:51 +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>Microcontrôleur &#8211; Electronique et Informatique</title>
	<link>https://amaury-laurent.fr</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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" fetchpriority="high" 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/realisation/microcontroleur/feed/?snippet=4456c54862&#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>Nomad ND1 &#8211; Sous le capot</title>
		<link>https://amaury-laurent.fr/nomad-nd1-sous-le-capot/</link>
					<comments>https://amaury-laurent.fr/nomad-nd1-sous-le-capot/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Fri, 26 Feb 2021 18:06:39 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<category><![CDATA[LabVIEW]]></category>
		<category><![CDATA[mass effect]]></category>
		<category><![CDATA[nomad]]></category>
		<category><![CDATA[udp]]></category>
		<category><![CDATA[wireshark]]></category>
		<guid isPermaLink="false">https://amaury-laurent.fr/?p=1222</guid>

					<description><![CDATA[<p>Introduction Si vous aussi êtes fan de Mass Effect et avez investi dans l&#8217;édition collector de Mass Effect Andromeda, vous vous retrouvez sans doute avec un Nomad ND1 télécommandé par smartphone. Comme l&#8217;application Android est toute nulle perfectible et peu stable, il parait intéressant de piloter ce petit drone roulant à partir d&#8217;un PC ou, [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/nomad-nd1-sous-le-capot/">Nomad ND1 &#8211; Sous le capot</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>Si vous aussi êtes fan de Mass Effect et avez investi dans l&rsquo;édition collector de Mass Effect Andromeda, vous vous retrouvez sans doute avec un Nomad ND1 télécommandé par smartphone. Comme l&rsquo;application Android est <del>toute nulle</del> perfectible et peu stable, il parait intéressant de piloter ce petit drone roulant à partir d&rsquo;un PC ou, pourquoi pas, d&rsquo;une radio commande conventionnelle.</p>
<p>Pour ce faire, je vais décortiquer la communication mise en place entre le Nomad et le smart phone.</p>
<h1>Deux types de communication</h1>
<p>Le Nomad est télécommandé (vitesse, direction, allumage des feux) mais dispose également d&rsquo;une caméra afin de fournir un retour vidéo temps réel. Du coup, deux communications différentes sont utilisées.</p>
<h2>Connexion WiFi</h2>
<p>Tout d&rsquo;abord, il est bon de préciser que la communication radio entre le smartphone et le Nomad est basée sur une liaison WiFi 2.4GHz. Le Nomad est un point d&rsquo;accès avec serveur DHCP. Quand on connecte un périphérique réseau sur le Nomad, on obtient automatiquement une adresse IP.</p>
<p>Le Nomad sera toujours accessible à l&rsquo;adresse 192.168.0.1.</p>
<h2>Retour Vidéo</h2>
<p>Je commence par exposer le fonctionnement du retour vidéo puisqu&rsquo;il s&rsquo;agit du moins complexe et qu&rsquo;il peut être solutionné avec des logiciels comme VLC.</p>
<p>Le Nomad se comporte comme une caméra IP. Il héberge un serveur de <a href="https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol" target="_blank" rel="noopener">streaming RTSP</a>. Le point d&rsquo;accès vidéo est vs1. Il est donc possible d&rsquo;ouvrir le flux vidéo en accédant à l&rsquo;adresse:</p>
<p><a href="rtsp://192.168.0.1/vs1" target="_blank" rel="noopener">rtsp://192.168.0.1/vs1</a></p>
<figure id="attachment_1233" aria-describedby="caption-attachment-1233" 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/02/video_nomad.png"><img decoding="async" class="size-medium wp-image-1233" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:272/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/02/video_nomad.png" alt="VLC affichant le retour vidéo du Nomad" width="300" height="272" /></a><figcaption id="caption-attachment-1233" class="wp-caption-text">VLC affichant le retour vidéo du Nomad</figcaption></figure>
<h2>Télécommande</h2>
<p>L&rsquo;envoie des commandes au Nomad est un peu plus artisanal. En effet, la messagerie entre le smartphone et le Nomad exploite une communication UDP sans protocole standard particulier. Les informations qui vont suivre sont issues de mes observations et d&rsquo;analyses réseaux faites avec <a href="https://fr.wikipedia.org/wiki/Wireshark" target="_blank" rel="noopener">WireShark</a>. N&rsquo;ayant qu&rsquo;un seul Nomad sous la main, il est possible que le comportement décrit ne soit pas identique pour tous les modèles.</p>
<h3>Première connexion</h3>
<p>La communication UDP bidirectionnelle s’établit sur le port 8234. Comme l&rsquo;UDP n&rsquo;est pas un protocole en mode connecté, il est nécessaire de pouvoir vérifier la présence d&rsquo;un interlocuteur de l&rsquo;autre côté de la liaison. Pour ce faire, le Nomad propose une commande de ping.</p>
<p>Il est possible d&rsquo;envoyer la chaine <span style="font-family: terminal, monaco, monospace;">MAKO_CONNECT</span> et le Nomad répond <span style="font-family: terminal, monaco, monospace;">CONNECT_OK</span>.</p>
<p>On notera au passage l&rsquo;amalgame entre le mako et le nomade qui laisse supposé l’existence d&rsquo;un <a href="https://en.wikipedia.org/wiki/Mako_(Mass_Effect)" target="_blank" rel="noopener">mako</a> radiocommandé?</p>
<h3>Récupération du statut</h3>
<p>Il est possible de récupérer l&rsquo;état général du Nomad (niveau de batterie et allumage des feux). Pour ce faire, il faut envoyer la chaine <span style="font-family: terminal, monaco, monospace;">MAKO_READ_BATT</span>. Le Nomad va alors répondre trois lignes:</p>
<p><span style="font-family: terminal, monaco, monospace;">BATT=%d</span><br />
<span style="font-family: terminal, monaco, monospace;">LED1=%b</span><br />
<span style="font-family: terminal, monaco, monospace;">LED2=%b</span></p>
<p>On obtient le niveau de batterie entre 0 et 100%, ainsi que l&rsquo;état des deux groupes de feux avant (0=éteint, 1=allumé)</p>
<h3>Allumage des feux</h3>
<p>Pour gérer les feux avant du Nomad, il y a les commande <span style="font-family: terminal, monaco, monospace;">MAKO_LED%d_ON</span> et <span style="font-family: terminal, monaco, monospace;">MAKO_LED%d_OFF<span style="font-family: georgia, palatino, serif;">. Il est nécessaire de préciser dans la commande le numéro des feux à allumer ou éteindre (par exemple <span style="font-family: terminal, monaco, monospace;">MAKO_LED1_ON</span> ou <span style="font-family: terminal, monaco, monospace;">MAKO_LED2_OFF</span>). Le Nomad ne répond pas à ces commandes. Le statut des LED peut être récupérer par la commande précédente <span style="font-family: terminal, monaco, monospace;">MAKO_READ_BATT</span>.</span></span></p>
<h3>Envoie des consignes</h3>
<p>L&rsquo;envoie des consignes est un peu plus problématique. En effet, une seule commande binaire est utilisée pour envoyer les consignes de vitesse avant, de vitesse arrière et de direction. En outre, la commande semble contenir un numéro unique qui, s&rsquo;il est mal renseigné, bloque l&rsquo;interprétation de la commande complète.</p>
<p>Voici la structure de la trame binaire envoyée. Les valeurs sont données en hexadécimal:</p>
<table class="customTable" style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<th style="width: 73%; text-align: center;" colspan="8">? Identifiant de trame ?</th>
<th style="width: 9%;">F-Throttle</th>
<th style="width: 9%;">R-Throttle</th>
<th style="width: 9%;">Stearing</th>
</tr>
<tr>
<td style="width: 9%;">C0</td>
<td style="width: 9%;">A8</td>
<td style="width: 9%;">01</td>
<td style="width: 9%;">01</td>
<td style="width: 9%;">00</td>
<td style="width: 9%;">00</td>
<td style="width: 9%;">04</td>
<td style="width: 9%;">21</td>
<td style="width: 9%;">Uint8</td>
<td style="width: 9%;">Uint8</td>
<td style="width: 9%;">Uint8</td>
</tr>
</tbody>
</table>
<p>Les consignes de vitesse  sont données en 0-255, soit en marche avant, soit en marche arrière.</p>
<p>La consignes de direction est également en 0-255, avec la valeur 128 pour aller tout droit. 0 tourne à gauche, 255 tourne à droite.</p>
<p>La réponse du Nomad à cette commande est assez impénétrable:</p>
<table class="customTable" style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<th style="width: 64%; text-align: center;" colspan="10">? Identifiant de trame ?</th>
<th style="width: 6%;">?</th>
<th style="width: 6%;">?</th>
<th style="width: 6%;">F-Throttle</th>
<th style="width: 6%;">R-Throttle</th>
<th style="width: 6%;"></th>
<th style="width: 6%;"></th>
</tr>
<tr>
<td style="width: 6%;">C0</td>
<td style="width: 6%;">A8</td>
<td style="width: 6%;">01</td>
<td style="width: 6%;">01</td>
<td style="width: 6%;">00</td>
<td style="width: 6%;">00</td>
<td style="width: 6%;">09</td>
<td style="width: 6%;">F8</td>
<td style="width: 6%;">00</td>
<td style="width: 6%;">00</td>
<td style="width: 6%;">Uint8</td>
<td style="width: 6%;">Uint8</td>
<td style="width: 6%;">Uint8</td>
<td style="width: 6%;">Uint8</td>
<td style="width: 6%;">00</td>
<td style="width: 6%;">00</td>
</tr>
</tbody>
</table>
<p>On y retrouve le même code qu&rsquo;à la commande. Ensuite, il y a deux octets à 0, deux octets qui sembles avoir une valeur proche de 0x66, les recopies des deux consignes de vitesse et encore deux octets à 0.</p>
<h1>Conclusion</h1>
<p>Même s&rsquo;il reste quelques octets inexpliqués dans les trames d&rsquo;envoie de consigne et de réponse, il est tout à fait possible de piloter le Nomad depuis n&rsquo;importe quel périphérique WiFi. Voici d’ailleurs un driver LabVIEW permettant le pilotage du Nomad:</p>
<p><a href="https://amaury-laurent.fr/wp-content/uploads/2021/02/NomadND1_LV2019.zip">NomadND1_LV2019.zip</a></p>
<figure id="attachment_1236" aria-describedby="caption-attachment-1236" 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/02/NomadND1_LV.png"><img decoding="async" class="size-medium wp-image-1236" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:83/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2021/02/NomadND1_LV.png" alt="Utilisation du driver LabVIEW pour le Nomad" width="300" height="83" /></a><figcaption id="caption-attachment-1236" class="wp-caption-text">Utilisation du driver LabVIEW pour le Nomad</figcaption></figure>
<p>En outre, j&rsquo;envisage le développement d&rsquo;une interface Radio &lt;-&gt; WiFi à base d&rsquo;ESP32. L&rsquo;idée est de récupérer les signaux d&rsquo;écolage radio, voir les PWM de pilotage servo issues d&rsquo;un récepteurs modélisme et de générer les trames UDP « qui vont bien » afin de piloter le Nomad comme il se doit!</p>
<p>Si une âme charitable et possédant un Nomad peut tester le pilotage par UDP afin de s&rsquo;assurer que la trame C0A8 0101 0000 0421 XXXX XX fonctionne sans modifications, le retour d&rsquo;expérience sera intéressant pour compléter cette petite introduction au pilotage du Nomad 🙂</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/nomad-nd1-sous-le-capot/">Nomad ND1 &#8211; Sous le capot</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/nomad-nd1-sous-le-capot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Bruiteur pour avion de modélisme</title>
		<link>https://amaury-laurent.fr/bruiteur-pour-avion-de-modelisme/</link>
					<comments>https://amaury-laurent.fr/bruiteur-pour-avion-de-modelisme/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Sat, 28 Mar 2020 13:22:58 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[bruit]]></category>
		<category><![CDATA[bruiteur]]></category>
		<category><![CDATA[mp3-tf-16p]]></category>
		<guid isPermaLink="false">http://amaury-laurent.fr/?p=1164</guid>

					<description><![CDATA[<p>Introduction Les bruiteurs pour avion de modélisme disponibles dans le commerce sont relativement chers (150€ pour ce modèle de MotionRC). Aujourd&#8217;hui, avec les modules disponibles pour la bricole autour des arduinos, il doit être possible de fabriquer un bruiteur à moindre frais. C&#8217;est ce que je vais essayer de faire dans cette article. Le matériel [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/bruiteur-pour-avion-de-modelisme/">Bruiteur pour avion de modélisme</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>Les bruiteurs pour avion de modélisme disponibles dans le commerce sont relativement chers (<a href="https://www.motionrc.eu/products/mrrcsound-sound-system-v4-1-with-tt-25-for-rc-planes?currency=EUR&amp;gclid=Cj0KCQjw6_vzBRCIARIsAOs54z7eDnc8qQJ7Ps1kv2FbbPpJojIT23MwZ6qzaoDOGTuFIo5TambI-ZUaAqD5EALw_wcB" target="_blank" rel="noopener noreferrer">150€ pour ce modèle de MotionRC</a>). Aujourd&rsquo;hui, avec les modules disponibles pour la bricole autour des arduinos, il doit être possible de fabriquer un bruiteur à moindre frais. C&rsquo;est ce que je vais essayer de faire dans cette article.</p>
<h1>Le matériel</h1>
<p>Pour construire mon bruiteur, j&rsquo;ai choisi de partir sur un <a href="https://store.arduino.cc/arduino-nano" target="_blank" rel="noopener noreferrer">arduino nano</a> (<a href="https://fr.aliexpress.com/item/32341832857.html?spm=a2g0o.productlist.0.0.4710572feqWZKX&amp;algo_pvid=964beaf9-c200-43de-a4ff-fbb9f3ba8527&amp;algo_expid=964beaf9-c200-43de-a4ff-fbb9f3ba8527-0&amp;btsid=0b0a050b15853880297704945ed2fb&amp;ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_" target="_blank" rel="noopener noreferrer">ou sa copie chinoise</a>) et un module lecteur <a href="https://fr.aliexpress.com/item/32919672331.html?spm=a2g0o.productlist.0.0.292476fboFzC03&amp;algo_pvid=0cc2b0d0-9c24-437a-b1f9-f4cb3fb0c134&amp;algo_expid=0cc2b0d0-9c24-437a-b1f9-f4cb3fb0c134-0&amp;btsid=0b0a050b15853880860396376ed2fb&amp;ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_" target="_blank" rel="noopener noreferrer">MP3-TF-16P.</a></p>
<p>Le matériel le plus chers sera donc la carte SD pour stocker les fichiers sons.</p>
<figure id="attachment_1167" aria-describedby="caption-attachment-1167" 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/2020/03/nano.jpg"><img decoding="async" class="wp-image-1167 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:300/q:mauto/rt:fill/g:ce/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/03/nano.jpg" alt="Arduino nano" width="300" height="300" /></a><figcaption id="caption-attachment-1167" class="wp-caption-text">Arduino nano</figcaption></figure>
<p>L&rsquo;arduino nano sera utilisé pour acquérir le signal PPM de pilotage moteur et envoyer les informations de lecture fichiers au module MP3 <em>via</em> l&rsquo;UART.</p>
<p>Le module MP3-TF-16P est un codec audio associé à un amplificateur capable de décoder des fichiers MP3 et WAV et de les jouer sur un haut parleur de 3W.</p>
<figure id="attachment_1168" aria-describedby="caption-attachment-1168" 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/2020/03/mp3-tf-16p.jpg"><img decoding="async" class="wp-image-1168 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:279/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/03/mp3-tf-16p.jpg" alt="MP3-TF-16P - Pas plus gros qu'une carte SD plein format" width="300" height="279" /></a><figcaption id="caption-attachment-1168" class="wp-caption-text">MP3-TF-16P &#8211; Pas plus gros qu&rsquo;une carte SD plein format</figcaption></figure>
<h1>Principe de fonctionnement</h1>
<p>Le signal PPM issu du récepteur radio de l&rsquo;avion est un pulse de 1 à 2ms émis toutes les 22ms ou 11ms (DSMX). Pour plus de détail, rendez-vous sur la page <a href="https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/" target="_blank" rel="noopener noreferrer">Récepteur radio-modélisme sur USB.</a> L&rsquo;arduino doit donc mesurer la durée de l&rsquo;état haut du pulse. Cela tombe bien, une fonction native s&rsquo;en occupe: <a href="https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/" target="_blank" rel="noopener noreferrer">pulseIn()</a>. Elle renvoie la durée des pulses reçus sur une broche d&rsquo;entrée en µs.</p>
<p>La plage de 1000µs à 2000µs est découpée en 6 plages réparties comme suis:</p>
<p><strong>1000</strong> &#8212; <em>OFF</em>&#8212; <strong>1100</strong> &#8212; <em>RPM1</em> &#8212; <strong>1280</strong> &#8212; <em>RPM2</em> &#8212; <strong>1460</strong> &#8212; <em>RPM3</em> &#8212;<strong>1640</strong> &#8212; <em>RPM4</em> &#8212; <strong>1820</strong> &#8212; <em>RPM5</em> &#8212; <strong>2000</strong></p>
<p>Chaque plage est associée à un fichier son sur la carte SD. Exception faite de la plage MotorOff qui donne lieu à la lecteur d&rsquo;un fichier de démarrage moteur et d&rsquo;une fichier d&rsquo;arrêt moteur quand la consigne sort ou entre dans la plage.</p>
<p>Les fichiers sons sont téléchargeables sur le site <a href="https://simviation.com/1/browse-Flight+Simulator+Sounds-112-0" target="_blank" rel="noopener noreferrer">Simviation</a> par exemple.</p>
<h1>Câblage</h1>
<p>Le câblage du système est très simple:</p>
<ol>
<li>Récupérer une prise servo 3 points</li>
<li>Alimenter l&rsquo;arduino entre noir et rouge (5V issu du BEC du récepteur)</li>
<li>Alimenter le module MP3-TF-16P avec le même 5V (pin 1 : Vcc, pin 7 et pin 10 : Gnd)</li>
<li>Connecter le signal (fil orange) sur une entrée de l&rsquo;arduino (j&rsquo;utilise D2)</li>
<li>Connecter l&rsquo;UART du module MP3-TF-16P (pin 2 : Rx, pin 3 : Tx) sur les broches Rx et Tx de l&rsquo;arduino (pensez bien à croiser Rx-&gt;Tx et Tx-&gt;Rx)</li>
<li>Connecter le haut parleur sur le module MP3-TF-16P (pin 8 : Spk- et pin 6 : Spk+)</li>
</ol>
<p>C&rsquo;est tout!</p>
<p>[EDIT] Voici un schéma de la version amplifiée:</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/03/schema.png"><img decoding="async" class="aligncenter size-medium wp-image-1217" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:200/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/03/schema.png" alt="" width="300" height="200" /></a></p>
<p>La spécification du module MP3-TF-16P est <a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/Module-Datasheet.pdf" target="_blank" rel="noopener noreferrer">disponible ici</a>.</p>
<h1>Programmation de l&rsquo;arduino</h1>
<p>Le programme de l&rsquo;arduino est assez simple. Il est basé sur une machine à états qui gère les différents régimes moteurs et les transitions de l&rsquo;un à l&rsquo;autre.</p>
<figure id="attachment_1171" aria-describedby="caption-attachment-1171" style="width: 250px" 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/2020/03/state_machine.png"><img decoding="async" class="wp-image-1171 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:250/h:300/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/03/state_machine.png" alt="La machine à état de l'arduino" width="250" height="300" /></a><figcaption id="caption-attachment-1171" class="wp-caption-text">La machine à état de l&rsquo;arduino</figcaption></figure>
<p>Le code source de l&rsquo;arduino est <a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/bruiteur_rc.zip">disponible ici</a>. La version que je propose utilise 7 fichiers son au total. Pour des raisons de simplicité d&rsquo;intégration je n&rsquo;ai pas utilisé la bibliothèque <a href="https://github.com/DFRobot/DFPlayer-Mini-mp3" target="_blank" rel="noopener noreferrer">DFPlayer-Mini</a>, préférant écrire ma propre implémentation. En effet, le protocole de communication mise en place sur le MP3-TF-16P est relativement simple. Il est très bien décrit dans la spécification du module:</p>
<table class="customTable">
<tbody>
<tr>
<th>Byte</th>
<th>Description</th>
</tr>
<tr>
<td style="width: 786.983px;">0x7E</td>
<td style="width: 786.967px;">Start byte</td>
</tr>
<tr>
<td style="width: 786.983px;">0xFF</td>
<td style="width: 786.967px;">Version</td>
</tr>
<tr>
<td style="width: 786.983px;">0x06</td>
<td style="width: 786.967px;">Byte number in frame</td>
</tr>
<tr>
<td style="width: 786.983px;">CMD</td>
<td style="width: 786.967px;">Command to execute</td>
</tr>
<tr>
<td style="width: 786.983px;">0x00</td>
<td style="width: 786.967px;">Feedback not required</td>
</tr>
<tr>
<td style="width: 786.983px;">Param_MSB</td>
<td style="width: 786.967px;">Most Significant Byte of the 2 bytes of data</td>
</tr>
<tr>
<td style="width: 786.983px;">Param_LSB</td>
<td style="width: 786.967px;">Least Significant Byte of the 2 bytes of data</td>
</tr>
<tr>
<td style="width: 786.983px;">Chksum_MSB</td>
<td style="width: 786.967px;">Most Significant Byte of the 2 bytes of check sum</td>
</tr>
<tr>
<td style="width: 786.983px;">Chksum_LSB</td>
<td style="width: 786.967px;">Least Significant Byte of the 2 bytes of check sum</td>
</tr>
<tr>
<td style="width: 786.983px;">0xEF</td>
<td style="width: 786.967px;">End byte</td>
</tr>
</tbody>
</table>
<p>Le même format de trame est utilisée en réception et en émission.</p>
<h1>La carte SD</h1>
<p>Les fichier sons doivent être rangés et nommés d&rsquo;une certaine manière pour que le module puisse les lire. Voici l’arborescence que j&rsquo;utilise:</p>
<ul>
<li>01
<ul>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/001.wav">001.wav</a></li>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/002.wav">002.wav</a></li>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/003.wav">003.wav</a></li>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/004.wav">004.wav</a></li>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/005.wav">005.wav</a></li>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/006.wav">006.wav</a></li>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2020/03/007.wav">007.wav</a></li>
</ul>
</li>
</ul>
<p>Les fichier 001 et 007 sont les fichier startup et shutdown. Les fichiers 002 à 006 sont les régimes moteurs établis.</p>
<h1>[EDIT] Ajout d&rsquo;un amplificateur et utilisation d&rsquo;un haut parleur vibrant (exciter)</h1>
<p>Comme prévu, les haut parleurs de 3W ne donne pas satisfaction dans un avion RC: il faudrait percer le fuselage pour sortir le son. Un solution proposée entre autre par MotionRC est d&rsquo;utiliser des excitateur vibrants. Ils fonctionnent comme un haut-parleur électroacoustique, mais sans membrane. Au lieux de la membrane, il y a juste un adhésif double faces collé sur la bobine. En montant ce type de matériel sur un avion, tout le fuselage devient haut-parleur!</p>
<p>Le modèle que j&rsquo;ai retenu est un <a href="https://www.audiophonics.fr/fr/vibreur-exciter/dayton-audio-daex25fhe-4-haut-parleur-vibreur-exciter-24w-4-ohm-o27cm-p-8713.html" target="_blank" rel="noopener noreferrer">Dayton Audio DAEX25FHE-4</a> de 24W. Je l&rsquo;ai couplé à un amplificateur <span id="productTitle" class="a-size-large"><a href="https://www.amazon.fr/gp/product/B083QHWSYD/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&amp;psc=1" target="_blank" rel="noopener noreferrer">TPA3110 sur carte de développement</a> :</span></p>
<figure id="attachment_1209" aria-describedby="caption-attachment-1209" 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/2020/05/8713_daytonaudio_DAEX25FHE-4-exciter_1.jpg"><img decoding="async" class="size-medium wp-image-1209" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:240/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/05/8713_daytonaudio_DAEX25FHE-4-exciter_1.jpg" alt="" width="300" height="240" /></a><figcaption id="caption-attachment-1209" class="wp-caption-text">Le haut parleur vibrant</figcaption></figure>
<figure id="attachment_1210" aria-describedby="caption-attachment-1210" 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/2020/05/61pmHZNUjPL._AC_SL1001_.jpg"><img decoding="async" class="size-medium wp-image-1210" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:211/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/05/61pmHZNUjPL._AC_SL1001_.jpg" alt="" width="300" height="211" /></a><figcaption id="caption-attachment-1210" class="wp-caption-text">L&rsquo;ampli mono voie</figcaption></figure>
<p>J&rsquo;ai récupéré l&rsquo;une des deux sorties DAC_L ou DAC_R du module MP3-TF-16P pour attaquer l&rsquo;ampli. J&rsquo;alimente ce dernier avec une batterie 2S auxiliaire afin de ne pas endommager le circuit électrique principal de mon avion en cas de défaillance.</p>
<figure id="attachment_1211" aria-describedby="caption-attachment-1211" 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/2020/05/20200507_123632-scaled.jpg"><img decoding="async" class="size-medium wp-image-1211" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:169/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/05/20200507_123632.jpg" alt="" width="300" height="169" /></a><figcaption id="caption-attachment-1211" class="wp-caption-text">Le haut parleur et son ampli</figcaption></figure>
<figure id="attachment_1212" aria-describedby="caption-attachment-1212" 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/2020/05/20200508_112352-scaled.jpg"><img decoding="async" class="size-medium wp-image-1212" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:169/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2020/05/20200508_112352.jpg" alt="" width="300" height="169" /></a><figcaption id="caption-attachment-1212" class="wp-caption-text">L&rsquo;installation dans le fuselage</figcaption></figure>
<p>Voici le résultat en images (et surtout en musique&#8230;):</p>
<p style="text-align: center;"><iframe  src="about:blank" data-opt-src="//www.youtube.com/embed/8IVSXylbTVU" width="560" height="314" allowfullscreen="allowfullscreen"></iframe></p>
<h1>Conclusion</h1>
<p>Voici donc un petit bruiteur sans prétentions qui semble donner des résultats satisfaisants pour un budget contenu. Je n&rsquo;ai pas encore pu essayer avec un haut parleur de 3W, mais une chose est sûre: avec mon petit haut parleur de 0.1W, on n&rsquo;entend pas le bruiteur à cause du bruit de l&rsquo;hélice de l&rsquo;avion. Dans le pire des cas, j&rsquo;ajouterais un amplificateur de 3W additionnel sur la sortie non amplifiée du module pour mettre deux HP en stéréo sur l&rsquo;avion.</p>
<p>J’envisage d&rsquo;équiper un <a href="https://www.horizonhobby.com/sukhoi-su-29mm-%28gen-2%29-bnf-basic-efl8850" target="_blank" rel="noopener noreferrer">su29mm</a> de chez ParkZone.</p>
<p style="text-align: center;"><iframe  src="about:blank" data-opt-src="//www.youtube.com/embed/bsAWjExBL6I" width="560" height="314" allowfullscreen="allowfullscreen"></iframe></p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/bruiteur-pour-avion-de-modelisme/">Bruiteur pour avion de modélisme</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/bruiteur-pour-avion-de-modelisme/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2020/03/001.wav" length="510188" type="audio/wav" />
<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2020/03/002.wav" length="1938796" type="audio/wav" />
<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2020/03/003.wav" length="633504" type="audio/wav" />
<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2020/03/004.wav" length="981536" type="audio/wav" />
<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2020/03/005.wav" length="485636" type="audio/wav" />
<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2020/03/007.wav" length="910416" type="audio/wav" />
<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2020/03/006.wav" length="932280" type="audio/wav" />

			</item>
		<item>
		<title>Mesure Lidar rotatif embarqué sur LattePanda et piloté par LabVIEW (LINX)</title>
		<link>https://amaury-laurent.fr/mesure-lidar-rotatif-embarque-sur-lattepanda-et-pilote-par-labview-linx/</link>
					<comments>https://amaury-laurent.fr/mesure-lidar-rotatif-embarque-sur-lattepanda-et-pilote-par-labview-linx/#comments</comments>
		
		<dc:creator><![CDATA[adrienBS]]></dc:creator>
		<pubDate>Wed, 06 Mar 2019 14:36:49 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<category><![CDATA[Capteurs]]></category>
		<category><![CDATA[Informatique]]></category>
		<category><![CDATA[Tutoriaux]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[LabVIEW]]></category>
		<category><![CDATA[LattePanda]]></category>
		<category><![CDATA[Lidar]]></category>
		<category><![CDATA[LINX]]></category>
		<guid isPermaLink="false">http://amaury-laurent.fr/?p=1012</guid>

					<description><![CDATA[<p>Le sujet abordé dans cet article présente la réalisation d’une mesure de distance à l’aide d’un capteur Lidar monté sur un moteur pas à pas et commandé par LabVIEW à travers la bibliothèque LINX. Nous verrons comment rendre ce système embarqué sur un LattePanda. L’objectif est de pouvoir mesurer une distance entre 0,1 à 20 [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/mesure-lidar-rotatif-embarque-sur-lattepanda-et-pilote-par-labview-linx/">Mesure Lidar rotatif embarqué sur LattePanda et piloté par LabVIEW (LINX)</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Le sujet abordé dans cet article présente la réalisation d’une mesure de distance à l’aide d’un capteur Lidar monté sur un moteur pas à pas et commandé par LabVIEW à travers la bibliothèque LINX. Nous verrons comment rendre ce système embarqué sur un LattePanda. L’objectif est de pouvoir mesurer une distance entre 0,1 à 20 mètres sur 360° et de contrôler l’ensemble à partir d’une IHM (Interface Homme Machine) tactile.</p>
<p><em>Avant de commercer cet article, je tiens à remercier Amaury qui m&rsquo;a permis de publier cet article sur son site. 🙂</em></p>
<div style="width: 640px;" class="wp-video"><!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->
<video class="wp-video-shortcode" id="video-1012-1" width="640" height="360" preload="metadata" controls="controls"><source type="video/mp4" src="https://amaury-laurent.fr/wp-content/uploads/2019/03/20190225_222725.mp4?_=1" /><a href="https://amaury-laurent.fr/wp-content/uploads/2019/03/20190225_222725.mp4">https://amaury-laurent.fr/wp-content/uploads/2019/03/20190225_222725.mp4</a></video></div>
<p>Je découvre actuellement l’électronique et la programmation entre  LabVIEW et Arduino et je tiens à partager certains résultats avec vous. Certaines notions abordées ne seront pas forcément poussées ou assez détaillées pour des lectures ou lectrices plus expérimenté(e)s.</p>
<h1><a name="_Toc2727674"></a>Théorie de mesure de distance Lidar</h1>
<p>Lidar est l’acronyme anglais de <em>light detection and ranging </em>qui est une technique qui permet de mesurer des distances allant de quelques centimètres à la distance Terre-Lune. Le lidar Garmin utilisé ici, génère un train d’onde électromagnétique cohérente (un faisceau laser InfraRouge) de longueur d’onde λ de 905 nm. Les trains d’onde sont envoyés à une fréquence comprise entre 10 à 20 kHz (à ne pas confondre avec la fréquence propre de l’onde du laser IR) d’après les datasheet. Les trains d’ondes se réfléchissent sur la cible visée par le capteur. Une partie de la lumière du laser revient sur le capteur. Une photodiode placée dans le Lidar et sensible dans la plage de longueur d’onde des IR reçoit l’onde réfléchie. L’écart de temps entre le départ d’un train d’onde et son retour est mesuré par le capteur. Cet écart de temps est proportionnel à la distance parcourue par l’onde. Cette technologie de mesure est communément appelée <em>Time of Flight</em>.</p>
<h1><a name="_Toc2727675"></a>Le matériel utilisé pour la réalisation</h1>
<table style="height: 778px" width="621">
<tbody>
<tr style="height: 24px">
<td style="width: 224px;text-align: center;height: 24px"><strong>Matériel</strong></td>
<td style="width: 172px;text-align: center;height: 24px"><strong>Prix (neufs)</strong></td>
<td style="width: 203px;text-align: center;height: 24px"><strong>Site achat</strong></td>
</tr>
<tr style="height: 72px">
<td style="width: 224px;height: 72px;text-align: center">Carte LattePanda 4 GB/64 GB DFR0419 (sans écran et capteur tactile)</td>
<td style="width: 172px;height: 72px;text-align: center">~ 187 €</td>
<td style="width: 203px;height: 72px;text-align: center">Go Tronic</td>
</tr>
<tr style="height: 72px">
<td style="width: 224px;height: 72px;text-align: center">Ecran 7’ + capteur tactile + Ventilateur et refroidisseur métalliques</td>
<td style="width: 172px;height: 72px;text-align: center">~ 80 €</td>
<td style="width: 203px;height: 72px;text-align: center">Go Tronic</td>
</tr>
<tr style="height: 72px">
<td style="width: 224px;height: 72px;text-align: center">LabVIEW pour l&rsquo;enseignement 2014 (version d’essai gratuite 7 jours)</td>
<td style="width: 172px;height: 72px;text-align: center">A partir de 196 €</td>
<td style="width: 203px;height: 72px;text-align: center">NI</td>
</tr>
<tr style="height: 48px">
<td style="width: 224px;height: 48px;text-align: center">LIDAR GARMIN lite V3</td>
<td style="width: 172px;height: 48px;text-align: center">143 €</td>
<td style="width: 203px;height: 48px;text-align: center">Amazon (Expédié et vendu par <a href="https://www.amazon.fr/gp/help/seller/at-a-glance.html/ref=dp_merchant_link?ie=UTF8&amp;seller=A2PIW95AGLR8G3" target="_blank" rel="noopener">RobotShop inc</a>.)</td>
</tr>
<tr style="height: 120px">
<td style="width: 224px;height: 120px;text-align: center">Driver de moteur Pas à Pas Bipolaire</p>
<p>(A4988 1182)</td>
<td style="width: 172px;height: 120px;text-align: center">7€</td>
<td style="width: 203px;height: 120px;text-align: center">Go Tronic</td>
</tr>
<tr style="height: 48px">
<td style="width: 224px;height: 48px;text-align: center">Moteur pas à Pas Bipolaire (14HM11-0404S)</td>
<td style="width: 172px;height: 48px;text-align: center">18 €</td>
<td style="width: 203px;height: 48px;text-align: center">Go Tronic</td>
</tr>
<tr style="height: 24px">
<td style="width: 224px;height: 24px;text-align: center">Laser Rouge de niveau recyclé</td>
<td style="width: 172px;height: 24px;text-align: center">0 €</td>
<td style="width: 203px;height: 24px;text-align: center">Sans objet</td>
</tr>
<tr style="height: 48px">
<td style="width: 224px;height: 48px;text-align: center">2 Piles de 9 Volts + 2 connecteurs</td>
<td style="width: 172px;height: 48px;text-align: center">~ 10 €</td>
<td style="width: 203px;height: 48px;text-align: center">Amazon</td>
</tr>
<tr style="height: 48px">
<td style="width: 224px;height: 48px;text-align: center">Une breadboard (400 points minimum)</td>
<td style="width: 172px;height: 48px;text-align: center">3 €</td>
<td style="width: 203px;height: 48px;text-align: center">Amazon</td>
</tr>
<tr style="height: 24px">
<td style="width: 224px;height: 24px;text-align: center">Batterie Li 20000mAh</td>
<td style="width: 172px;height: 24px;text-align: center">30 €</td>
<td style="width: 203px;height: 24px;text-align: center">Amazon</td>
</tr>
<tr style="height: 24px">
<td style="width: 224px;height: 24px;text-align: center">1 Condensateur 100µF 16V</td>
<td style="width: 172px;height: 24px;text-align: center">Qlq centimes</td>
<td style="width: 203px;height: 24px;text-align: center">Amazon</td>
</tr>
<tr style="height: 24px">
<td style="width: 224px;height: 24px;text-align: center">2 Condensateurs 0.1µF</td>
<td style="width: 172px;height: 24px;text-align: center">Idem</td>
<td style="width: 203px;height: 24px;text-align: center">Amazon/ Go Tronic</td>
</tr>
<tr style="height: 24px">
<td style="width: 224px;height: 24px;text-align: center">1 Résistance de 1KΩ</td>
<td style="width: 172px;height: 24px;text-align: center">Idem</td>
<td style="width: 203px;height: 24px;text-align: center">Amazon/ Go Tronic</td>
</tr>
<tr style="height: 48px">
<td style="width: 224px;height: 48px;text-align: center">1 Résistance de 500Ω de 1W (ou 4 de 2KΩ mis en parallèles)</td>
<td style="width: 172px;height: 48px;text-align: center">Idem</td>
<td style="width: 203px;height: 48px;text-align: center">Amazon/ Go Tronic</td>
</tr>
<tr style="height: 24px">
<td style="width: 224px;height: 24px;text-align: center">Régulateur de tension LM7815</td>
<td style="width: 172px;height: 24px;text-align: center">1,5€</td>
<td style="width: 203px;height: 24px;text-align: center">RS Components</td>
</tr>
<tr style="height: 10px">
<td style="width: 224px;height: 10px;text-align: center">Des fils</td>
<td style="width: 172px;height: 10px;text-align: center">recyclés</td>
<td style="width: 203px;height: 10px;text-align: center"></td>
</tr>
<tr style="height: 24px">
<td style="width: 224px;height: 24px;text-align: center"><strong>Coût total</strong></td>
<td style="width: 172px;height: 24px;text-align: center"><strong>667 €</strong></td>
<td style="width: 203px;height: 24px;text-align: center"></td>
</tr>
</tbody>
</table>
<p>Nota : un clavier et une souris seront très certainement nécessaires pour naviguer sur LattePanda.</p>
<h1><a name="_Toc2727676"></a>Le Montage global</h1>
<p>Le schéma suivant a été réalisé sur le logiciel libre Fritzing. N’ayant pas trouvé de modèle de LattePanda dans la librairie Fritzing, il a donc été représenté par sa carte Arduino qu’il intègre. Un schéma du LattePanda est donné après.</p>
<p><img decoding="async" class="alignnone wp-image-1016 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/Schema-Fritzing-Stepper-et-Lidar_regulationtension.png" alt="" width="962" height="908" /></p>
<p style="text-align: center">Figure 1 Schéma Global de la mesure Lidar (à l’aide du logiciel gratuit Fritzing)</p>
<p>L’intégration des différents éléments a été faite à l’aide d’un vieux jeu mécanos.</p>
<h2><a name="_Toc2727677"></a>LattePanda</h2>
<p>Le modèle de  LattePanda utilisé est le 4 GB/64 GB sous Windows 10. Ce modèle suffit pour faire tourner un LabVIEW 2014 (<a href="https://www.gotronic.fr/art-carte-lattepanda-4-gb-64-gb-dfr0419-24792.htm" target="_blank" rel="noopener">https://www.gotronic.fr/art-carte-lattepanda-4-gb-64-gb-dfr0419-24792.htm</a> ). LattePanda sera très utile car il intègre une carte Arduino Leonardo et ses E/S associées. A l’aide des entrées et sorties numériques (0-5V), il sera possible de piloter le moteur pas à pas, le laser et d’acquérir le signal du Lidar. Le LattePanda est enfaîte un petit ordinateur d’instrumentation très compacte et assez puissant. Le projet n’utilise ici qu’une petite partie de sa capacité. Pour plus de détails sur LattePanda, le lecteur pourra se référer à l&rsquo;article : <a href="https://amaury-laurent.fr/lattapanda-premiere-mise-route/">LattePanda – Première mise en route</a></p>
<p>Le schéma ci-dessous reprend les principales E/S :</p>
<p><img decoding="async" class="alignnone size-full wp-image-1017 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/lattepanda.jpg" alt="" width="649" height="637" /></p>
<p style="text-align: center">Figure 2 E/S LattePanda 4GB/64GB (https://www.lattepanda.com)</p>
<h2><a name="_Toc2727678"></a>Le moteur Pas à Pas</h2>
<p>Le moteur Pas à Pas bipolaire est contrôlé par un Driver Pololu (A4988). Le schéma ci-après (d’après le site Pololu qui commercialise le Driver) permet de connecter le moteur et le Driver. La puce du Driver est alimentée en 5 V par la carte Arduino du LattePanda. Ce driver a été choisi car il est facilement pilotable à partir des E/S digitales du Arduino, qui seront contrôlées par le logiciel ; lequel qui sera abordé après.</p>
<p><img decoding="async" class="alignnone size-full wp-image-1018 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/SchémaDriver.png" alt="" width="605" height="377" /></p>
<p style="text-align: center">Figure 3 Schéma de fonctionnement du Drive couplé au moteur Pas à Pas (bipolaire)</p>
<p>Pour connecter correctement le moteur pas à pas au driver on pourra suivre le tableau suivant :</p>
<table>
<tbody>
<tr>
<td width="136"><strong>Fils côté moteur</strong></td>
<td width="140"><strong>Pin entrée Driver</strong></td>
</tr>
<tr>
<td width="136">A (noir)</td>
<td width="140">1A</td>
</tr>
<tr>
<td width="136">C (vert)</td>
<td width="140">1B</td>
</tr>
<tr>
<td width="136">B (rouge)</td>
<td width="140">2A</td>
</tr>
<tr>
<td width="136">D (bleu)</td>
<td width="140">2B</td>
</tr>
</tbody>
</table>
<p><img decoding="async" class="alignnone size-full wp-image-1019 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/Schema-Moteur.png" alt="" width="209" height="212" /></p>
<p style="text-align: center">Figure 4 Schéma du moteur Pas à Pas (14HM11-0404S) d&rsquo;après datasheet Go Tronic</p>
<p>Il est conseillé de relier la masse de l’alimentation du moteur à la masse du circuit afin d’éviter de le moteur ne grésille. Un petit régulateur LM7815 (15 V) permet de limiter la tension en entrée. Pour ma part j’ai utilisé deux piles de 9 V. En sortie du régulateur il vaut mieux ne pas oublier de limiter le courant à l’aide d’une résistance de charge. Le moteur consomme 400 mA par phase. Pour limiter le courant j’ai choisi de mettre en parallèle 4 résistances de 2 kΩ de 1/4 W qui forment une résistance 500 Ω supportant 1 W. Avec ce montage, le moteur ne chauffe et a assez de puissance pour réaliser ses pas. Un potentiomètre présent sur le driver permet de réguler la tension. Le réglage du courant limite est disponible dans la vidéo disponible en suivant de <a href="https://www.youtube.com/watch?v=89BHS9hfSUk" target="_blank" rel="noopener">lien</a> (https://www.youtube.com/watch?v=89BHS9hfSUk). Pololu préconise de régler le courant limite à l’aide du réglage du VREF et non en entrée comme cela a été fait ici.</p>
<ul>
<li>Une fois le montage du moteur réalisé, un test du moteur peut être réalise. Pour cela, la Pin STEP du driver peut être connecté au 5V délivré par l’Arduino. Le moteur est censé faire un pas. Sinon, revérifier le schéma de montage.</li>
</ul>
<p>Les entrées MS1, MS2 et MS3 permettent de réduire le Pas, c’est-à-dire de gagner en précision angulaire. Le tableau ci-dessous affiche les niveaux à utiliser sur les pins en fonctions de la résolution du pas.</p>
<p><img decoding="async" class="alignnone size-full wp-image-1021 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/Tableau-resolution-pas.png" alt="" width="369" height="193" /></p>
<p style="text-align: center">Figure 5 Tableau de résolution des pas d&rsquo;après le site Pololu</p>
<p>Dans le cas présent, un pas complet est de 0,9°, un demi-pas en vaudra la moitié et ainsi de suite. Dans le présent projet, il n’est pas possible de descendre en dessous du demi-pas.</p>
<p><strong>Nota important:</strong> il est fortement<strong> déconseillé de déconnecter le moteur du driver quand le moteur est en fonctionnement</strong> car le Driver peut-être endommagé. Il faudra couper l’alimentation du moteur pour effectuer des changements de postions (si besoin) sur les 4 fils du moteur pas à pas.</p>
<h2><a name="_Toc2727679"></a>Le Lidar</h2>
<p>Pour fonctionner le Lidar doit être alimenté en 5 V. L’alimentation 5 V de l’Arduino du LattePanda convient parfaitement. L’acquisition de la mesure de distance est lue en largeur d’impulsion (PWM) sur le fil jaune. Les datasheet préconisent l’utilisation d’une résistance de 1KΩ qui est reliée entre le fil de sortie de la mesure et la masse comme ci-dessous :</p>
<p><img decoding="async" class="size-full wp-image-1020 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/schema-cablage-lidar.png" alt="" width="604" height="457" /></p>
<p style="text-align: center">Figure 6 Schéma de câblage du lidar en acquisition de mesure en PWM (d&rsquo;après datasheet Gramin)</p>
<p>Concernant les aspects métrologiques du capteur, la portée maximale du Lidar est de 40 mètres. Sa résolution est de 1 cm.</p>
<p>L&rsquo;incertitude de mesure du Lidar Lite V3,  entre 0 et 5m est de ± 2.5cm et ± 10 cm au delà.</p>
<p>En sortie de mesure en largeur d&rsquo;impulsion, la sensibilité est de 10 µs/cm. Cette valeur est à retenir pour comprendre la partie acquisition du signal du logiciel.</p>
<h2><a name="_Toc2727680"></a>Le Laser de visée</h2>
<p>Le laser est utile ici afin d&rsquo;avoir un repère visuel sur l&rsquo;orientation du Lidar. Le laser est du même type qu’utilisé pour les pointeurs laser de présentation (diode laser). Dans le cas présent, un laser d’alignement de 1 mW (λ = 650 nm) de couleur rouge a été utilisé. Il est alimenté en 5V par une entrée digitale de carte Arduino activable à partir du logiciel.</p>
<p><strong><span style="color: #ff0000">Attention aux yeux !</span></strong> Le laser concentre l&rsquo;énergie sur une surface très petite et a pour conséquence d&rsquo;être nocif pour l’œil.</p>
<p>L&rsquo;utilisateur est responsable de sa sécurité mais également celle des personnes autour !</p>
<h1><a name="_Toc2727681"></a>Le logiciel/programme</h1>
<p>Pour piloter les instruments (Lidar, moteur, laser) le logiciel LabVIEW 2014 est utilisé. Le but n’est pas de faire la présentation ni la promotion de ce logiciel mais de tenter d’expliquer comment utiliser certaines briques LINX. Si LabVIEW n’est pas utilisé, il sera quand même possible de piloter les instruments via un programme développé sur l’IDE Arduino. La suite de l’article pourra paraître obscure pour les personnes non initiées à LabVIEW; je m’en excuse par avance. Cependant, un petit effort a été fait pour que le code soit compris des personnes non initiées à LabVIEW.</p>
<p>Des briques (ou VI) de code LabVIEW ont été développées afin de faciliter grandement la compatibilité entre des cartes Arduino et LabVIEW. Pour utiliser les briques de codes LINX, la bibliothèque LINX côté LabVIEW doit avoir été installée préalablement dans VI Pack Manager (logiciel qui permet de charger des ToolKit ou librairies de programme).</p>
<h2><a name="_Toc2727682"></a>Chargement des librairies</h2>
<p>Avant de compiler le code, il faut charger les bibliothèques. Pour charger les bibliothèques, aller sur l’onglet <em>Tool\MakerHub\LINX\Generate Firmware Librairies :</em></p>
<p><img decoding="async" class="size-full wp-image-1022 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/screen-chargement-librairies.png" alt="" width="612" height="399" /></p>
<p>Et mettre en cible : <strong>C:\Program Files\Arduino\Libraries</strong></p>
<p><img decoding="async" class="wp-image-1023 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/screen-chargement-librairies_2.png" alt="" width="579" height="486" /></p>
<p>Les librairies sont donc maintenant chargées et opérationnelles.</p>
<h2><a name="_Toc2727683"></a>Configuration du type de carte</h2>
<p>Avant de compiler le code, il faudra configurer le type de carte (Mega, Leonardo) et le type de liaison. Dans ce projet avec LattePanda, la carte Arduino Leonardo est utilisée sur le port COM 4. Dans LabVIEW cliquez dans l&rsquo;onglet <em>Tool </em>puis <em>\MakerHub\LINX\LINX Firmware Wizard… </em>il faut configurer les champs à l’aide des informations mentionnées plus haut.</p>
<h2><a name="_Toc2727683"></a>TEST simple avec une LED</h2>
<p>Pour vérifier que la carte fonctionne correctement, l’exemple du pilotage d’une LED pourra être réalisé (onglet <em>HELP/Find Example…</em>). L&rsquo;exemple est prêt à être utilisé et ne nécessite que la mise en place d&rsquo;une LED en série avec une résistance de 220 Ω reliées au LattePanda.</p>
<p><img decoding="async" class="size-full wp-image-1024 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/screen-test-example-LED-LINX.png" alt="" width="605" height="421" /><img decoding="async" class="size-full wp-image-1025 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/Screen-Exemple-LED-LINX.png" alt="" width="766" height="616" /></p>
<p>Mettre le port COM 4 (normalement) et configurer la pin du Arduino sur laquelle est reliée l&rsquo;anode de la LED (la patte la plus longue) et ne pas oublier la résistance de 220 Ω en série 😉 . Puis relier la résistance à la masse et lancer le programme (flèche blanche).</p>
<p>Si la LED clignote quand le bouton est pressé, c’est gagné. Passer aux étapes suivantes. Sinon, il faut trouver la raison de cette malchance.</p>
<p>Ne pas hésiter à reconfigurer la carte car il arrive (trop) souvent que cela saute au bout de 3 à 4 compilations. Par exemple, il vaut mieux arrêter proprement la boucle avec un bouton « stop » placé dans la boucle While plutôt que de stopper le programme avec le bouton rouge de LabVIEW.</p>
<h1>L&rsquo;IHM (côté « Face Avant » de LabVIEW)</h1>
<p>L&rsquo;IHM qui permet à l&rsquo;utilisateur de contrôler les instruments pourra ressembler fortement à celle présentée ci-dessous.</p>
<p>Les configurations des Pins et du port sont situées à gauche.</p>
<p>Le bouton « Motor ON » permet d&rsquo;activer le driver sur la Pin ENABLE (Driver).</p>
<p>Le bouton « Left » permet d&rsquo;activer la Pin STEP (Driver)  et faire faire un pas au moteur.</p>
<p>Le bouton « Right »agit comme le bouton « Left » mais active la pin DIR (Driver) à l&rsquo;état haut et permet de changer de sens de rotation.</p>
<p>Un bouton « Laser » permet d&rsquo;activer le laser de visée.</p>
<p>Un bouton STOP permet d&rsquo;arrêter l’exécution proprement et d&rsquo;arrêter le moteur (ENABLE) et le Laser.</p>
<p>Trois types d’indicateurs sont présents : numérique (format chaîne de caractère), une barre de remplissage, et un graphe déroulant.</p>
<p>Un contrôleur barre graphe permet de passer au pilotage Pas par Pas (un clique sur LEFT ou RGTH = 0,9°) ou active la vitesse constante (comme sur la vidéo du début de l&rsquo;article).</p>
<p><img decoding="async" class=" wp-image-1036 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/IHM.png" alt="" width="700" height="376" /></p>
<p>Pour le lecteur non initié à LabVIEW, la « face avant » est la partie visible finale du programme disponible pour l&rsquo;utilisateur.</p>
<p>Le code est développé dans une seconde fenêtre appelée « Diagramme ». Et c&rsquo;est la partie de développement du Diagramme que nous allons maintenant aborder.</p>
<p><em>Nota : un Crtl+E permet de permuter rapidement rentre la face avant et le diagramme.</em></p>
<h2><a name="_Toc2727684"></a>La structure (côté diagramme)</h2>
<p>La structure générale du programme est la suivante :</p>
<p><img decoding="async" class="size-full wp-image-1026 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/screen-LINX-boucle-while.png" alt="" width="605" height="230" /></p>
<p style="text-align: center">Figure 7 Structure générale du programme dans un boucle While</p>
<p>Le code source ne sera pas disponible dans cet article mais les principales briques seront détaillées pour arriver facilement au résultat. 🙂</p>
<h2><a name="_Toc2727685"></a>Lecture de la valeur de la distance du Lidar</h2>
<p>Le Lidar Garmin Lite V3 admet deux sorties de données pour la lecture des mesures : I2C ou PWM. La lecture en modulation de largeur d’impulsion est apparue comme le plus simple du point de vue du soft. Un VI LINX permet de réaliser cette mesure rapidement contre plusieurs VI pour la communication en I2C.</p>
<p>Dans la boucle While cadencée à 50 ms, la mesure du Lidar est effectuée à l’aide du VI « <strong>Lecture de la largueur d’impulsion</strong> » :</p>
<p><img decoding="async" class="size-full wp-image-1027 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LINX-lecture-largeur-impulsion.png" alt="" width="385" height="150" /></p>
<p>L’entrée <strong>DO Channel</strong> est connectée et la valeur de la Pin 0 de la carte Arduino est rentrée (cf Figure 8 ci-dessous).</p>
<p>Un tableau général de configuration des Pins d’E/S pourra être créé en amont de la boucle While comme ceci :</p>
<p><img decoding="async" class="size-full wp-image-1028" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LINX-tableau-E_S-ecrire.png" alt="" width="733" height="645" /></p>
<p>La valeur en sortie du VI n’est pas en cm mais en largeur d’une impulsion (µs), qui est proportionnelle à la distance mesurée en cm par le lidar. Afin de lire et d’afficher une valeur en cm, il faut diviser les valeurs en sortie du VI par une constante valant 10 pour obtenir une mesure de longueur (en cm). Cette constante est la sensibilité (en µs/cm) du capteur abordé précédemment que l&rsquo;on peut retrouver dans la documentation du Lidar Lite V3 (page 4, §Mode Pin Control).</p>
<p>Une moyenne glissante pourra être développée afin d’obtenir une mesure plus stable et plus juste à l’aide des registres à décalage (flèches oranges sur les bords de la boucle While). L’inconvénient de cette technique est qu’il faudra attendre n fois le nombre de points moyennés, pour obtenir le résultat. Si l’on choisit de moyenner sur 10 points et que le temps du cadencement est de 500 ms, alors le résultat sera juste au bout de 5 secondes. Ne pas oublier d’initialiser les registres à décalage à zéro. Différents types d’indicateurs pourront être placés en face avant comme ci-dessous :</p>
<p><img decoding="async" class="alignnone size-full wp-image-1029 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LINX-moyenne-glissante.png" alt="" width="1069" height="627" /></p>
<p style="text-align: center">Figure 9 Moyenne glissante (côté diagramme/code) et exemples d&rsquo;indicateurs en face avant</p>
<p>Comme le Lidar affiche une incertitude de ± 2.5 cm et une résolution de 1 cm, il a été choisi de n’afficher que des valeurs entières arrondies au centimètre.</p>
<h2><a name="_Toc2727686"></a>VI de contrôle du Driver et du moteur</h2>
<p>Un VI « écrire sur des E/S digitales » permet d’activer les sorties de l’Arduino du LattePanda afin de piloter le Driver.</p>
<p>La fonction suivante a été construite comme ci-après :</p>
<p><img decoding="async" class="size-full wp-image-1030 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LINX-ecrire-E-S-digitales.png" alt="" width="186" height="156" /></p>
<p>Cette fonctionnalité permet de prendre, en entrée, un tableau de booléens (ordres des boutons pressés en face avant) et d’activer les E/S correspondantes.</p>
<ul>
<li><strong>La première entrée</strong> (en partant du haut) de la fonction « <strong>Construire un tableau</strong>» est reliée au bouton « MOTOR ON » et agit sur la Pin « ENABLE » du Driver. Ce bouton permet vraisemblablement d’activer l’alimentation du driver et du moteur.</li>
<li><strong>La seconde entrée </strong>permet de gérer la direction du moteur. Le fil (vert) est relié au bouton « RIGHT » de mon interface afin d’active la Pin « DIR » du driver. Le moteur tourne ainsi dans le sens horaire.</li>
<li><strong>La troisième entrée</strong> active la pin « STEP » du driver et permet d’effectuer un Pas de 0,9° (avec les entrées du driver MS1=MS2=MS3=0=GND). Le moteur effectue un pas par changement de niveau de l’état bas à l’état haut. Cette entrée est active si le bouton « LEFT » OU le bouton « RIGHT » est activé. Nous verrons ensuite comment faire tourner le moteur à vitesse constante.</li>
<li><strong>La quatrième entrée</strong> active le laser. Un laser de visée peut fonctionner qu’avec une tension de 5V et ne consomme que quelques milliampères. Il est souhaitable pour la sécurité des personnes, que le bouton « STOP » qui arrête le programme, puisse stopper l’émission du laser à la fin de la manip en même temps. Pour cela on pourra mettre une boucle conditions comme ci-dessous :</li>
</ul>
<p><img decoding="async" class="size-full wp-image-1031 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LINX-Secu-Laser.png" alt="" width="746" height="166" /></p>
<p>Il pourra être fait de même avec l’arrêt du moteur (« MOTOR ON ») à la fin de l’exécution du programme.</p>
<ul>
<li><strong>Les cinquième, sixième et septième</strong> entrées activent les Pins MS1, MS2 et MS3 du driver et permettent de gagner en précision d’angle (jusqu’au demi pas ici).</li>
</ul>
<p>Afin de faire fonctionner le moteur à vitesse constante, la fonctionnalité suivante a été développée :</p>
<p><img decoding="async" class="size-full wp-image-1032 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LINX-ecrire-signal-carre.png" alt="" width="294" height="155" /></p>
<p>Lorsqu’un booléen (bouton) active la structure « Cas », le VI « écrire un signal carré » est activé avec une fréquence nulle et d&rsquo;une durée nulle sur la pin STEP. Cette fonctionnalité m&rsquo;a permis de faire fonctionner le moteur à vitesse constante. Dans ce cas, la vitesse est fonction du temps de cadencement de la boucle (réglée à 50 ms). A l’heure où est écrit cet article, il existe surement de meilleures solutions, notamment avec le VI « PWM Set Duty Cycle »:</p>
<p><img decoding="async" class="size-full wp-image-1033 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LINX-PWM.png" alt="" width="126" height="74" /></p>
<p>Mais cela n’a pas fonctionné comme il était souhaité lors du test.</p>
<p>A la suite de ces nombreux réglages et bidouillages, le programme doit pouvoir se lancer (flèche blanche non brisée). Si cela n&rsquo;est pas le cas, résoudre les erreurs unes à unes.</p>
<p>Il fortement probable que rien ne fonctionne du premier coup, ou qu’à moitié, il est alors conseillé, dans un premier temps, de vérifier les branchements (alimentation) des organes dysfonctionnant.</p>
<p>L&rsquo;utilisateur pourra jouer avec les différents types d&rsquo;actions mécaniques pour contrôler le moteur (clique droit sur un bouton) :</p>
<p><img decoding="async" class=" wp-image-1040 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/LabVIEW_acrion-boutons.png" alt="" width="326" height="354" /></p>
<p>&nbsp;</p>
<h1><a name="_Toc2727687"></a>Résultats en images :</h1>
<p><img decoding="async" class="size-full wp-image-1015 aligncenter" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2019/03/20190225_222601.jpg" alt="" width="4608" height="3456" /></p>
<p>Figure 10 Interface de la mesure de distance (Windows n&rsquo;est pas à l&rsquo;heure ^_^ )</p>
<p>J’espère que ce projet a pu continuer d’éveiller votre curiosité et a pu vous aider dans vos futurs développements !</p>
<h1><a name="_Toc2727688"></a>Sources :</h1>
<ul>
<li>Site Pololu (<a href="https://www.pololu.com/product/1182" target="_blank" rel="noopener">https://www.pololu.com/product/1182</a> )</li>
<li>Site GO Tronic</li>
<li><a href="https://www.lattepanda.com" target="_blank" rel="noopener">https://www.lattepanda.com</a></li>
<li>Ressources LINX : <a href="http://sine.ni.com/nips/cds/view/p/lang/fr/nid/212478" target="_blank" rel="noopener">http://sine.ni.com/nips/cds/view/p/lang/fr/nid/212478</a></li>
<li>Forum LINX : <a href="https://www.labviewmakerhub.com/doku.php?id=libraries:linx:start" target="_blank" rel="noopener">https://www.labviewmakerhub.com/doku.php?id=libraries:linx:start</a></li>
<li>Datasheet Lidar Garmin lite V3 : <a href="https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf" target="_blank" rel="noopener">https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf</a></li>
<li><em>LabVIEW &#8211; 4e édition &#8211; Programmation et applications &#8211; Introduction à LabVIEW NXG, </em>Collection : Technique et ingénierie, Dunod, Parution : août 2018,Francis Cottet, Luc Desruelle, Michel Pinard</li>
</ul>
<ul>
<li><em>The Art of electronic</em>, Third edition, Paul Horowitz et Winfield Hill</li>
</ul>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/mesure-lidar-rotatif-embarque-sur-lattepanda-et-pilote-par-labview-linx/">Mesure Lidar rotatif embarqué sur LattePanda et piloté par LabVIEW (LINX)</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/mesure-lidar-rotatif-embarque-sur-lattepanda-et-pilote-par-labview-linx/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		<enclosure url="https://amaury-laurent.fr/wp-content/uploads/2019/03/20190225_222725.mp4" length="98513038" type="video/mp4" />

			</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>Interface Ethernet PIC18F</title>
		<link>https://amaury-laurent.fr/interface-ethernet-pic18f/</link>
					<comments>https://amaury-laurent.fr/interface-ethernet-pic18f/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Tue, 09 Feb 2016 21:08:53 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<guid isPermaLink="false">http://vps200917.ovh.net/?p=440</guid>

					<description><![CDATA[<p>Connectez vos applications embarquées à Internet Acquisitions sur le terrain, télégestion, domotique&#8230; De nombreuses applications s’accommodent très bien d&#8217;une connexion à l&#8217;Internet. Qu&#8217;il s&#8217;agisse d&#8217;envoyer des mesures dans une base de données ou de piloter un système à distance: les idées ne manquent pas. Je vous propose aujourd&#8217;hui une petite carte comprenant un microcontrôleur et [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/interface-ethernet-pic18f/">Interface Ethernet PIC18F</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Connectez vos applications embarquées à Internet</h1>
<p>Acquisitions sur le terrain, télégestion, domotique&#8230; De nombreuses applications s’accommodent très bien d&rsquo;une connexion à l&rsquo;Internet. Qu&rsquo;il s&rsquo;agisse d&rsquo;envoyer des mesures dans une base de données ou de piloter un système à distance: les idées ne manquent pas.</p>
<p>Je vous propose aujourd&rsquo;hui une petite carte comprenant un microcontrôleur et l&rsquo;interface réseau qui va lui permettre de dialoguer avec un modem.</p>
<p>Ce projet est rendu possible par Microchip qui propose un contrôleur réseau en boitier DIP28 simplement commandé par un bus SPI. Ce fameux composant se nomme <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en022889" target="_blank" rel="noopener noreferrer">ENC28J60</a>. Il ne requiert que très peu de composants annexes: quelques condensateurs et résistances, un quartz à 25.000 MHz et, bien évidemment, une prise RJ45 et son transformateur de couplage.</p>
<h2>Le schéma</h2>
<p>Assez palabré, jetons un coup d’œil au schéma.</p>
<div><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/schema.png" target="_blank" rel="noopener"><img decoding="async" class="aligncenter wp-image-441 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/schema-300x116.png" alt="schema" width="300" height="116" /></a></div>
<h2>L&rsquo;alimentation</h2>
<div>
<figure id="attachment_450" aria-describedby="caption-attachment-450" style="width: 300px" class="wp-caption aligncenter"><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/DSCF3539.jpg" target="_blank" rel="noopener"><img decoding="async" class="wp-image-450 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/DSCF3539-300x169.jpg" alt="L’alimentation à découpage" width="300" height="169" /></a><figcaption id="caption-attachment-450" class="wp-caption-text">L’alimentation à découpage</figcaption></figure>
</div>
<p>J&rsquo;ai choisi d&rsquo;utiliser un PIC 18F qui fonctionne sous 5V, mais l&rsquo;ENC fonctionne lui en 3.3V. Il y a donc deux régulateurs de tension: le premier fournit le 5V au micro et le second fournit le 3.3V à l&rsquo;ENC. J&rsquo;ai d&rsquo;abord monté ces deux régulateurs en parallèle alimentés par le 12Vdc, mais pour limiter l&rsquo;échauffement du LM317, je l&rsquo;ai ensuite monté en cascade derrière le régulateur 5V (passant du même coup d&rsquo;un classique 7805 à un PT78ST105 à découpage).</p>
<p>Il serait peut-être plus avantageux d&rsquo;utiliser un PIC18LF alimenté directement en 3.3V. Mais vu la consommation de l&rsquo;ENC (250 mA), il ne semble pas utilise de gratter quelques mA sur le PIC.</p>
<h2>L&rsquo;ENC28J60</h2>
<figure id="attachment_449" aria-describedby="caption-attachment-449" style="width: 300px" class="wp-caption aligncenter"><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/DSCF3538.jpg" target="_blank" rel="noopener"><img decoding="async" class="wp-image-449 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/DSCF3538-300x169.jpg" alt="L'ENC28J60 et son horloge" width="300" height="169" /></a><figcaption id="caption-attachment-449" class="wp-caption-text">L&rsquo;ENC28J60 et son horloge</figcaption></figure>
<p>L&rsquo;ENC28J60 est un microcontrôleur, certes un peu particulier, mais qui a les mêmes besoins: une horloge, une alimentation découplée et un Reset.</p>
<p>Le quartz imposé par Microchip doit résonner à 25 MHz. C&rsquo;est une fréquence courante pour les contrôleurs réseau: on peut donc récupérer de tels quartz dans de vieux routeurs, par exemple. Autrement, ils sont disponibles en neuf chez Conrad.</p>
<p>La connexion à la prise réseau doit obligatoirement passer par un transformateur de couplage. Là encore, il est possible d&rsquo;en récupérer dans de vieux routeurs. Il existe aussi des prises réseaux intégrant le transformateur appelées « magjack ». C&rsquo;est une prise de ce type que j&rsquo;ai utilisé (récupérée dans une vielle Livebox Sagem).</p>
<p>La connexion avec le PIC passe par un bus SPI. Ce dernier transporte les informations sur deux fils (SDI et SDO) accompagnées d&rsquo;un signal d&rsquo;horloge (SCK). Il suffit donc de relier la broche SDO du PIC à la broche SI de l&rsquo;ENC, SDI sur SO et SCK sur SCK. Il faut aussi compléter ce bus des deux lignes /RESET et /CS (chip select), qui permettent d&rsquo;initialiser le composant et de le choisir (si le bus SPI est relié à d&rsquo;autres périphériques).</p>
<p>Enfin, Une self permet d&rsquo;isoler l&rsquo;alimentation de la carte avec la liaison Ethernet (très bruitée).</p>
<p><em>ATTENTION:</em> comme je l&rsquo;ai déjà signalé, l&rsquo;ENC fonctionne en 3.3V et le PIC en 5V. Dans le cas d&rsquo;un PIC, les entrées du bus SPI sont dites à « trigger de Schmitt ». En gros, cela signifie qu&rsquo;elles sont compatibles avec les signaux 3.3V. Pour d&rsquo;autres microcontrôleurs, il peut être nécessaire d&rsquo;ajouter un circuit d&rsquo;adaptation de niveau sur les lignes SDI et /INT. Par contre les entrées de l&rsquo;ENC sont compatibles TTL 5V. Il n&rsquo;est donc pas nécessaire d&rsquo;abaisser le niveau 5V à 3.3V avant d&rsquo;entrer dans l&rsquo;ENC.</p>
<h2>Le Microcontrôleur</h2>
<div class="image">
<figure id="attachment_451" aria-describedby="caption-attachment-451" style="width: 300px" class="wp-caption aligncenter"><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/DSCF3540.jpg" target="_blank" rel="noopener"><img decoding="async" class="wp-image-451 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/DSCF3540-300x169.jpg" alt="Le PIC18 et son horloge" width="300" height="169" /></a><figcaption id="caption-attachment-451" class="wp-caption-text">Le PIC18 et son horloge</figcaption></figure>
</div>
<p>Je suis d&rsquo;abord parti sur un <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010300" target="_blank" rel="noopener noreferrer">PIC18F4550</a>, bien connu, qui offre la possibilité d&rsquo;utiliser le bootloader USB de <a class="menu_link" href="http://vps200917.ovh.net/index.php/2015/10/03/interface-usb-hid/" target="_blank" rel="noopener">l&rsquo;Interface HID Universelle</a>. Malheureusement, bien que milieu de gamme, ce contrôleur n&rsquo;offre presque pas suffisamment de ressources pour utiliser une stack TCP/IP ou UDP/IP. J&rsquo;ai donc migré vers un <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en550197" target="_blank" rel="noopener noreferrer">PIC18F46K80</a>. Avec ses deux UART et son bus CAN, ce microcontrôleur est parfaitement adapté à la communication sur réseaux de terrain (je le réservais d&rsquo;ailleurs à la réalisation d&rsquo;un espion RS232 &#8230;). Il offre cependant 64 ko de flash et 3.6 ko de RAM (contre 32ko de flash et 2ko de RAM pour le 4550) et des convertisseurs A/N 12 bits (contre 10 bits pour le 4550).</p>
<p>Le PIC18F46K80 permet de programmer un mini serveur web ou d&rsquo;implanter une petite stack TCP/IP pour envoyer des infos sur une base de données (par exemple).<br />
<em>ATTENTION:</em> le 46K80 n&rsquo;est pas entièrement compatible avec le 4550: les broches d&rsquo;alimentations sont identiques, mais le bus SPI n&rsquo;est pas à la même place. En outre, comme le module USB disparaît, la configuration de l&rsquo;horloge diffère et il faut ajouter un connecteur ICSP (pas de bootloader pour le 46K80, sauf peut-être un en Ethernet &#8230;).</p>
<h2>Overclocking</h2>
<p>Pour les néophytes, l&rsquo;overclocking est l&rsquo;art de faire fonctionner un système informatique plus rapidement que ce que préconise le fabricant. Fort populaire <a href="=&quot;http://www.overclocking-pc.fr/&quot;" target="_blank" rel="noopener noreferrer">sur PC</a>, l&rsquo;overclocking peut aussi s&rsquo;appliquer à nos chers microcontrôleurs.</p>
<p>Dans le cas du 18F46K80, il s&rsquo;agit surtout de conserver le quartz de 20MHz que j&rsquo;avais mis pour le 4550. Le 46K80 offre une configuration d&rsquo;horloge complètement différente du 4550. Il est notamment possible de configurer l&rsquo;utilisation d&rsquo;une horloge secondaire plus lente pour le mode basse consommation. Par contre, il ne propose qu&rsquo;une seule PLL d&rsquo;un coefficient de 4. On a donc le choix entre une horloge à 20MHZ ou une horloge à 80MHz. Je vous laisse imaginer quelle configuration j&rsquo;utilise ;). Par contre, cette fréquence dépasse de 25% les spécifications constructeur, donc si votre micro a un comportement anormal, désactivez la PLL et contentez-vous d&rsquo;une horloge à 20MHz.</p>
<p>NB: Il est bien connu qu&rsquo;un microprocesseur de PC chauffe plus quand on l&rsquo;overclocke. Un PIC n&rsquo;est pas différent: si le 46K80 est froid à 20MHz, il tiédit légèrement à 80MHz (mais rien de comparable avec l&rsquo;ENC28J60, qui lui tiédit franchement).</p>
<h2>Utilisation</h2>
<p>Une fois n&rsquo;est pas coutume, j&rsquo;utilise l&rsquo;environnement MikroC pour programmer cette carte. En effet, MikroC offre une bibliothèque dédiée à l&rsquo;utilisation de l&rsquo;ENC28J60. Je vous invite à essayer leurs exemples, notamment leur serveur web.</p>
<p>Une version modifiée et améliorée de leur stack TCP/IP est disponible sur leur dépôt <a href="http://www.libstock.com/projects/view/107/network-ethernet-library" target="_blank" rel="noopener noreferrer">Libstock</a>.</p>
<p>Voici un exemple de code :</p>
<div class="source">
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "__NetEthEnc28j60.h"
#include "recources.h"
 
#define TMR0_PRE                    34286    //une IT toutes les 200ms à 80MHz
 
// mE ehternet NIC pinout
sfr sbit Net_Ethernet_28j60_Rst at LATD3_bit;  // for writing to output pin always use latch
sfr sbit Net_Ethernet_28j60_CS  at LATD2_bit;  // for writing to output pin always use latch
sfr sbit Net_Ethernet_28j60_Rst_Direction at TRISD3_bit;
sfr sbit Net_Ethernet_28j60_CS_Direction  at TRISD2_bit;
// end ethernet NIC definitions
 
const code unsigned char httpHeader[] = "HTTP/1.1 200 OK\nConnection: close";  // HTTP header
const code unsigned char httpMimeTypeHTML[] = "\nContent-type: text/html\n\n";              // HTML MIME type
const code unsigned char httpImage[] = "HTTP/1.1 200 OK\nConnection: keep-alive\nContent-type: image/jpg\n\n";           // TEXT MIME type
unsigned char httpMethod[] = "GET /";
unsigned char httpRequ[] = "GET / HTTP/1.1";
 
 
unsigned char   myMacAddr[6] = "ENC28";   // my MAC address
unsigned char   myIpAddr[4]  = {0, 0, 0, 0};                   // my IP address: 0.0.0.0 =&gt; utilise le DHCP pour obtenir une IP
unsigned char   gwIpAddr[4]  = {192, 168,   1, 254};           // gateway (router) IP address
unsigned char   ipMask[4]    = {255, 255, 255,  0 };           // network mask (for example : 255.255.255.0)
unsigned char   dnsIpAddr[4] = {192, 168,   1, 254};           // DNS server IP address
 
unsigned char   getRequest[15];                                // HTTP request buffer
unsigned char   dyna[31] ;                                     // buffer for dynamic response
char led0status = 0;
 
int nb200ms = 0;
 
////////////////////////////////////////////////////////////////////////////////
// // User must set values of global variables in _Lib_NetEthEnc24j600_Defs.c file: !!!!!
/*
NUM_OF_SOCKET_28j60 = 7;     // Max number of socket We can open.
TCP_TX_SIZE_28j60 = 256;    // Size of Tx buffer in RAM.
MY_MSS_28j60 = 30;          // Our maximum segment size.
SYN_FIN_WAIT_28j60 = 1;      // Wait-time (in second) on remote SYN/FIN segment.
RETRANSMIT_WAIT_28j60 = 1;   // Wait-time (in second) on ACK which we expect.
*/
////////////////////////////////////////////////////////////////////////////////
 
char sendHTML_mark = 0;
SOCKET_28j60_Dsc *socketHTML;
unsigned int pos[10];
// Initialization of Timer1
unsigned int cnt;
 
void Net_Ethernet_28j60_UserTCP(SOCKET_28j60_Dsc *socket) {
  unsigned int    len;
  char content_length[32];
  asm CLRWDT;
  
  // I listen only to web request on port 80 for web server
 
  if(socket-&gt;destPort != 80) return ;
  // get 10 first bytes only of the request, the rest does not matter here
  for(len = 0; len &lt; 10; len++){
    getRequest[len] = Net_Ethernet_28j60_getByte();
    }
  getRequest[len] = 0;
 
  // only GET method is supported here
  if(memcmp(getRequest, httpMethod, 5)&amp;&amp;(socket-&gt;state != 3)){
    return;
    }
 
  if(memcmp(getRequest, httpRequ, 9)==0){
    sendHTML_mark = 1;
    socketHTML = socket;
  }
 
 
  //............................................................................
  // Send html page.
  if((sendHTML_mark == 1)&amp;&amp;(socketHTML == socket)) {
    if(pos[socket-&gt;ID]==0) {
      LATD.F1 = 1;
      // Send HTTP header.
      sprintf(content_length, "Content-Length: %d", strlen(html_code));
      Net_Ethernet_28j60_putConstStringTCP(httpHeader, socket);
      Net_Ethernet_28j60_putStringTCP(content_length, socket);
      Net_Ethernet_28j60_putConstStringTCP(httpMimeTypeHTML, socket);
      Net_Ethernet_28j60_putConstStringTCP("&lt;script&gt;\n", socket);
      sprintf(dyna, "var kimoTemp=%2.1f\n",getTempKimo(KIMO_TEMP));
      Net_Ethernet_28j60_putStringTCP(dyna, socket);
      sprintf(dyna, "var kimoHygro=%2.1f\n",getHygroKimo(KIMO_HYGRO));
      Net_Ethernet_28j60_putStringTCP(dyna, socket);
      Net_Ethernet_28j60_putConstStringTCP("&lt;/script&gt;\n", socket);
    }
    while(pos[socket-&gt;ID] &lt; strlen(html_code)) {
      asm CLRWDT;
      if(Net_Ethernet_28j60_putByteTCP(html_code[pos[socket-&gt;ID]++], socket) == 0) {
        pos[socket-&gt;ID]--;
        break;
      }
    }
    if( Net_Ethernet_28j60_bufferEmptyTCP(socket) &amp;&amp; (pos[socket-&gt;ID] &gt;= strlen(html_code)) ) {
      Net_Ethernet_28j60_disconnectTCP(socket);
      LATD.F1 = 0;
      sendHTML_mark = 0;
      sendDATA_mark = 0;
      pos[socket-&gt;ID] = 0;
    }
  }
}
 
////////////////////////////////////////////////////////////////////////////////
 
int ReadSampleADC (char channel)
{
      /* Fonction de lecture des voies Analogiques */
      /* Les fonctions de MikroC ne semble pas s'accomoder des entrées différentielles */
      ADCON0 = channel * 4;
      ADCON0.f0 = 1;
      ADCON0.f1 = 1;
      while(ADCON0.f1 == 1);
      ADCON0.f0 = 0;
      
      return (ADRESH*256 + ADRESL)%4096;
}
 
unsigned int    Net_Ethernet_28j60_UserUDP(UDP_28j60_Dsc *udpDsc) {
 
  unsigned int    len = 0;                           // my reply length
 
  // reply is made of the remote host IP address in human readable format
  ByteToStr(udpDsc-&gt;remoteIP[0], dyna);                // first IP address byte
  dyna[3] = '.';
  ByteToStr(udpDsc-&gt;remoteIP[1], dyna + 4);            // second
  dyna[7] = '.';
  ByteToStr(udpDsc-&gt;remoteIP[2], dyna + 8);            // third
  dyna[11] = '.';
  ByteToStr(udpDsc-&gt;remoteIP[3], dyna + 12);           // fourth
 
  dyna[15] = ':';                                // add separator
 
  // then remote host port number
  WordToStr(udpDsc-&gt;remotePort, dyna + 16);
  dyna[21] = '[';
  WordToStr(udpDsc-&gt;destPort, dyna + 22);
  dyna[27] = ']';
  dyna[28] = 0;
 
  // the total length of the request is the length of the dynamic string plus the text of the request
  len = 28 + udpDsc-&gt;dataLength;
 
  // puts the dynamic string into the transmit buffer
  Net_Ethernet_28j60_putBytes(dyna, 28);
 
  // then puts the request string converted into upper char into the transmit buffer
 
  while(udpDsc-&gt;dataLength--)
          {
          Net_Ethernet_28j60_putByte(toupper(Net_Ethernet_28j60_getByte()));
          }
  return(len);
}
 
void interrupt (void)
{
     if (INTCON.T0IF == 1)
     {
        TMR0H = TMR0_PRE / 256;
        TMR0L = TMR0_PRE % 256;
 
        nb200ms++;
 
        if (nb200ms%5 == 0)
        {
           nb200ms = 0;
           Net_Ethernet_28j60_UserTimerSec ++;
        }
 
 
        if(led0Status == 0)
        {
            LATD.f0 = 0;
        }
        else if(led0Status == 1)
        {
            LATD.f0 = 1;
        }
        else if(led0Status == 2)
        {
            LATD.f0 = !LATD.f0;
        }
 
        INTCON.T0IF = 0;
     }
 
}
 
void MCUInit() {
        ADCON1 = 0;
        ADCON2 = 0b10101010;
        ANCON0 = 0xff;
 
        CM1CON = 0;
        CM2CON = 0;
 
        CVRCON = 0;
 
        PORTA = 0 ;
        TRISA = 0xff ;          // set PORTA as input for ADC
 
        PORTB = 0 ;
        TRISB = 0xff ;          // set PORTB as input for buttons
 
        LATD  = 0 ;
        TRISD = 0 ;             // set PORTD as output
 
        INTCON.GIE = 1;
        T0CON = 0b10000110;
        TMR0H = TMR0_PRE / 256;
        TMR0L = TMR0_PRE % 256;
        INTCON.T0IE = 1;
}
 
void main() {
        char useDHCP = 0;
        int i = 0;
        
        MCUInit();
 
        for(i = 0; i &lt; NUM_OF_SOCKET_28j60; i++)
          pos[i] = 0;
 
        Net_Ethernet_28j60_stackInitTCP();
 
        SPI1_Init();
        SPI_Rd_Ptr = SPI1_Read;
 
        Net_Ethernet_28j60_Init(myMacAddr, myIpAddr, 1); // init ethernet board
        if(Net_Ethernet_28j60_getIpAddress()[0] == 0) useDHCP = 1;
        LATD.f1 = 0;
        led0Status = 2;
        
        asm CLRWDT;
 
        if(useDHCP == 1)
        {
            while(Net_Ethernet_28j60_initDHCP(10) == 0) // try to get one from DHCP until it works
            {
              Net_Ethernet_28j60_Init(myMacAddr, myIpAddr, 1);
              asm CLRWDT;
            }
 
            memcpy(myIpAddr,  Net_Ethernet_28j60_getIpAddress(),    4) ; // get assigned IP address
            memcpy(ipMask,    Net_Ethernet_28j60_getIpMask(),       4) ; // get assigned IP mask
            memcpy(gwIpAddr,  Net_Ethernet_28j60_getGwIpAddress(),  4) ; // get assigned gateway IP address
            memcpy(dnsIpAddr, Net_Ethernet_28j60_getDnsIpAddress(), 4) ; // get assigned dns IP address
 
        }
        else
        {
            Net_Ethernet_28j60_confNetwork(ipMask, gwIpAddr, dnsIpAddr) ; // use configured IP address
        }
 
        led0Status = 1;
        
        
        while(1) {
          //  Process incoming Ethernet packets
          Net_Ethernet_28j60_doPacket();
          
          asm CLRWDT;
          
          for(i = 0; i &lt; NUM_OF_SOCKET_28j60; i++) {
           if(socket_28j60[i].open == 0)
             pos[i] = 0;
          }
          
          if(Net_Ethernet_28j60_doDHCPLeaseTime()) Net_Ethernet_28j60_renewDHCP(5); // it's time to renew the IP address lease, with 5 secs for a reply
 
        }
}

</pre>
</div>
<p>Les actions à effectuer dans l&rsquo;ordre:</p>
<ol>
<li>Définir les paramètres réseau:
<ul>
<li>Adresse IP</li>
<li>Adresse passerelle</li>
<li>Masque de réseau</li>
</ul>
</li>
<li>Initialiser le module SPI</li>
<li>Initialiser le module Ethernet</li>
<li>Configurer le réseau (ou demander une IP par DHCP)</li>
<li>Définir les deux fonctions User_UDP et User_TCP qui sont appelées pour chaque requête reçue ou envoyée</li>
<li>Appeler la fonction doPacket() dans la boucle principale</li>
</ol>
<p>Et voilà, vous êtes prêt à créer un mini serveur web basse consommation.</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/interface-ethernet-pic18f/">Interface Ethernet PIC18F</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/interface-ethernet-pic18f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Joystick USB sur PIC32</title>
		<link>https://amaury-laurent.fr/joystick-usb-sur-pic32/</link>
					<comments>https://amaury-laurent.fr/joystick-usb-sur-pic32/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Tue, 09 Feb 2016 18:38:53 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<guid isPermaLink="false">http://vps200917.ovh.net/?p=402</guid>

					<description><![CDATA[<p>Concevez vos propres contrôleurs de jeux ! Envie d&#8217;améliorer vos expériences de jeux? Alors, concevez vos propres interfaces utilisateurs: tableaux de bord de voiture ou d&#8217;avion, manette de jeu, adaptateur pour de vieux périphériques&#8230; Avec un PIC équipé d&#8217;un module USB tout devient imaginable. Je vais vous expliquer ici comment implanter la couche HID pour [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/joystick-usb-sur-pic32/">Joystick USB sur PIC32</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Concevez vos propres contrôleurs de jeux !</h1>
<p>Envie d&rsquo;améliorer vos expériences de jeux? Alors, concevez vos propres interfaces utilisateurs: tableaux de bord de voiture ou d&rsquo;avion, manette de jeu, adaptateur pour de vieux périphériques&#8230; Avec un PIC équipé d&rsquo;un module USB tout devient imaginable.</p>
<p>Je vais vous expliquer ici comment implanter la couche HID pour que votre PIC soit reconnu en temps que contrôleur de jeux par votre OS préféré.</p>
<h2>Introduction</h2>
<p>Tout d&rsquo;abord, plantons le décor. J&rsquo;ai mené ce projet avec comme objectif final la réalisation d&rsquo;un adaptateur USB pour manette de Nintendo 64 (pour les plus jeunes, voir la page <a href="http://fr.wikipedia.org/wiki/Nintendo_64" target="_blank" rel="noopener noreferrer">Wikipedia</a>). N&rsquo;ayant pas accès au matériel nécessaire à la réalisation finale dans l&rsquo;immédiat, l&rsquo;adaptateur est en stand-by, mais devrait voir le jour prochainement&#8230;</p>
<h2>Le matériel</h2>
<p>Voici le matériel dont vous aurez besoin:</p>
<ul>
<li>Un microcontrôleur avec interface USB</li>
<li>Des moyens d&rsquo;interagir avec ce dernier
<ul>
<li>boutons poussoirs</li>
<li>potentiomètres</li>
<li>joysticks</li>
<li>écran tactile</li>
<li>&#8230;</li>
</ul>
</li>
<li>Le logiciel <a class="no-ajaxy" href="https://amaury-laurent.fr/wp-content/uploads/2016/02/USB_Descriptor_Tool.zip">HID Descriptor Tool</a></li>
<li>De la documentation
<ul>
<li><a class="no-ajaxy" href="https://amaury-laurent.fr/wp-content/uploads/2016/02/HID1_11.pdf" target="_blank" rel="noopener noreferrer">Device Class Definition for Human Interface Devices</a></li>
<li><a class="no-ajaxy" href="https://amaury-laurent.fr/wp-content/uploads/2016/02/Hut1_11.pdf" target="_blank" rel="noopener noreferrer">HID Usage Tables</a></li>
</ul>
</li>
<li>Un environnement de développement pour votre microcontrôleur</li>
<li>Du temps libre</li>
</ul>
<p>J&rsquo;ai réalisé ce projet en étant en déplacement. J&rsquo;ai donc utilisé ma « trousse de survie en milieu hostile »: <a href="http://www.mikroe.com/mikromedia/pic32/" target="_blank" rel="noopener noreferrer">Mikromedia for PIC32</a> + <a href="http://www.mikroe.com/mikroc/pic32/" target="_blank" rel="noopener noreferrer">MikroC for PIC32</a> + <a href="http://www.mikroe.com/visualtft/" target="_blank" rel="noopener noreferrer">Visual TFT</a>. J&rsquo;ai utilisé l&rsquo;écran tactile pour émuler un pad analogique et des boutons poussoirs.</p>
<h2>Un point sur le protocole HID</h2>
<p>Bien que l&rsquo;<a class="menu_link" href="https://amaury-laurent.fr/interface-usb-hid/" target="_blank" rel="noopener noreferrer">Interface USB HID</a> porte son nom, elle n&rsquo;utilise pas les fonctionnalités HID. Elle communique de manière brute (raw) avec le PC en s&rsquo;appuyant uniquement sur les drivers HID. Elle est ainsi configurée par le descripteur USB généré par MikroC. Il est possible de modifier ce descripteur pour déclarer n&rsquo;importe quel périphérique d&rsquo;interface utilisateur.</p>
<p>Mais qu&rsquo;est-ce qu&rsquo;un descripteur? C&rsquo;est très simple: il s&rsquo;agit un bloc d&rsquo;octets envoyés par le périphérique à chaque connexion à un PC afin de s&rsquo;identifier. Ce bloc est interprété par le PC pour configurer automatiquement le driver HID. Le descripteur décrit (tiens tiens&#8230;) également le format du rapport envoyé périodiquement par le périphérique. Ce rapport contient toutes les variables acquises par le périphérique (valeur des axes, état des boutons&#8230;). Ainsi, l&rsquo;utilisateur n&rsquo;a pas ou peu de configuration à faire (sauf pour des cas très spéciaux): la magie du plug&rsquo;n&rsquo;play ! La rédaction de ce descripteur sera l&rsquo;étape la plus importante et la plus critique de ce projet.</p>
<p>La première chose à faire est d&rsquo;identifier les besoins: nombre d&rsquo;entrées, de quels types &#8230; Pour ce faire, j&rsquo;ai repris le matchup de la manette de N64:</p>
<ul>
<li style="color=: green;">Axe X</li>
<li style="color=: green;">Axe Y</li>
<li style="color=: blue;">Croix directionnelle</li>
<li style="color=: red;">Boutons C (haut, bas, gauche et droite), A, B, Z, L, R, START</li>
</ul>
<p>J&rsquo;ai donc deux types d&rsquo;entrés: analogiques (x2) et tout ou rien (x14).</p>
<p>Voici donc la structure de données que je vais utiliser. Je décide de coder les signaux analogiques sur 8 bits signés. Les boutons se contentent eux d&rsquo;un bit chacun.</p>
<table class="customTable">
<tbody>
<tr>
<th></th>
<th>bit 0</th>
<th>bit 1</th>
<th>bit 2</th>
<th>bit 3</th>
<th>bit 4</th>
<th>bit 5</th>
<th>bit 6</th>
<th>bit 7</th>
</tr>
<tr>
<th>octet 0</th>
<td colspan="8">Axe X</td>
</tr>
<tr>
<th>octet 1</th>
<td colspan="8">Axe Y</td>
</tr>
<tr>
<th>octet 2</th>
<td colspan="4">Croix directionnelle</td>
<td colspan="4">Boutons C</td>
</tr>
<tr>
<th>octet 3</th>
<td>A</td>
<td>B</td>
<td>Z</td>
<td>L</td>
<td>R</td>
<td>START</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>Les deux derniers bits du dernier octet sont inutilisés. Ce n&rsquo;est pas grave, mais il faut les faire apparaitre dans le descripteur pour obtenir un nombre entier d&rsquo;octets dans le rapport.</p>
<p>Après avoir compulsé rapidement les deux PDF de documentation pour s&rsquo;imprégner de la philosophie HID, il est temps d&rsquo;ouvrir le logiciel HID Descriptor Tool.</p>
<p><a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/02/UDT.png"><img decoding="async" class="aligncenter wp-image-409 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:190/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2016/02/UDT.png" alt="" width="300" height="190" /></a></p>
<p>Le panneau de gauche propose les différents champs qu&rsquo;il est possible d&rsquo;inclure dans le descripteur de l&rsquo;interface HID. Le panneau de droite représente votre descripteur.</p>
<p>Vous pouvez voir sur la capture d&rsquo;écran le descripteur que j&rsquo;ai utilisé pour mon joystick. La règle qu&rsquo;il faut toujours respecter est d&rsquo;obtenir un rapport codé sur un nombre entier d&rsquo;octets. Je m&rsquo;explique: la plus petite unité utilisée en informatique pour coder des informations est l&rsquo;octet (8 bits), le rapport HID est envoyé octet par octet au PC et se dernier doit connaitre précisément l&rsquo;utilité ce chacun de ces octets.</p>
<p>Regardons plus en détail le descripteur:</p>
<ul>
<li><em><strong>USAGE_PAGE (Generic Desktop)</strong>:</em> Déclare un périphérique d&rsquo;usage général (joystick). Plusieurs périphériques peuvent être déclarés sur une même interface HID.</li>
<li><em><strong>USAGE (Joystick)</strong>:</em> Identifie le type de périphérique décrit dans la USAGE_PAGE.</li>
<li><em><strong>COLLECTION (Application)</strong>:</em> Déclare le descripteur.
<ul>
<li><em><strong>USAGE (Pointer)</strong>:</em> Déclare un périphérique de pointage (ensemble d&rsquo;axes analogiques)</li>
<li><em><strong>COLLECTION (Physical)</strong>:</em> Déclare un descripteur physique.
<ul>
<li><em><strong>USAGE (X)</strong>:</em> Déclare l&rsquo;axe X.</li>
<li><em><strong>USAGE (Y)</strong>:</em> Déclare l&rsquo;axe Y.</li>
<li><em><strong>LOGICAL_MAXIMUM (127)</strong>:</em> Déclare la valeur de la borne maximum des axes (8 bits signés dans mon cas).</li>
<li><em><strong>LOGICAL_MINIMUM (-128)</strong>:</em> Déclare la valeur de la borne minimum des axes (8 bits signés dans mon cas).</li>
<li><em><strong>REPORT_SIZE (8)</strong>:</em> Longueur en bits du champ représentant un axe.</li>
<li><em><strong>REPORT_COUNT (2)</strong>:</em> Nombre de champ dans le descripteur (2 axes sur 8 bits).</li>
<li><em><strong>INPUT (Data,Var,Abs)</strong>:</em> Type de données pour les axes: variable.</li>
</ul>
</li>
<li><em><strong>END_COLLECTION</strong>:</em> fin du descripteur physique.</li>
<li><em><strong>USAGE (Hat Switch)</strong>:</em> Déclare un PoV Hat. C&rsquo;est le bouton en forme de chapeau sur le haut des joysticks. Il est fait pour changer le point de vue (PoV &lt;=&gt; Point of View) dans les jeux. Je vais l&rsquo;utiliser pour la croix directionnelle.</li>
<li><em><strong>LOGICAL_MINIMUM (0)</strong>:</em> Valeur logique minimum. C&rsquo;est l&rsquo;indice du premier bit représentant la première position du hat.</li>
<li><em><strong>LOGICAL_MAXIMUM (3)</strong>:</em> Valeur logique maximum. C&rsquo;est l&rsquo;indice du dernier bit représentant la dernière position du hat.</li>
<li><em><strong>PHYSICAL_MINIMUM (0)</strong>:</em> Valeur physique minimum. C&rsquo;est la valeur d&rsquo;angle du hat liée à la valeur logique minimum.</li>
<li><em><strong>PHYSICAL_MAXIMUM (270)</strong>:</em> Valeur physique maximum. C&rsquo;est la valeur d&rsquo;angle du hat liée à la valeur logique maximum.</li>
<li><em><strong>UNIT (Eng Rot:Angular Pos)</strong>:</em> Unité des valeurs physiques du hat: rotation en degré</li>
<li><em><strong>REPORT_SIZE (4)</strong>:</em> Longueur en bits du champ représentant le hat.</li>
<li><em><strong>REPORT_COUNT (1)</strong>:</em> Nombre de champ dans le descripteur (1 seul hat déclaré).</li>
<li><em><strong>INPUT (Data,Var,Abs)</strong>:</em> Type de donnée pour le hat: variable.</li>
<li><em><strong>USAGE_PAGE (Button)</strong>:</em> Déclare un descripteur de boutons.</li>
<li><em><strong>USAGE_MINIMUM (No Buttons Pressed)</strong>:</em>Valeur représentant tous les bits au repos</li>
<li><em><strong>USAGE_MAXIMUM (Button 10)</strong>:</em> Valeur représentant le dernier bit activé.</li>
<li><em><strong>LOGICAL_MINIMUM (0)</strong>:</em> Valeur logique minimum. Valeur du bit représentant un bouton au repos.</li>
<li><em><strong>LOGICAL_MAXIMUM (1)</strong>:</em> Valeur logique maximum. Valeur du bit représentant un bouton activé.</li>
<li><em><strong>REPORT_SIZE (1)</strong>:</em> Longueur en bits du champ représentant un bouton.</li>
<li><em><strong>REPORT_COUNT (10)</strong>:</em> Nombre de champ dans le descripteur (10 boutons).</li>
<li><em><strong>UNIT_EXPONENT (0)</strong>:</em> Pas de facteur multiplicatif à appliquer sur les champ du descripteur.</li>
<li><em><strong>UNIT (None)</strong>:</em> Pas d&rsquo;unité pour un bouton.</li>
<li><em><strong>INPUT (Data,Var,Abs)</strong>:</em> Type de donnée pour les boutons: variable.</li>
</ul>
</li>
<li><em><strong>REPORT_SIZE (1)</strong>:</em> Longueur en bits du champ de padding.</li>
<li><em><strong>REPORT_COUNT (2)</strong>:</em> Nombre de champ dans le descripteur (2 bits vides à la fin du descripteur).</li>
<li><em><strong>INPUT (Cnst,Var,Abs)</strong>:</em> Type de donnée pour le hat: constant. ⚠ Il est capital de mettre ces champ en constant autrement le périphérique ne marche pas.</li>
<li><em><strong>END_COLLECTION</strong>:</em> fin du descripteur.</li>
</ul>
<p>Voici votre descripteur prêt à être implanté dans votre microcontrôleur. Il reste à l&rsquo;enregistrer en fichier header (.h) pour pouvoir l&rsquo;exploiter dans votre code source:</p>
<div class="source">
<pre class="EnlighterJSRAW" data-enlighter-language="c">char ReportDescriptor[71] = {
    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)
    0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
    0x15, 0x80,                    //     LOGICAL_MINIMUM (-128)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0x09, 0x39,                    //   USAGE (Hat switch)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x03,                    //   LOGICAL_MAXIMUM (3)
    0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
    0x46, 0x0e, 0x01,              //   PHYSICAL_MAXIMUM (270)
    0x65, 0x14,                    //   UNIT (Eng Rot:Angular Pos)
    0x75, 0x04,                    //   REPORT_SIZE (4)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x00,                    //   USAGE_MINIMUM (No Buttons Pressed)
    0x29, 0x0a,                    //   USAGE_MAXIMUM (Button 10)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x0a,                    //   REPORT_COUNT (10)
    0x55, 0x00,                    //   UNIT_EXPONENT (0)
    0x65, 0x00,                    //   UNIT (None)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x75, 0x01,                    // REPORT_SIZE (1)
    0x95, 0x02,                    // REPORT_COUNT (2)
    0x81, 0x03,                    // INPUT (Cnst,Var,Abs)
    0xc0                           // END_COLLECTION
};</pre>
</div>
<p>La variable ReportDescriptor peut être envoyée au PC sur l&rsquo;USB par votre microcontrôleur.</p>
<h2>Mise en place avec MikroC</h2>
<p>Pour programmer ma Mikromedia, j&rsquo;utilise MikroC et Visual TFT (pour l&rsquo;interface graphique). Je ne vais pas détailler l&rsquo;interface graphique, mais plutôt me concentrer sur la couche USB. Le départ est identique à celui utilisé pour l&rsquo;Interface HID Universelle: configuration de l&rsquo;horloge, déclaration des buffers USB (read et write), génération d&rsquo;un descripteur avec HID Terminal et initialisation du module USB dans le programme. Voici les lignes importantes du programme qui concernent uniquement l&rsquo;USB:</p>
<div class="source">
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "USB_DSC.c"
#define USB_BUFFER_LEN       64
 
unsigned char readbuff[USB_BUFFER_LEN] ;
unsigned char writebuff[USB_BUFFER_LEN] ;
 
T_USB_Report USB_Report;
 
void USB_Isr() iv IVT_USB_1 ilevel 7 ics ICS_SRS {
    USB_Interrupt_Proc();        // USB servicing is done inside the interrupt
    USBIF_bit = 0;
}
 
void main() {
    EnableInterrupts();
 
    /* Interruption USB sur vecteur 7*/
    USBIP0_bit = 1;
    USBIP1_bit = 1;
    USBIP2_bit = 1;
    USBIE_bit = 1;
 
    HID_Enable(&amp;readbuff,&amp;writebuff);
    
    while (1) {
        HID_Write(USB_Report.bytes, sizeof(USB_Report));
    }
}

</pre>
</div>
<p>Le rapport USB est une variable de type T_USB_Report déclaré comme suit:</p>
<div class="source">
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef union {
    char bytes[4];
    struct {
        char x_value;
        char y_value;
        unsigned pov_hat :4;
        unsigned button_1 :1;
        unsigned button_2 :1;
        unsigned button_3 :1;
        unsigned button_4 :1;
        unsigned button_5 :1;
        unsigned button_6 :1;
        unsigned button_7 :1;
        unsigned button_8 :1;
        unsigned button_9 :1;
        unsigned button_10:1;
    };
} T_USB_Report;

</pre>
</div>
<p>On y retrouve tous les champ déclarés dans le descripteur. L&rsquo;union permet d&rsquo;y accéder comme un tableau d&rsquo;octets (pour l&rsquo;envoi) ou champ par champ (pour y insérer les valeurs).</p>
<p>Ensuite, il faut modifier le fichier USBdsc.c pour y modifier le descripteur. Il faut remplacer celui généré par HID Terminal par celui que nous avons créé avec USB Descriptor Tool. Trouvez la variable hid_rpt_desc et remplacé sont contenu par celui généré par UDT:</p>
<div class="source">
<pre class="EnlighterJSRAW" data-enlighter-language="c">const struct {
  char report[USB_HID_RPT_SIZE];
}hid_rpt_desc =
  {
    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)
    0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
    0x15, 0x80,                    //     LOGICAL_MINIMUM (-128)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0x09, 0x39,                    //   USAGE (Hat switch)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x03,                    //   LOGICAL_MAXIMUM (3)
    0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
    0x46, 0x0e, 0x01,              //   PHYSICAL_MAXIMUM (270)
    0x65, 0x14,                    //   UNIT (Eng Rot:Angular Pos)
    0x75, 0x04,                    //   REPORT_SIZE (4)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x00,                    //   USAGE_MINIMUM (No Buttons Pressed)
    0x29, 0x0a,                    //   USAGE_MAXIMUM (Button 10)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x0a,                    //   REPORT_COUNT (10)
    0x55, 0x00,                    //   UNIT_EXPONENT (0)
    0x65, 0x00,                    //   UNIT (None)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x75, 0x01,                    // REPORT_SIZE (1)
    0x95, 0x02,                    // REPORT_COUNT (2)
    0x81, 0x03,                    // INPUT (Cnst,Var,Abs)
    0xc0                           // END_COLLECTION
  };

</pre>
</div>
<p>Il faut également modifier la taille du descripteur: <em>const char USB_HID_RPT_SIZE = 71;</em> Cette ligne est au début du fichier USBdsc.c .</p>
<p>Enfin, il reste à affecter les valeurs du rapport USB avec celles acquises par le microcontrôleur, et envoyer le rapport au PC. Pour l&rsquo;envoi, il est possible de choisir une période de boucle de l&rsquo;ordre de 10ms. La fluidité du périphérique est bonne et la charge de calcul et de la liaison reste correcte.</p>
<p><a href="http://www.libstock.com/projects/view/715/usb-joystick-for-mikromedia-for-pic32" target="_blank" rel="noopener noreferrer">Le projet pour Mikromedia est disponible sur Libstock.</a></p>
<h2>Fonctionnement</h2>
<p>Si tous s&rsquo;est bien passé, une fois votre microcontrôleur programmé et branché, vous devriez le trouver en tant que contrôleur de jeux:</p>
<p>[metaslider id=422]</p>
<h3>Démonstration en vidéo</h3>
<p><iframe title="USB Joystick on Mikromedia for PIC32" width="640" height="480"  src="about:blank" data-opt-src="https://www.youtube.com/embed/owLl_IGX6aU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></p>
<h3>Utilisation avec Zelda: Ocarina of Time</h3>
<p><a href="https://www.facebook.com/amaury.laurent.31/videos/147704392082253/" target="_blank" rel="noopener">https://www.facebook.com/amaury.laurent.31/videos/147704392082253/</a></p>
<p>&nbsp;</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/joystick-usb-sur-pic32/">Joystick USB sur PIC32</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/joystick-usb-sur-pic32/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Télécommande IR pour Nikon</title>
		<link>https://amaury-laurent.fr/telecommande-ir-pour-nikon/</link>
					<comments>https://amaury-laurent.fr/telecommande-ir-pour-nikon/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Tue, 09 Feb 2016 18:05:50 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<guid isPermaLink="false">http://vps200917.ovh.net/?p=388</guid>

					<description><![CDATA[<p>Idéal pour les photos sur trépieds Le concept Les amateurs de photo sont rapidement tentés par la réalisation de prises de vue nocturnes, la réalisation de Timelapses ou la photo HDR. Toutes ces techniques requièrent l&#8217;utilisation d&#8217;un trépieds et le maintient parfait de l&#8217;appareil photo. Le simple appuie sur le déclencheur peut ruiner la pose! [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/telecommande-ir-pour-nikon/">Télécommande IR pour Nikon</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Idéal pour les photos sur trépieds</h1>
<h2>Le concept</h2>
<p>Les amateurs de photo sont rapidement tentés par la réalisation de prises de vue nocturnes, la réalisation de Timelapses ou la photo HDR. Toutes ces techniques requièrent l&rsquo;utilisation d&rsquo;un trépieds et le maintient parfait de l&rsquo;appareil photo. Le simple appuie sur le déclencheur peut ruiner la pose! Pour me simplifier la vie, j&rsquo;ai conçu une petite télécommande qui me permet, en plus de déclencher l&rsquo;appareil, de lancer une suite de prises de vue avec un intervalle fixe mais long (plusieurs secondes voir plusieurs minutes).</p>
<h2>Le protocole de communication</h2>
<p>L&rsquo;une des constante que l&rsquo;on retrouve souvent dans les liaisons numériques infrarouge est la double modulation de l&rsquo;onde lumineuse. Tout d&rsquo;abord, la source lumineuse, une LED IR, émet de la lumière aux alentours de 940nm. Cette onde lumineuse est ensuite hachée à une quarantaine de kHz pour former un signal porteur carré (les récepteurs IR intégré du type <a href="http://www.datasheetcatalog.com/datasheets_pdf/T/S/O/P/TSOP1133.shtml" target="_blank" rel="noopener noreferrer">TSOP 1133</a> démodulent directement ce signal carré). Ce signal est ensuite modulé pour transmettre l&rsquo;information. Si le codage <a href="http://fr.wikipedia.org/wiki/Codage_Manchester" target="_blank" rel="noopener noreferrer">Manchester</a> est souvent utilisé pour la modulation, Nikon ne semble pas l&rsquo;utiliser. Le site <a href="http://www.sbprojects.com/projects/nikon/" target="_blank" rel="noopener noreferrer">SBProject</a> présente la forme de la trame envoyée par la télécommande:</p>
<p><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/frame.png" target="_blank" rel="noopener"><img decoding="async" class="aligncenter wp-image-394 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/frame-300x97.png" alt="Trame IR" width="300" height="97" /></a></p>
<p>Ce motif vient moduler un signal carré à 38kHz avant d&rsquo;être appliqué aux LED infrarouge. Le motif est répété 2 fois à 63.2ms d&rsquo;intervalle. Les 2 motifs commandent une seule prise de vue.</p>
<h2>Le fonctionnement de la télécommande</h2>
<p>Ma télécommande vise la simplicité: un seul bouton et un double afficheur 7 segments. Avec ceci, je veux pouvoir prendre des photos à l&rsquo;appuie sur le bouton, fixer une période de répétition, lancer et arrêter une séquence de prise de vue. Voici les différentes actions possibles :</p>
<ul>
<li>Pas de durée de répétition fixée:
<ul>
<li>Appuie court: Prise de vue</li>
<li>Appuie long: Incrémentation de la durée de répétition (tant que le bouton est maintenu)</li>
</ul>
</li>
<li>Une durée de répétition est fixée:
<ul>
<li>Appuie court: Arrêter/Démarrer la séquence</li>
<li>Appuie long: Remise à zéro de la durée de répétition</li>
</ul>
</li>
</ul>
<p>Un appuie court dure moins de 750ms. Un appuie long dure plus de 750ms et est maintenu tant que le bouton est enfoncé.</p>
<h2>Le matériel</h2>
<p>Pour réaliser cette télécommande, il vous faut: un micro-contrôleur (et tout ce qui l&rsquo;accompagne), un afficheur, un bouton, une pile (et le circuit d&rsquo;alimentation) et des LED infrarouge. Voici mes choix technologiques:</p>
<ul>
<li>Un PIC18F4550 cadencé à 48MHz (un peu gros mais c&rsquo;est le seul que j&rsquo;avais sous la main)</li>
<li>Un double afficheur 7 segments à anodes communes</li>
<li>3 LED infrarouge et un transistor NPN pour les commander</li>
<li>Une pile 9V et un 7805 pour fournit le 5V</li>
<li>Un bouton poussoir</li>
<li>Un boitier étanche (même s&rsquo;il faut percer des trous pour les LED et les boutons&#8230;) et antichocs</li>
</ul>
<p>Et maintenant, le schéma:</p>
<p><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/schematic.png" target="_blank" rel="noopener"><img decoding="async" class="aligncenter wp-image-395 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/schematic-300x220.png" alt="Schéma de la télécommande" width="300" height="220" /></a></p>
<p>On retrouve le PIC18F4550 avec ses capacités de découplage, son horloge, son circuit de Reset et son connecteur de programmation. Autours de lui, on a l&rsquo;afficheur 7 segments directement alimenté par le PIC, avec les deux digits multiplexés, et le bouton poussoir relié à la broche RB0 qui présente le double avantage de générer une interruption processeur et de proposer une résistance de Pull-Up intégrée (comme tout le port B).</p>
<h2>Le programme</h2>
<p>Ce programme a été écrit pour l&rsquo;environnement MikroC. C&rsquo;est bien sûr un exemple. Chacun est libre d&rsquo;adapter le fonctionnement de la télécommande à son inspiration et son envie.</p>
<div class="source">
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define MAIN_CLK 48000000
#define CARRIER_CLK 38000
#define DEMI_PERIODE_US     13
#define PERIODE_AFF_MS      10
 
/* Brochage afficheur 7 segments :
**     Cathodes :
**       ___
**     | RE0 |
** RE1 |     | RA1
**     | ___ |
**     | RA5 |
** RA3 |     | RA2
**     | ___ |
**       RA4
**
**      Anodes:
**       _   _
**      |_| |_|
**      |_| |_|
**      RE2 RA0
*/
 
short displayed = 12;
short toogle = 0;
short intervalle = 0;
short running = 0;
int inc = 0;
int old_pushed_button = 0;
 
void IrCycles (int nbCycles) {
     int i = 0;
     
     for (i=0; i&lt;nbCycles; i++) {
         latd.f1 = 1;
         Delay_us(DEMI_PERIODE_US);
         latd.f1 = 0;
         Delay_us(DEMI_PERIODE_US);
     }
}
 
void WaitCycles (int nbCycles) {
     int i = 0;
     
     latd.f1 = 0;
 
     for (i=0; i&lt;nbCycles; i++) {
         Delay_us(DEMI_PERIODE_US);
         Delay_us(DEMI_PERIODE_US);
     }
}
 
void TakePhoto (void) {
     latd.f2 = 1;
     IrCycles(76);
     WaitCycles(1064);
     IrCycles(15);
     WaitCycles(60);
     IrCycles(15);
     WaitCycles(136);
     IrCycles(15);
     Delay_us(63200);
     IrCycles(76);
     WaitCycles(1064);
     IrCycles(15);
     WaitCycles(60);
     IrCycles(15);
     WaitCycles(136);
     IrCycles(15);
     latd.f2 = 0;
}
 
void DisplayNumber (char number) {
     number = number%16;
     
     switch (number) {
      case 0:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 1;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 1:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 1;
           lata.f4 = 1;
           lata.f5 = 1;
           late.f0 = 1;
           late.f1 = 1;
           break;
      case 2:
           lata.f1 = 0;
           lata.f2 = 1;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 1;
           break;
      case 3:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 1;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 1;
           break;
      case 4:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 1;
           lata.f4 = 1;
           lata.f5 = 0;
           late.f0 = 1;
           late.f1 = 0;
           break;
      case 5:
           lata.f1 = 1;
           lata.f2 = 0;
           lata.f3 = 1;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 6:
           lata.f1 = 1;
           lata.f2 = 0;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 7:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 1;
           lata.f4 = 1;
           lata.f5 = 1;
           late.f0 = 0;
           late.f1 = 1;
           break;
      case 8:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 9:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 1;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 0xa:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 0;
           lata.f4 = 1;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 0xb:
           lata.f1 = 1;
           lata.f2 = 0;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 1;
           late.f1 = 0;
           break;
      case 0xc:
           lata.f1 = 1;
           lata.f2 = 1;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 1;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 0xd:
           lata.f1 = 0;
           lata.f2 = 0;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 1;
           late.f1 = 1;
           break;
      case 0xe:
           lata.f1 = 1;
           lata.f2 = 1;
           lata.f3 = 0;
           lata.f4 = 0;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 0;
           break;
      case 0xf:
           lata.f1 = 1;
           lata.f2 = 1;
           lata.f3 = 0;
           lata.f4 = 1;
           lata.f5 = 0;
           late.f0 = 0;
           late.f1 = 0;
           break;
     }
}
 
void interrupt (void) {
     if (INT0IF_bit) {
        if (!PORTB.f0) {
           if (intervalle != 0) inc = 0;
           else inc = 1;
        }
        
        INT0IF_bit = 0;
     }
 
     if (TMR0IF_bit) {
        if (displayed &gt;=0) {
           if (toogle) {
              late.f2 = 1;   //dizaine
              lata.f0 = 0;   //unite
              DisplayNumber((displayed/10)%10);
           }
           else {
              late.f2 = 0;   //dizaine
              lata.f0 = 1;   //unite
              DisplayNumber((displayed)%10);
           }
        }
        else {
             late.f2 = 0;   //dizaine
             lata.f0 = 0;   //unite
        }
        toogle = !toogle;
        TMR0IF_bit = 0;
     }
}
 
void main() {
     int i = 0;
     int j = 0;
     int cligno = 0;
 
     trisd.f2 = 0;
     trisd.f1 = 0;
     trisa = 0;
     trise = 0;
     RBPU_bit = 0;
     latd.f2 = 0;
     INTEDG0_bit = 0; //falling edge
     INT0IE_bit = 1;
     TMR0IE_bit = 1;
     GIE_bit = 1;
     PEIE_bit = 1;
     T08BIT_bit = 0;
     T0CS_bit = 0;
     PSA_bit = 1;
     TMR0H = 0;
     TMR0L = 0;
     TMR0ON_bit = 1;
     
     intervalle = 0;
     
     i = -0;
     j = 0;
     inc = 0;
     cligno = 0;
     old_pushed_button = 0;
 
     while (1) {
         if (!running) {
           if (intervalle &gt; 0) displayed = intervalle;
           else displayed = -1;
         }
         
         if (!portb.f0) {
            j = 0;
            if (inc == 1) {
              if ((intervalle &lt; 10) &amp;&amp; (i%50 == 0) &amp;&amp; (i&gt;0)) intervalle++;
              else if ((intervalle &gt;= 10) &amp;&amp; (intervalle &lt; 99) &amp;&amp; (i%25 == 0) &amp;&amp; (i&gt;0)) intervalle++;
            }
            else if ((i%50 == 0) &amp;&amp; (i&gt;0)) intervalle = 0;
            i++;
         }
         else {
           if ((i&lt;50)&amp;&amp;(i&gt;0)&amp;&amp; (old_pushed_button)) {
              if (intervalle == 0) TakePhoto();
              else running = !running;
           }
           i = -0;
           
           if (running) {
               if ((j/100&lt;intervalle)) {
                   if (j%50 == 0) cligno = !cligno;
                   if (cligno) displayed = intervalle - j/100;
                   else displayed = -1;
                   j++;
               }
               else {
                  j = 0;
                  TakePhoto();
               }
           }
         }
         old_pushed_button = !portb.f0;
         Delay_ms(10);
     }
 
}

</pre>
</div>
<h2>Quelques photos</h2>
<p>[metaslider id=399]</p>
<p>A vos reflex !</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/telecommande-ir-pour-nikon/">Télécommande IR pour Nikon</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/telecommande-ir-pour-nikon/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Horloge à tubes Nixie</title>
		<link>https://amaury-laurent.fr/horloge-a-tubes-nixie/</link>
					<comments>https://amaury-laurent.fr/horloge-a-tubes-nixie/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Sat, 17 Oct 2015 16:23:14 +0000</pubDate>
				<category><![CDATA[Electronique]]></category>
		<category><![CDATA[Microcontrôleur]]></category>
		<guid isPermaLink="false">http://vps200917.ovh.net/?p=285</guid>

					<description><![CDATA[<p>Ou comment ajouter une touche de mauvais goût sur votre bureau&#8230; !!! Avertissements !!! Cette réalisation utilise des tensions continues supérieures à 200V. Un contact direct avec une pièce nue sous tension peut causer un choc électrique. Historique: Avant l&#8217;avènement des LED (1962), Afficheurs 7 segments et autres tubes VFD (1980), l&#8217;indicateur numérique par excellence [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/horloge-a-tubes-nixie/">Horloge à tubes Nixie</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 ajouter une touche de mauvais goût sur votre bureau&#8230;</h1>
<h2 style="color: #8a0000; text-align: center;">!!! Avertissements !!!</h2>
<p>Cette réalisation utilise des tensions continues supérieures à 200V. Un contact direct avec une pièce nue sous tension peut causer un choc électrique.</p>
<h2>Historique:</h2>
<p>Avant l&rsquo;avènement des LED (1962), Afficheurs 7 segments et autres tubes VFD (1980), l&rsquo;indicateur numérique par excellence était le tube Nixie. Produit en série à partir de 1954, ce sont des tubes à vides à cathode froide munis d&rsquo;une dizaine d&rsquo;électrodes (entre 10 et 12 généralement). Chaque électrode à la forme d&rsquo;un chiffre, avec potentiellement un ou deux points décimal. L&rsquo;application d&rsquo;une tension sur l&rsquo;une des électrode provoque une luminescence de celle-ci. En associant plusieurs tubes, il est possible de réaliser un indicateur numérique. Ces composants furent utilisés dans les premiers voltmètres à affichages digital, les calculatrices et autres appareils numériques:</p>
<p><a href="http://vps200917.ovh.net/wp-content/uploads/2015/10/NixieFrequencyCounter.jpg" target="_blank" rel="noopener"><img decoding="async" class="aligncenter size-medium wp-image-290" src="http://vps200917.ovh.net/wp-content/uploads/2015/10/NixieFrequencyCounter-300x118.jpg" alt="NixieFrequencyCounter" width="300" height="118" /></a><br />
<em> Source: <a class="fancybox-iframe" href="https://fr.wikipedia.org/wiki/Tube_Nixie" target="_blank" rel="noopener"> Wikipedia </a></em></p>
<h2>Mise en oeuvre</h2>
<p>Le principal problème technique posé par l&rsquo;utilisation de tubes Nixie réside dans leur tension d&rsquo;alimentation. La datasheet de mes tubes IN-16 (<a class="no-ajaxy" href="http://vps200917.ovh.net/wp-content/uploads/2015/10/IN-16_02.pdf" target="_blank" rel="noopener">En Russe</a>&#8230;) indique une tension d&rsquo;amorçage d&rsquo;au-moins 200 volts continue. La tension d&rsquo;alimentation après amorçage doit être maintenue à environ 170 volts continue sous un courant de 2.5mA. La première difficulté consiste donc à obtenir 200Vdc sous 10mA (4 tubes) à partir d&rsquo;une alimentation de sécurité (idéalement 9-15Vdc). La deuxième difficulté va être de trouver des composants (drivers d&rsquo;affichage) capables de manipuler une telle tension.</p>
<h2>Les tubes Nixie</h2>
<p>Il existe plein de revendeurs de tubes Nixie sur la toile (dont pas mal sur eBay). Je me suis orienté vers <a class="fancybox-iframe" href="http://www.kosbo.com" target="_blank" rel="noopener">kosbo.com</a> sur les conseils d&rsquo;un ami. Je n&rsquo;ai vraiment pas été déçu: livraison sérieuse, tous les tubes sont arrivés entiers. Pour ces derniers, j&rsquo;ai choisi un modèle de petite taille: l&rsquo;IN-16. Il s&rsquo;agit de tubes russes d&rsquo;environ 3cm de haut. Ils ont l’avantage d&rsquo;utiliser une électrode différente pour le 2 et pour le 5 (qui était souvent la même monté dans deux orientations différentes).</p>
<p>Pour les nostalgiques voici la datasheet d&rsquo;origine en Russe: <a class="no-ajaxy" href="http://vps200917.ovh.net/wp-content/uploads/2015/10/IN-16_02.pdf" target="_blank" rel="noopener">IN-16_02.pdf</a></p>
<p>Pour les non russophones, voici une traduction dans la langue de Shakespeare fournie par kosbo: <a class="no-ajaxy" href="http://vps200917.ovh.net/wp-content/uploads/2015/10/IN16_layout.pdf" target="_blank" rel="noopener">IN16_layout.pdf</a></p>
<p>Le pilotage des tubes Nixie va être confié à un composant d&rsquo;époque (russes également, équivalent du DM54 de MSI et du 74141&#8230;): <a class="no-ajaxy" href="http://vps200917.ovh.net/wp-content/uploads/2015/10/k155id1.pdf" target="_blank" rel="noopener">le K555</a>. Il s&rsquo;agit d&rsquo;un décodeur BCD vers décimal capable de commuter la tension d&rsquo;alimentation des tubes.</p>
<h2>L&rsquo;alimentation 200Vdc</h2>
<p>Il est possible de réaliser une alimentation à découpage 15V -&gt; 200V à base d&rsquo;un NE555, d&rsquo;une capacité et d&rsquo;une bobine. L&rsquo;un des schéma circulant sur la toile est le suivant:<a href="http://vps200917.ovh.net/wp-content/uploads/2015/10/nixie-psu.png" target="_blank" rel="noopener"><img decoding="async" class="aligncenter size-medium wp-image-303" src="http://vps200917.ovh.net/wp-content/uploads/2015/10/nixie-psu-300x188.png" alt="nixie psu" width="300" height="188" /></a></p>
<p>Il est tiré du site: <a class="fancybox-iframe" href="http://www.turbokeu.com" target="_blank" rel="noopener">http://www.turbokeu.com</a>. J&rsquo;ai réalisé un prototype d&rsquo;une telle alimentation avec des composants tirés d&rsquo;un fond de tiroir:</p>
<ul>
<li>Un condensateur 33µF 500 Vcc de marque CMF</li>
<li>Une inductance 100µH C&amp;D Technologies</li>
<li>Un MOS IRF740 comme hacheur</li>
</ul>
<p>Étonnement, L&rsquo;alimentation s&rsquo;est très bien comportée: pas de sifflement gênant, pas de surchauffe de l&rsquo;IRF740, un courant convenable et une tension de sortie à partir de 170V. Cependant, lors du réglage de la tension de sortie, celle-ci à dépassée la tension de claquage de mon condensateur&#8230; Tout à refaire! J&rsquo;avoue alors m&rsquo;être tourné vers une solution plus simple, bien que moins élégante: acheter un module d&rsquo;alimentation pour tubes Nixie. Je me suis tourné vers le revendeur de mes tubes, <a class="fancybox-iframe" href="http://www.kosbo.com" target="_blank" rel="noopener">kosbo.com</a>, et j&rsquo;ai trouvé <a class="fancybox-iframe" href="http://www.kosbo.com/index.php?option=com_content&amp;view=article&amp;id=107&amp;Itemid=79" target="_blank" rel="noopener">un petit module intégré</a> recevant une alimentation de 12V et ressortant environ 200V ainsi que 5V régulé pour l&rsquo;électronique de pilotage.</p>
<h2>L&rsquo;électronique de pilotage</h2>
<p>L&rsquo;intelligence est confiée à un PIC18F4550 (exhumé d&rsquo;un fond de tiroir&#8230;), pas du tout de l&rsquo;époque des tubes, animé par un quartz à 20MHz. Les valeurs envoyées aux K555 pilotant les tubes sont mémorisées dans des verrous <a class="no-ajaxy" href="http://vps200917.ovh.net/wp-content/uploads/2015/10/cd4042.pdf" target="_blank" rel="noopener">cd4042</a> 4 bits qui multiplexent l&rsquo;un des port du PIC. L&rsquo;horloge calendrier est un module MikroElektonika <a class="fancybox-iframe" href="http://www.mikroe.com/click/rtc2/" target="_blank" rel="noopener">RTC2 Click</a> qui a l&rsquo;avantage énorme d&#8217;embarquer la pile de sauvegarde. Quatre boutons poussoirs permettent le réglage de l&rsquo;heure.</p>
<p>Voici le schéma de principe:</p>
<div class="image"><a href="http://vps200917.ovh.net/wp-content/uploads/2015/10/schema1.png" target="_blank" rel="noopener"><img decoding="async" class="aligncenter size-medium wp-image-291" src="http://vps200917.ovh.net/wp-content/uploads/2015/10/schema1-300x277.png" alt="schema" width="300" height="277" /></a></div>
<p>Ma réalisation est faite intégralement sur platine d&rsquo;essai à bandes. Je ne fournirais donc pas de typon de l&rsquo;horloge.</p>
<h2>Galerie</h2>
<p>[metaslider id=326]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/horloge-a-tubes-nixie/">Horloge à tubes Nixie</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/horloge-a-tubes-nixie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Interface USB HID</title>
		<link>https://amaury-laurent.fr/interface-usb-hid/</link>
					<comments>https://amaury-laurent.fr/interface-usb-hid/#comments</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Sat, 03 Oct 2015 08:07:14 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<guid isPermaLink="false">http://vps200917.ovh.net/?p=94</guid>

					<description><![CDATA[<p>Contrôlez vos systèmes depuis un PC en utilisant simplement un port USB Qui n&#8217;a pas eu envie de contrôler un robot, un système embarqué ou son chauffage depuis un PC? Traditionnellement, la liaison utilisée par les électroniciens pour communiquer entre un système embarqué et un PC est la liaison RS232. Elle est en effet très [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/interface-usb-hid/">Interface USB HID</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Contrôlez vos systèmes depuis un PC en utilisant simplement un port USB</h1>
<p>Qui n&rsquo;a pas eu envie de contrôler un robot, un système embarqué ou son chauffage depuis un PC?</p>
<p>Traditionnellement, la liaison utilisée par les électroniciens pour communiquer entre un système embarqué et un PC est la <a class="fancybox-iframe" href="http://fr.wikipedia.org/wiki/RS-232" target="_blank" rel="noopener noreferrer">liaison RS232</a>. Elle est en effet très simple à mettre en place, tant sur le plan matériel que logiciel. Malheureusement, cette dernière commence à ce faire vielle (introduit sur le marché en 1962). De plus en plus de cartes mères arrivent aujourd&rsquo;hui sur le marché sans port RS232, rendant ainsi impossible l&rsquo;utilisation du PC pour des applications électroniques.<br />
Heureusement pour nous, l&rsquo;USB est arrivé, et avec lui tout une gamme de microcontrôleurs pourvus de contrôleurs USB intégrés.</p>
<p>L&rsquo;interface que je vous propose s&rsquo;appuie sur un micro-contrôleur <a class="fancybox-iframe" href="http://ww1.microchip.com/downloads/en/devicedoc/39632d.pdf" target="_blank" rel="noopener noreferrer">PIC18F4550</a> utilisé en <a class="fancybox-iframe" href="http://en.wikipedia.org/wiki/Human_interface_device" target="_blank" rel="noopener noreferrer">périphérique HID</a>.<br />
La programmation de cette interface est en outre simplifiée par l&rsquo;excellent IDE C pour PIC: <a class="fancybox-iframe" href="https://www.mikroe.com/mikroc/#pic" target="_blank" rel="noopener noreferrer">MikroC</a>. Ne prenez pas peur en voyant le prix de la licence MikroC, le logiciel est disponible en version de démonstration. Sa seule limite porte sur la taille du code généré par le compilateur (2ko).</p>
<p>Le schéma s&rsquo;articule donc autour du PIC. On y retrouve son horloge, un circuit de Reset, des connecteurs permettant d&rsquo;accéder aux ports, un connecteur ICSP pour <a class="fancybox-iframe" href="http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;nodeId=1406&amp;dDocName=en538340&amp;redirects=pickit3" target="_blank" rel="noopener">Pickit</a>, un connecteur <a class="fancybox-iframe" href="http://fr.wikipedia.org/wiki/I2C" target="_blank" rel="noopener">I2C</a> et un connecteur USB.<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2015/10/schema_HID.jpg"><img decoding="async" class="aligncenter wp-image-96 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:158/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2015/10/schema_HID.jpg" alt="Schéma de l'interface HID" width="300" height="158" /></a></p>
<p>Les deux capacités du résonateur quartz ne sont pas cruciales: si vous ne disposez pas de la bonne valeur, il vaut mieux ne pas mettre de condensateur du tout. De même pour la capacité C3: si votre alimentation présente un front raide à la mise sous tension, il n&rsquo;est pas nécessaire de la monter (ne pas la mettre facilite la connexion du Pickit&#8230;). En revanche, les deux capacités de découplage C5 et C6 doivent être montées au plus près du PIC. La valeur du condensateur C4 (régulation de la tension USB) est assez libre. La datasheet impose 470nF à 20%, j&rsquo;ai mis une capacité électrochimique de 2.2µF et l&rsquo;interface marche très bien&#8230; À l&rsquo;origine, cette carte à été conçue pour être interfacée avec les <a class="fancybox-iframe" href="http://fr.wikipedia.org/wiki/Lego_Mindstorms_NXT" target="_blank" rel="noopener">Légo Mindstorm NXT</a>, les valeurs des résistances de Pull Up sur la ligne I2C répondent donc aux spécifications Légo. Si vous visez une application plus conventionnelle, des résistances de 1k ou 1k8 feront parfaitement l&rsquo;affaire. La LED3 est un témoin d&rsquo;alimentation et les deux LED 1 et 2 sont des LED de debug.</p>
<p>Le typon tiens sur un circuit simple face:<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2015/10/typon_HID.jpg"><img decoding="async" class="aligncenter wp-image-97 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:240/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2015/10/typon_HID.jpg" alt="Typon de l'interface HID" width="300" height="240" /></a></p>
<p>Le schéma d&rsquo;implantation:<a href="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2015/10/Implantation_HID.jpg"><img decoding="async" class="aligncenter wp-image-100 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:227/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2015/10/Implantation_HID.jpg" alt="Schéma d'implantation de l'interface HID" width="300" height="227" /></a></p>
<p>Vous trouverez tous les documents du projet ci-dessous:</p>
<ul>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2015/10/Interface_HID.zip">Projet Eagle 5.11</a></li>
<li><a class="fancybox-iframe" href="https://amaury-laurent.fr/wp-content/uploads/2015/10/typon_HID.pdf">Typon au format PDF échelle 1:1</a></li>
<li><a href="https://amaury-laurent.fr/tutoriel-de-programmation-de-linterface-hid/">Un tutoriel pour la mise en place du protocole HID avec MikroC</a></li>
<li><a href="https://amaury-laurent.fr/communication-entre-labview-et-linterface-hid/">Un tutoriel pour la commmunication USB avec LabVIEW</a></li>
</ul>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/interface-usb-hid/">Interface USB HID</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/interface-usb-hid/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
