<?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>Réalisation &#8211; Electronique et Informatique</title>
	<atom:link href="https://amaury-laurent.fr/category/realisation/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>Réalisation &#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/feed/?snippet=15cd1e4bde&#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>Exporter un Circuit Imprimé depuis EAGLE vers GALAAD/PERCIVAL</title>
		<link>https://amaury-laurent.fr/exporter-un-circuit-imprime-depuis-eagle-vers-galaad-percival/</link>
					<comments>https://amaury-laurent.fr/exporter-un-circuit-imprime-depuis-eagle-vers-galaad-percival/#respond</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Wed, 02 May 2018 18:11:53 +0000</pubDate>
				<category><![CDATA[Usinage]]></category>
		<category><![CDATA[Electronique]]></category>
		<category><![CDATA[circuit imprimé]]></category>
		<category><![CDATA[eagle]]></category>
		<category><![CDATA[galaad]]></category>
		<category><![CDATA[gerber]]></category>
		<category><![CDATA[gravure]]></category>
		<category><![CDATA[lancelot]]></category>
		<category><![CDATA[percival]]></category>
		<guid isPermaLink="false">http://amaury-laurent.fr/?p=881</guid>

					<description><![CDATA[<p>Cet article a pour but d&#8217;expliquer la procédure a suivre pour passer d&#8217;une conception réalisée avec EAGLE Layout Editor à un circuit imprimé en chair et en os (ou plutôt en époxy et en cuivre) réalisé avec PERCIVAL. Cet article présuppose une bonne connaissance des outils EAGLE et GALAAD/LANCELOT pour la CAO et l&#8217;usinage. Introduction [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/exporter-un-circuit-imprime-depuis-eagle-vers-galaad-percival/">Exporter un Circuit Imprimé depuis EAGLE vers GALAAD/PERCIVAL</a> est apparu en premier sur <a rel="nofollow" href="https://amaury-laurent.fr">Electronique et Informatique</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Cet article a pour but d&rsquo;expliquer la procédure a suivre pour passer d&rsquo;une conception réalisée avec EAGLE Layout Editor à un circuit imprimé en chair et en os (ou plutôt en époxy et en cuivre) réalisé avec PERCIVAL. Cet article présuppose une bonne connaissance des outils <a href="https://amaury-laurent.fr/2015/10/17/conception-dun-circuit-imprime-avec-eagle/" target="_blank" rel="noopener">EAGLE</a> et GALAAD/LANCELOT pour la CAO et l&rsquo;usinage.</p>
<h1>Introduction</h1>
<p>Rappelons rapidement le principe de fonctionnement d&rsquo;un circuit imprimé.</p>
<p>Un circuit électronique consiste en l&rsquo;interconnexion de différents <b>composants</b> (résistances, condensateurs, circuits intégrés, &#8230;). Ces connexions électriques doivent être réalisées avec un matériau conducteur d&rsquo;électricité; habituellement le cuivre. Sur un circuit imprimé, on appelle ces connexions des <b>pistes</b>. Pour tenir ces pistes, on fait appel à un substrat isolant: l&rsquo;époxy ou la bakélite (bien que d&rsquo;autres matériaux soient également utilisés). Chaque piste relie donc différents composants <i>via</i> leurs <b>broches</b>. Les broches des composants sont reliées aux pistes par des <b>pastilles</b> de cuivre: c&rsquo;est une zone plus large que la piste (afin de pouvoir y percer un trou) qui permet à l&rsquo;étain de <b>soudure</b> d&rsquo;adhérer et offre une meilleure résistance mécanique. Un circuit imprimé peut avoir une ou deux (voir plus) couches de cuivre afin d&rsquo;augmenter la complexité du circuit. Enfin, il est possible de conserver de grandes étendues de cuivre reliées à une masse d&rsquo;alimentation (ou à un autre potentiel); on parle alors de <b>plan de masse</b>. Ils ont plusieurs avantages, parmi lesquels une meilleure immunité du circuit au bruit électromagnétique, une meilleure dissipation thermique, &#8230;</p>
<figure id="attachment_882" aria-describedby="caption-attachment-882" style="width: 640px" 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/2018/05/Principe_coupe.png"><img decoding="async" class="wp-image-882 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/Principe_coupe.png" alt="Coupe d'un circuit imprimé" width="640" height="360" /></a><figcaption id="caption-attachment-882" class="wp-caption-text">Coupe d&rsquo;un circuit imprimé</figcaption></figure>
<figure id="attachment_883" aria-describedby="caption-attachment-883" style="width: 640px" 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/2018/05/Principe_dessous.png"><img decoding="async" class="wp-image-883 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:576/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/Principe_dessous.png" alt="Soudure d'une broche sur une pastille" width="640" height="360" /></a><figcaption id="caption-attachment-883" class="wp-caption-text">Soudure d&rsquo;une broche sur une pastille</figcaption></figure>
<p>La réalisation de circuits imprimés peut s&rsquo;appuyer sur deux principes différents, mais à la finalité identique : enlever le cuivre autour des pistes afin d&rsquo;isoler celles-ci les unes envers les autres. Je vais citer deux principes largement répandus:</p>
<ul>
<li>L&rsquo;attaque chimique</li>
<li>La gravure à l&rsquo;anglaise (ou gravure mécanique)</li>
</ul>
<h2>L&rsquo;attaque chimique</h2>
<p>Cette méthode ancienne et fiable repose sur l&rsquo;utilisation d&rsquo;un composé chimique capable d&rsquo;attaquer et dissoudre le cuivre.</p>
<p>On commence par prendre une plaque d&rsquo;époxy recouverte d&rsquo;une couche de cuivre et d&rsquo;une couche photosensible.</p>
<p>Pour éviter de ronger tout le cuivre du circuit imprimé, on imprime un typon (représentation physique des pistes imprimées en noir sur une feuille transparent). Ce typon est utilisé pour <a href="https://amaury-laurent.fr/2015/10/17/banc-a-insoler/" target="_blank" rel="noopener">insoler</a> le vernis photosensible. Ensuite, comme pour la photographie argentique, il faut plonger la plaque dans un bain de révélateur. A ce moment, le dessin des pistes devrait apparaitre sur la plaque. On enlève les résidus de vernis photosensible et on plonge la plaque dans un bain d&rsquo;attaque chimique (perchlorure de fer ou acide chlorique + peroxyde d&rsquo;hydrogène).</p>
<p><b>ATTENTION </b>: ces produits sont agressifs (voir très agressifs) et très salissant pour le perchlorure de fer.</p>
<p>On enlève la plaque du bain d&rsquo;attaque dès que le cuivre est complètement dissout. Il ne reste alors plus qu&rsquo;à percer les trous dans les pastilles et souder les composants.</p>
<p>Cette méthode a fait ses preuves. Elle est relativement bon marché, nécessite un peu de matériel spécifique (<a href="https://amaury-laurent.fr/2015/10/17/banc-a-insoler/" target="_blank" rel="noopener">banc à insoler</a> et bain de gravure) et de produits chimiques. Par contre, elle nécessiter une très bonne maitrise du temps (insolation, révélation, gravure) qui ne peut s&rsquo;obtenir qu&rsquo;après moult essais et échecs. En outre, elle est très salissante et s’accommode mal des espaces clos (dégagements gazeux).</p>
<h2>La gravure à l&rsquo;anglaise</h2>
<p>Cette méthode repose elle sur l&rsquo;utilisation d&rsquo;une fraiseuse pour usiner la couche de cuivre. En usinant les contours des pistes, on obtient un résultat similaire à la méthode chimique: les pistes sont isolées entre-elles. C&rsquo;est cette méthode que je vais détailler dans cet article.</p>
<h1>Du logiciel de CAO au module de FAO</h1>
<p>La Conception Assistée par Ordinateur (CAO) nous permet de concevoir un circuit électronique en toute quiétude. Le lien est fort entre le schéma et le circuit imprimé: les logiciels de CAO actuels sont capables de rendre bien des services : contrôle électriques, contrôles dimensionnels, auto-routage, &#8230;</p>
<p>Cependant, la concrétisation d&rsquo;une conception en un circuit imprimé fonctionnel reste encore une opération assez complexe. Voici ma chaine logicielle complète pour la réalisation de circuits imprimés:</p>
<figure id="attachment_885" aria-describedby="caption-attachment-885" 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/2018/05/Processus.png"><img decoding="async" class="size-medium wp-image-885" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:200/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/Processus.png" alt="Processus de réalisation" width="300" height="200" /></a><figcaption id="caption-attachment-885" class="wp-caption-text">Processus de réalisation</figcaption></figure>
<p><b>NB</b> : PERCIVAL et LANCELOT font tous les deux partie de l&rsquo;environnement de FAO <a href="https://amaury-laurent.fr/2016/04/11/fraiseuse-cnc-stepcraft-420-logiciel/" target="_blank" rel="noopener">GALAAD</a>.</p>
<p>On distingue trois grandes phases:</p>
<ol>
<li>La conception du circuit proprement dite avec un logiciel de CAO, dans mon cas, EAGLE</li>
<li>La préparation à l&rsquo;usinage avec PERCIVAL</li>
<li>L&rsquo;usinage avec LANCELOT</li>
</ol>
<p>Ces phases sont toujours reliées par un fichier descriptif du circuit imprimé : PERCIVAL attend un fichier Gerber en entrée et délivre un fichier PCB ou GCODE directement interprétable par le module d&rsquo;usinage (LANCELOT).</p>
<h2>Exportation du fichier Gerber avec EAGLE</h2>
<p><b>ASTUCES</b> :</p>
<ul>
<li>Il convient de ne pas définir de plan de masse dans EAGLE, la suite du processus en sera simplifiée. Le plan de masse sera géré par PERCIVAL.</li>
<li>L&rsquo;ajout de quatre repères en croix aux quatre coins du circuit va simplifier le réglage de la fraiseuse.</li>
</ul>
<p>EAGLE comporte un module appelé CAM (<i>Computer Aided Machining</i> &#8211; équivalent anglo-saxon de FAO). Il est accessible depuis la fenêtre d&rsquo;édition du circuit:</p>
<figure id="attachment_887" aria-describedby="caption-attachment-887" 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/2018/05/EAGLE_-_Module_CAM.png"><img decoding="async" class="wp-image-887 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:193/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/EAGLE_-_Module_CAM.png" alt="EAGLE - Module CAM" width="300" height="193" /></a><figcaption id="caption-attachment-887" class="wp-caption-text">EAGLE &#8211; Module CAM</figcaption></figure>
<p>Ce module permet d&rsquo;exporter différents types de fichiers d&rsquo;usinage. On peut symétriser le circuit imprimé, le faire tourner, &#8230; Il est également possible de choisir les couches à exporter. La configuration du module CAM est appelée un job. Il est possible d&rsquo;enregistrer ses jobs au format .cam pour les rappeler plus facilement et ne pas oublier d&rsquo;étape.</p>
<figure id="attachment_892" aria-describedby="caption-attachment-892" 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/2018/05/EAGLE_-_CAM_Processor.png"><img decoding="async" class="size-medium wp-image-892" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:233/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/EAGLE_-_CAM_Processor.png" alt="EAGLE - CAM Processor" width="300" height="233" /></a><figcaption id="caption-attachment-892" class="wp-caption-text">EAGLE &#8211; CAM Processor</figcaption></figure>
<p>Voici les grandes lignes à respecter pour l&rsquo;export vers PERCIVAL d&rsquo;un circuit simple face:</p>
<ul>
<li>Device: GERBER_RS274X</li>
<li>Mirror</li>
<li>pos. Coord</li>
<li>Optimize</li>
<li>Layers 16, 17, 18:
<ul>
<li>Bottom</li>
<li>Pads</li>
<li>Vias</li>
</ul>
</li>
</ul>
<p>Par extension, voici les grandes lignes à respecter pour l&rsquo;export vers PERCIVAL de la face supérieure d&rsquo;un circuit double face:</p>
<ul>
<li>Device: GERBER_RS274X</li>
<li>pos. Coord</li>
<li>Optimize</li>
<li>Layers 1, 17, 18:
<ul>
<li>Top</li>
<li>Pads</li>
<li>Vias</li>
</ul>
</li>
</ul>
<p>Voici les deux fichiers .cam que j&rsquo;utilise:</p>
<ul>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2018/05/percival_bottom.cam" download="">percival_bottom.cam</a></li>
<li><a href="https://amaury-laurent.fr/wp-content/uploads/2018/05/percival_top.cam" download="">percival_top.cam</a></li>
</ul>
<p>Pour générer le fichier Gerber, cliquer simplement sur « Process Job » et le tour est joué.</p>
<h2>Importation du fichier Gerber dans PERCIVAL</h2>
<p>Pour importer le fichier Gerber dans PERCIVAL, il faut passer par le menu <i>Fichier</i> -&gt; <i>Ouvrir</i> -&gt;<i> Nouveau Circuit (Ctrl + O)</i>. Pointer ensuite sur le fichier .grb généré par EAGLE. Une incompatibilité du format Gerber généré par EAGLE va causer l&rsquo;apparition de ce message d&rsquo;erreur:</p>
<figure id="attachment_894" aria-describedby="caption-attachment-894" 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/2018/05/PERCIVAL_Error.png"><img decoding="async" class="size-medium wp-image-894" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:122/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_Error.png" alt="PERCIVAL - Erreur d'importation" width="300" height="122" /></a><figcaption id="caption-attachment-894" class="wp-caption-text">PERCIVAL &#8211; Erreur d&rsquo;importation</figcaption></figure>
<p>Rien de grave cependant: PERCIVAL nous informe simplement que le fichier Gerber ne contient pas les définitions des pastilles. D&rsquo;une certaine façon, cela nous arrange puisque nous allons reconfigurer toutes les pastilles du circuit pour optimiser l&rsquo;usinage. Après validation du message, un assistant de configuration des pastilles s&rsquo;ouvre:</p>
<figure id="attachment_895" aria-describedby="caption-attachment-895" style="width: 640px" 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/2018/05/PERCIVAL_-_Configuration_des_pastilles.png"><img decoding="async" class="wp-image-895 size-large" src="https://ml9zfxsqktal.i.optimole.com/w:1024/h:269/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_-_Configuration_des_pastilles.png" alt="PERCIVAL - Configuration des pastilles" width="640" height="168" /></a><figcaption id="caption-attachment-895" class="wp-caption-text">PERCIVAL &#8211; Configuration des pastilles</figcaption></figure>
<p>Les pastilles concernées s&rsquo;allument en rouge sur le circuit. Il est alors possible de modifier leur forme, leurs dimensions, le diamètre de perçage, &#8230;</p>
<p>Il faut passer en revue toutes les pastilles de la carte (en navigant avec les boutons « <b>&lt;</b> » et « <b>&gt;</b>« ) pour définir tous ces paramètres. Il est facile de voir quelle taille de pastille va causer un court-circuit ou bien sera trop petite par rapport au diamètre de perçage.</p>
<p>Une fois cette tâche effectuée, on se rend compte que certaines pastilles n&rsquo;ont pas été traitées:</p>
<figure id="attachment_896" aria-describedby="caption-attachment-896" 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/2018/05/PERCIVAL_-_Pastilles_non_traitees.png"><img decoding="async" class="size-medium wp-image-896" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:167/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_-_Pastilles_non_traitees.png" alt="PERCIVAL - Pastilles non traitées" width="300" height="167" /></a><figcaption id="caption-attachment-896" class="wp-caption-text">PERCIVAL &#8211; Pastilles non traitées</figcaption></figure>
<p>Le problème provient de la manière utilisée par EAGLE pour exporter les pastilles oblongues: elles sont définies comme des pistes dans le fichier. Pour convertir ces « pistes » en pastille, il faut simplement faire un clic droit sur l&rsquo;une d&rsquo;elle et choisir définir comme pastille. PERCIVAL propose alors gentiment de transformer toutes les autres pastilles équivalentes. A vous de voir si PERCIVAL ne fait pas un excès de zèle en convertissant en pastille des pistes bien réelles.</p>
<p>Une fois les torts rétablis et les fausses pistes transformées en pastilles, il convient de refaire l&rsquo;étape précédente en rouvrant l&rsquo;assistant de configuration de pastilles (<i>clic droit</i> sur la pastille a configurer -&gt; <i>Editer les pastilles identiques</i>).</p>
<h2>Gestion des plans de masse</h2>
<p>Avec la gravure à l&rsquo;anglaise, le plan de masse est quasiment intrinsèque. En effet, à moins de faire en sorte que la fraiseuse retire tout le cuivre inutile, celle-ci na va faire qu&rsquo;un simple détourage. Il va donc demeurer de grandes zones cuivrées autour des pistes. Il convient alors de les relier à la masse. Cette opération s&rsquo;effectue dans PERCIVAL et requiert un peu d&rsquo;attention. En effet, il faut identifier sur le circuit quelles sont les broches et pistes reliées à la masse. Ensuite, il faudra passer chaque piste une par une en faisant un <i>Clic droit</i> -&gt; <i>Définir comme plan-masse.</i> Les pistes appartenant au plan de masse sont symbolisées en marron.</p>
<p>Il est également possible de convertir les pastilles reliées au plan de masse en pastilles thermiques. Cela va grandement simplifier le repérage et la soudure desdites pastilles. Pour ce faire, activer l&rsquo;outil Pastille thermique (en choisissant l&rsquo;orientation de la pastille) et cliquer les pastilles à convertir.</p>
<figure id="attachment_899" aria-describedby="caption-attachment-899" style="width: 177px" 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/2018/05/PERCIVAL_Pastille_thermique.png"><img decoding="async" class="size-full wp-image-899" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_Pastille_thermique.png" alt="PERCIVAL - L'outil Pastille thermique" width="177" height="88" /></a><figcaption id="caption-attachment-899" class="wp-caption-text">PERCIVAL &#8211; L&rsquo;outil Pastille thermique</figcaption></figure>
<p>Cette fois-ci quand PERCIVAL propose de convertir les pastilles identiques, il est recommandé de ne pas le faire. Une croix apparait en légère surimpression sur les pastilles thermiques.</p>
<h2>Réglage de l&rsquo;origine du circuit</h2>
<p>Pour usiner le circuit imprimé, le module d&rsquo;usinage va nécessiter la prise d&rsquo;origine de la pièce. Cette origine sera d&rsquo;autant plus simple à régler si elle se situe sur le bord de la carte. Dans PERCIVAL, il est possible de positionner deux croix: une rouge et une bleue.</p>
<figure id="attachment_900" aria-describedby="caption-attachment-900" style="width: 223px" 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/2018/05/PERCIVAL_-_Croix.png"><img decoding="async" class="size-full wp-image-900" src="https://ml9zfxsqktal.i.optimole.com/w:auto/h:auto/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_-_Croix.png" alt="PERCIVAL - Positionnement des Croix" width="223" height="89" /></a><figcaption id="caption-attachment-900" class="wp-caption-text">PERCIVAL &#8211; Positionnement des Croix</figcaption></figure>
<p>Ces croix pourront servir d&rsquo;origine pièce au module d&rsquo;usinage. Pour positionner précisément ces croix, il convient au préalable d&rsquo;avoir prévu des repères dans EAGLE (une petite croix dans chaque angle dessinée avec des pistes sur chacune des faces à usiner). Une fois l&rsquo;outil activé en mode « Pointage manuel », il suffit de cliquer sur l&rsquo;extrémité d&rsquo;une piste ou une pastille pour y positionner la croix.</p>
<figure id="attachment_901" aria-describedby="caption-attachment-901" 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/2018/05/PERCIVAL_-_Resultat_avant_detourage.png"><img decoding="async" class="wp-image-901 size-medium" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:167/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_-_Resultat_avant_detourage.png" alt="PERCIVAL - Résultat avant isolation" width="300" height="167" /></a><figcaption id="caption-attachment-901" class="wp-caption-text">PERCIVAL &#8211; Résultat avant isolation</figcaption></figure>
<p>Le circuit est maintenant prêt pour le calcul des contours d&rsquo;isolation.</p>
<h2>Calcul des contours d&rsquo;isolation</h2>
<p>Les contours d&rsquo;isolation sont les chemins que suivra la fraise afin d&rsquo;isoler électriquement les pistes du circuit. Le calcul des contours dépend principalement de deux facteurs:</p>
<ul>
<li>La forme de l&rsquo;outil</li>
<li>La largeur d&rsquo;isolation entre la piste et le plan de masse</li>
</ul>
<p>Le premier facteur se règle dans le menu <i>Paramètres</i> -&gt; <i>Bibliothèque d&rsquo;outils</i>.</p>
<figure id="attachment_902" aria-describedby="caption-attachment-902" 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/2018/05/PERCIVAL_-_Bibliotheque_d_outils.png"><img decoding="async" class="size-medium wp-image-902" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:130/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_-_Bibliotheque_d_outils.png" alt="PERCIVAL - Bibliothèque d'outils" width="300" height="130" /></a><figcaption id="caption-attachment-902" class="wp-caption-text">PERCIVAL &#8211; Bibliothèque d&rsquo;outils</figcaption></figure>
<p>Ce menu permet de déclarer les différents outils en votre disposition. Ainsi, PERCIVAL adapteras les calculs d&rsquo;isolation et de perçage à la forme et au diamètre des outils disponibles. En outre, le module d&rsquo;usinage sera à même de vous demander d&rsquo;installer le bon outil avant chaque phase de gravure ou de perçage.</p>
<p>J&rsquo;utilise personnellement ces outils:</p>
<ul>
<li>Un stylet conique à 60° pour l&rsquo;isolation (soie de 3.17mm)</li>
<li>Un foret de 0.8mm pour les perçages (soie de 3.17mm)</li>
<li>Une fraise à rainurer de 2mm pour le détourage</li>
</ul>
<p>Il est possible de remplir le nombre de dents et la vitesse de la broche pour chaque outil. PERCIVAL calcul ainsi les vitesses avance optimales pour l&rsquo;usinage.</p>
<p>Pour calculer les contours d&rsquo;isolation, il faut utiliser le menu <i>Usinage</i> -&gt; <i>Contours d&rsquo;isolation</i> -&gt; <i>Calculer les contours.</i> Il est possible de choisir le nombre de passes à réaliser autour des pistes et des pastilles. Plus ce nombre est élevé, plus large sera le contour d&rsquo;isolation, mais plus long sera l&rsquo;usinage. Pour ma part, je me contente de deux contours successifs et d&rsquo;un contour supplémentaire autour des pastilles. Quand le calcul est terminé, PERCIVAL affiche un rendu du résultat final. Les contours affichés en rouges sont ceux qui ont été « forcés » par le logiciel, les pastilles ou pistes adjacentes étant trop proches.</p>
<figure id="attachment_903" aria-describedby="caption-attachment-903" 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/2018/05/PERCIVAL_-_Isolation_terminee.png"><img decoding="async" class="size-medium wp-image-903" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:167/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/PERCIVAL_-_Isolation_terminee.png" alt="PERCIVAL - Isolation terminée" width="300" height="167" /></a><figcaption id="caption-attachment-903" class="wp-caption-text">PERCIVAL &#8211; Isolation terminée</figcaption></figure>
<p>Il est également possible de gérer le détourage de la carte (découpe du circuit à la fraise) en ajoutant ou non pontets de maintien.</p>
<h1>Usinage du circuit</h1>
<h2>Positionner la carte à usiner</h2>
<p>Pour fixer la carte à usiner sur la table de la fraiseuse, j&rsquo;utilise pour ma part du Scotch double faces transparent « extra-fort »:</p>
<p><a href="https://www.leroymerlin.fr/v3/p/produits/adhesif-scotch-fixation-double-face-interieur-exterieur-l1-5mxl19mm-transparent-e1400097015" target="_blank" rel="noopener">https://www.leroymerlin.fr/v3/p/produits/adhesif-scotch-fixation-double-face-interieur-exterieur-l1-5mxl19mm-transparent-e1400097015</a></p>
<p>Il présente l&rsquo;avantage d&rsquo;avoir une épaisseur suffisante pour ne pas usiner la table de la fraiseuse. Il est en outre assez simple à décoller.</p>
<p>Un petit carré d&rsquo;adhésif dans chaque coin et un au centre de la carte suffisent à maintenir le circuit en place pendant tout l&rsquo;usinage.</p>
<h2>Lancer l&rsquo;usinage</h2>
<p>L&rsquo;usinage du circuit n&rsquo;est alors plus qu&rsquo;une « simple » formalité. Il suffit de choisir le menu <i>Usinage</i> -&gt; <i>Fraisage</i>, et de choisir <i>Chainer automatiquement au module d&rsquo;usinage</i>. Le fichier GCODE est automatiquement généré et passé à LANCELOT pour la gravure.</p>
<p><b>ATTENTION</b> : Si le circuit a été inversé à la génération du fichier GERBER (mirror activé pour la face du dessous dans EAGLE), il convient de ne pas activer l&rsquo;inversion horizontale à ce moment du processus.</p>
<p>LANCELOT est lancé automatiquement.</p>
<figure id="attachment_904" aria-describedby="caption-attachment-904" 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/2018/05/LANCELOT_-_Configuration.png"><img decoding="async" class="size-medium wp-image-904" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:143/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/LANCELOT_-_Configuration.png" alt="LANCELOT - Configuration" width="300" height="143" /></a><figcaption id="caption-attachment-904" class="wp-caption-text">LANCELOT &#8211; Configuration</figcaption></figure>
<p>La première page permet de configurer l&rsquo;usinage. Le tableau en haut à gauche récapitule les différentes phases de la réalisation. Il est possible de les activer (entouré en vert) ou de les désactiver (barré de rouge) à volonté. Chaque phase est associée à un outil et repérée par le numéro de l&rsquo;outil dans le magasin. Il est également possible de surcharger les paramètres d&rsquo;usinage (profondeur des passes, vitesse d&rsquo;avance, &#8230;). Enfin, il est possible de tourner ou symétriser le circuit, au cas où une erreur se serait glissé dans le processus précédent.</p>
<figure id="attachment_905" aria-describedby="caption-attachment-905" 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/2018/05/LANCELOT_-_Pilotage.png"><img decoding="async" class="size-medium wp-image-905" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:143/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/LANCELOT_-_Pilotage.png" alt="LANCELOT - Pilotage" width="300" height="143" /></a><figcaption id="caption-attachment-905" class="wp-caption-text">LANCELOT &#8211; Pilotage</figcaption></figure>
<p>La deuxième page permet de positionner la carte sur la table d&rsquo;usinage. Il faut prendre l&rsquo;origine de la carte (croix rouge, croix bleue ou bien un coin du circuit) en X et Y. Pour le réglage de la hauteur d&rsquo;outil, deux méthodes sont disponibles:</p>
<ul>
<li>La machine est équipée d&rsquo;un capteur de hauteur d&rsquo;outil mobile</li>
<li>Le positionnement de l&rsquo;outil à fleur de la carte</li>
</ul>
<p>Pour la première méthode, il convient de se référer à la notice d&rsquo;utilisation du logiciel LANCELOT. Pour la seconde, je préconise une astuce à base d&rsquo;Ohmmètre. <b>ATTENTION</b> : toute cette manipulation devra être effectuée <b>broche hors tension</b>, vous allez entrer en contact avec l&rsquo;outil.</p>
<ul>
<li>Installer l&rsquo;outil dans la broche</li>
<li>Amener l&rsquo;outil à quelques millimètres de la surface de la carte</li>
<li>Passer le pilotage en mode 1mm ou 1/10mm selon la distance entre l&rsquo;outil et la carte</li>
<li>Mettre l&rsquo;Ohmmètre en mode continuité (bip quand les pointes de touche se touchent)</li>
<li>Mettre une pointe sur la carte (partie cuivrée) l&rsquo;autre sur le mandrin de la broche (ou directement l&rsquo;outil si le mandrin est en plastique)</li>
<li>Descendre l&rsquo;outil progressivement et doucement jusqu&rsquo;au bip de l&rsquo;Ohmmètre</li>
<li>Cliquer sur Z &#8211; ok</li>
</ul>
<p>ATTENTION : avec un foret de 0.8mm, cette manipulation peut s&rsquo;avérer destructrice pour l&rsquo;outil sir la vitesse de descente est trop élevée.</p>
<p>Une fois l&rsquo;origine réglée, il est alors possible de lancer l&rsquo;Usinage Automatique (ou de faire une simulation avant d&rsquo;ouvrir les hostilités).</p>
<figure id="attachment_906" aria-describedby="caption-attachment-906" 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/2018/05/LANCELOT_-_Usonage_automatique.png"><img decoding="async" class="size-medium wp-image-906" src="https://ml9zfxsqktal.i.optimole.com/w:300/h:143/q:mauto/f:best/https://amaury-laurent.fr/wp-content/uploads/2018/05/LANCELOT_-_Usonage_automatique.png" alt="LANCELOT - Usinage automatique" width="300" height="143" /></a><figcaption id="caption-attachment-906" class="wp-caption-text">LANCELOT &#8211; Usinage automatique</figcaption></figure>
<p>Si tout fonctionne comme prévu, LANCELOT devrait aller au bout de la première phase avant de demander un changement d&rsquo;outil. Il convient alors de refaire la prise d&rsquo;origine en Z.</p>
<p>Voici le résultat pour un circuit simple face basé autour d&rsquo;un PIC18F4550 :</p>
<p>[metaslider id=910]</p>
<p>Voici deux petites vidéos de l&rsquo;outil en action (Attention, le volume sonore est un peu élevé&#8230;):</p>
<p><iframe width="640" height="360"  src="about:blank" data-opt-src="https://www.youtube.com/embed/_bYgNou0XTc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p><iframe width="640" height="360"  src="about:blank" data-opt-src="https://www.youtube.com/embed/rnrIA0OaIaI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h1>Conclusion</h1>
<p>Avec le bon outillage, il est aisé de passer d&rsquo;une conception virtuelle à un circuit bien réel. Il est tout a fait normal d&rsquo;éprouver une certaine appréhension lors des premiers mouvement de la broche. J&rsquo;ai cassé quelques outils et gâché un certain nombre de cartes avant de pleinement prendre en main les différents modules logiciels du processus. Il est important d&rsquo;être méthodique de bout en bout. Le processus que je présente ici n&rsquo;est bien sûr pas parole d&rsquo;évangiles, cependant, il fonctionne à merveille chez moi.</p>
<p>Bonnes réalisations !</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/exporter-un-circuit-imprime-depuis-eagle-vers-galaad-percival/">Exporter un Circuit Imprimé depuis EAGLE vers GALAAD/PERCIVAL</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/exporter-un-circuit-imprime-depuis-eagle-vers-galaad-percival/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Récepteur radio-modélisme sur USB</title>
		<link>https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/</link>
					<comments>https://amaury-laurent.fr/recepteur-radio-modelisme-sur-usb/#comments</comments>
		
		<dc:creator><![CDATA[Amaury LAURENT]]></dc:creator>
		<pubDate>Tue, 09 May 2017 21:24:57 +0000</pubDate>
				<category><![CDATA[Microcontrôleur]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Réalisation]]></category>
		<guid isPermaLink="false">http://amaury-laurent.fr/?p=721</guid>

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

					<description><![CDATA[<p>Ou comment passer quatre heures de temps libre, quelques mètres de fil de cuivre et du bon temps ! Avertissements: Cette réalisation a pour but de générer de hautes tensions. Il vous revient de prendre toutes les précautions nécessaires pour ne pas vous mettre en danger ou endommager vos appareils électroniques! Historique Comme son nom [&#8230;]</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/mini-bobine-de-tesla/">Mini Bobine de Tesla</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 passer quatre heures de temps libre, quelques mètres de fil de cuivre et du bon temps !</h1>
<h2 style="text-align: left;"><strong><span style="color: #ff0000;">Avertissements:</span></strong></h2>
<p style="text-align: left;">Cette réalisation a pour but de générer de hautes tensions. Il vous revient de prendre toutes les précautions nécessaires pour ne pas vous mettre en danger ou endommager vos appareils électroniques!</p>
<h2 style="text-align: left;">Historique</h2>
<p style="text-align: left;">Comme son nom l&rsquo;indique, le résonateur Tesla est l&rsquo;une des inventions du savant Serbe Nikola Tesla. Né le 10 juillet 1856 à Smiljan, Nikola Tesla entre à l&rsquo;école Polytechnique de Graz en 1875. Il y assimilera deux années d&rsquo;études en un an seulement avant de quitter l&rsquo;université faute d&rsquo;argent. Il commence son travail d&rsquo;ingénieur en 1881 pour l&rsquo;Office du télégraphe à Budapest. À l&rsquo;avènement du téléphone, il est promu chef électricien puis ingénieur-chef de la compagnie. On lui devrait le premier haut-parleur. En 1882, il vient travailler à Paris pour la société Continental Edison où il finit de mettre au point le premier moteur à induction. Il expérimente les résonateurs hautes fréquences entre 1899 et 1900 dans le but de créer une tour de télécommunications. Ce sont les fameuses bobines de Tesla.</p>
<p>Source: <a href="http://fr.wikipedia.org/wiki/Nikola_Tesla" target="_blank" rel="noopener">Wikipedia</a></p>
<h2 style="text-align: left;">Principe de fonctionnement du résonateur Tesla</h2>
<p style="text-align: left;">L&rsquo;objectif du résonateur Tesla est de produire des champs électriques intenses à haute fréquence. L&rsquo;idée de Tesla repose sur deux principes fondamentaux:</p>
<ul>
<li style="text-align: left;">L&rsquo;utilisation d&rsquo;un transformateur</li>
<li style="text-align: left;">L&rsquo;utilisation de la résonance</li>
</ul>
<p>Un transformateur électrique est chargé d&rsquo;augmenter ou d&rsquo;abaisser une tension électrique sinusoïdale en utilisant le couplage magnétique de deux bobines aux nombres de spires différents. Le rapport de transformation est alors donné par le rapport du nombre de spires de la bobine secondaire sur le nombre de spires de la bobine primaire. Le résonateur Tesla est un transformateur élévateur de tension comportant très peu de spires au primaire (une dizaine) et beaucoup plus au secondaire (plusieurs milliers).<br />
L’idée de génie de Tesla fut d&rsquo;utiliser ce transformateur à sa fréquence de résonance. Pour ce faire, il place un condensateur en série avec le primaire et un autre en série avec le secondaire. Les valeurs des condensateurs sont choisies pour que les deux circuits LC résonnent à la même fréquence.<br />
La haute tension est alors produite par la décharge répétitive du condensateur dans la bobine primaire. Le transformateur entre en résonance (autour de 500kHz) et un très haut potentiel électrique apparait sur le condensateur secondaire.</p>
<h2>Schéma d&rsquo;un résonateur Tesla</h2>
<figure id="attachment_475" aria-describedby="caption-attachment-475" style="width: 300px" class="wp-caption aligncenter"><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/schema.jpg" target="_blank" rel="noopener"><img decoding="async" class="wp-image-475 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/schema-300x153.jpg" alt="Schéma de principe d'un résonateur Tesla" width="300" height="153" /></a><figcaption id="caption-attachment-475" class="wp-caption-text">Schéma de principe d&rsquo;un résonateur Tesla</figcaption></figure>
<p>On retrouve le condensateur primaire, les bobines primaire et secondaire, ainsi que le condensateur secondaire qui est en réalité soit un tore soit une sphère métallique. Un interrupteur est chargé de connecter périodiquement le condensateur primaire à la bobine primaire. Quand l&rsquo;interrupteur conduit, le condensateur se décharge dans la bobine et le circuit primaire entre en résonance. Quand l&rsquo;interrupteur est ouvert, le condensateur se charge à la tension d&rsquo;alimentation du résonateur.</p>
<h2>Particularité d&rsquo;un résonateur à éclateur solide</h2>
<p>Les bobines de Tesla conventionnelles sont alimentées en haute tension alternative (de l&rsquo;ordre de 10kV). L&rsquo;interrupteur du primaire doit donc être capable de commuter de très forts courants sous une tension de 10kV à la fréquence d&rsquo;alimentation de la Tesla (50 Hz en France). Pour réaliser ma mini Tesla, j&rsquo;ai choisi d&rsquo;utiliser une alimentation 12V continue et de mettre un transistor MOS comme interrupteur primaire. Ceci présente plusieurs avantages, comme notamment la possibilité de régler la fréquence de commutation du MOS en jouant sur la fréquence du signal de grille.</p>
<h2>Réalisation</h2>
<p>La première chose à faire est de bobiner le secondaire. Assurez-vous au préalable d&rsquo;avoir tout ce qu&rsquo;il faut&#8230; Pour ma bobine secondaire, j&rsquo;ai bobiné du fil de cuivre de 0.125mm de diamètre sur un tube de PVC de 32mm sur une longueur d&rsquo;environ 10cm (le fil a cassé avant que j&rsquo;atteigne mon objectif de 15cm&#8230;). Qu&rsquo;à cela ne tienne, je poursuis ma réalisation!!!<br />
Pensez bien à laisser suffisamment de mous au fil de cuivre de chaque côté de la bobine pour permettre les connexions électriques. Ensuite: la bobine primaire. Pour celle-là, rien de plus simple: quelques tours de fils de cuivre (celui que vous avez, pour moi du 0.75 mm²) sur un tronçon de PVC de plus grand diamètre que celui du secondaire et voilà! Ensuite, le condensateur secondaire. Le mien est une balle de ping-pong soigneusement recouverte de scotch aluminium.<br />
Enfin: le circuit électronique de commande. Pour simplifier la réalisation, je génère la commande du MOS avec mon GBF, mais rien n&#8217;empêche de construire un petit oscillateur avec un <a href="http://fr.wikipedia.org/wiki/NE555" target="_blank" rel="noopener">555 </a>pour rendre votre réalisation parfaitement mobile. L&rsquo;alimentation 12Vdc est tirée d&rsquo;un vieille alimentation de PC (et alors 😉 ). Attention toutefois à ce que votre alimentation soit assez tolérante aux retours de hautes fréquences et aux courts-circuits! Le schéma n&rsquo;a en sois rien de compliqué:</p>
<p>On retrouve le condensateur primaire connecté directement à la source, le PMOS intercalé entre le condensateur et la bobine du secondaire. Attention: le PMOS conduit quand la grille à un potentiel inférieur à Vcc &#8211; 5V et il est bloqué quand le potentiel de grille est égal à Vcc. Si vous avez un NMOS sous la main, n&rsquo;hésitez surtout pas à modifier le schéma!</p>
<p><a href="http://vps200917.ovh.net/wp-content/uploads/2016/02/tesla.jpg" target="_blank" rel="noopener"><img decoding="async" class="aligncenter wp-image-476 size-medium" src="http://vps200917.ovh.net/wp-content/uploads/2016/02/tesla-300x188.jpg" alt="tesla" width="300" height="188" /></a></p>
<h2>Les premiers essais</h2>
<p>Après avoir relié l&rsquo;alimentation, le signal de commande du MOS et relié le bas de la bobine secondaire à la masse, il ne reste plus qu&rsquo;à mettre en route! Selon la fréquence du signal de commande, on peut isoler deux modes de fonctionnement:</p>
<p>Fréquences basses (de l&rsquo;ordre du kHz): le résonateur fonctionne comme Tesla l&rsquo;avait prévu: la capacité du primaire entre en résonance avec la bobine. J&rsquo;ai réussi à produire des étincelles d&rsquo;un petit millimètre. Assez décevant me direz-vous, mais ces fréquences sont audibles et l&rsquo;on peut faire chanter la Tesla!</p>
<p>Fréquences élevées (environ 750 kHz): la capacité n&rsquo;a plus le temps de se charger ou de se décharger et la bobine primaire entre directement en résonance avec la tension hachée fournie par le MOS. Cette fois, les étincelles atteignent facilement le centimètre.</p>
<p>Pour trouver la fréquence de résonances, il y a deux écoles: à l&rsquo;oscilloscope (méthode « propre ») ou au tube fluo (méthode « amusante »). A l&rsquo;oscilloscope, il suffit laisser la sonde posée négligemment sur le plan de travail à proximité de la Tesla pour observer les signaux HF rayonnés par la Tesla. Avec un tube fluo, c&rsquo;est le même principe: il faut saisir le tube par une électrode et approcher l&rsquo;autre de la Tesla. Le fluo devrait s&rsquo;allumer. Ensuite, que vous utilisiez le fluo ou l&rsquo;oscilloscope, il faut régler la fréquence de commande du MOS pour obtenir la plus grande amplitude de signal (à l&rsquo;oscilloscope) ou la plus forte luminosité (au fluo).</p>
<p>NB: si vous n&rsquo;avez pas de fluo, une ampoule à économie d&rsquo;énergie (fluocompacte) ou même une simple LED feront l&rsquo;affaire.</p>
<p>[metaslider id=482]</p>
<p>On peut remarquer la taille impressionnante du dissipateur thermique du MOS. Tous d&rsquo;abord, je n&rsquo;en avais pas d&rsquo;autre (eh oui, ça joue&#8230;), ensuite, à basse fréquence, le courant circulant dans le MOS peut provoquer un échauffement très intense (mon premier MOS mourut ainsi dans d’atroces souffrances). Donc, ne négligez pas le refroidissement du MOS: un accident est vite arrivé!</p>
<p>Cet article <a rel="nofollow" href="https://amaury-laurent.fr/mini-bobine-de-tesla/">Mini Bobine de Tesla</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/mini-bobine-de-tesla/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>
	</channel>
</rss>
