Retour Suite
sylvainmahe.site LE SITE de Sylvain Mahé contact@sylvainmahe.site
Article : Sylvain Mahé contact@sylvainmahe.site Le code source du site Dans cette philosophie de partage de mon travail avec le plus grand nombre, tout est libre de droits d'auteur (voir dans la section "Licence officielle" en page d'accueil), ainsi les fichiers sources (programmation notamment) sont tous ouverts et modifiables (open source). C'est pourquoi dans cette démarche je vous propose ici s'il en était besoin, l'intégralité du code source de ce présent site. Fichier style.css : html { font-family: sans-serif; } body { margin: 0px; background-color: #ffffff; } back { z-index: 1; display: inline-block; position: fixed; margin-left: 192px; margin-top: 60px; padding: 6px; background-color: #ac3626; border-top-right-radius: 8px; border-bottom-right-radius: 8px; font-size: 12px; text-align: right; color: #ebffff; } next { z-index: 1; display: inline-block; position: fixed; margin-left: 192px; margin-top: 90px; padding: 6px; background-color: #ac3626; border-top-right-radius: 8px; border-bottom-right-radius: 8px; font-size: 12px; text-align: right; color: #ebffff; } header { z-index: 2; display: inline-block; position: fixed; width: 128px; height: 100%; padding: 32px; background-image: url("image/background.jpg"); background-position: left top; background-repeat: repeat; border-top-right-radius: 32px; box-shadow: 0px 0px 2px #404040; } header dualine { display: inline-block; position: relative; width: 128px; height: 1px; margin-top: 16px; border-width: 1px; border-style: solid; border-color: #808080; border-left: none; border-right: none; } header title { display: inline-block; position: relative; width: 128px; font-size: 11px; color: #ebffff; margin-top: 16px; } header subtitle { display: inline-block; position: relative; width: 128px; margin-top: 16px; font-size: 16px; color: #ebffff; } header text { display: inline-block; position: relative; width: 128px; margin-top: 2px; font-size: 12px; color: #ebffff; } header contact { display: inline-block; position: relative; width: 128px; margin-top: 4px; font-size: 9px; color: #ebffff; } header logo { display: inline-block; position: relative; width: 128px; height: 92px; } header sublogo { display: inline-block; position: relative; width: 48px; height: 40px; margin-top: 16px; } page { position: absolute; width: 768px; margin-top: 8px; padding-left: 256px; padding-right: 64px; padding-top: 32px; padding-bottom: 32px; border-top-right-radius: 64px; box-shadow: 0px 0px 64px #e0e0e0; } page underline { display: inline-block; position: relative; width: 768px; height: 1px; background-color: #dddddd; } page line { display: inline-block; position: relative; width: 768px; height: 1px; margin-top: 18px; background-color: #dddddd; } page author { display: inline-block; position: relative; float: left; width: 384px; font-size: 14px; color: #b0b8c0; } page contact { display: inline-block; position: relative; float: right; width: 384px; font-size: 10px; color: #b0b8c0; text-align: right; } page title { display: inline-block; position: relative; width: 768px; margin-top: 54px; font-size: 28px; color: #2c3e50; letter-spacing: 2px; } page text { display: inline-block; position: relative; width: 768px; margin-top: 18px; font-size: 16px; color: #496479; } page text bold { font-weight: bold; } page text radioactive { display: inline-block; position: relative; width: 16px; height: 16px; background-image: url("image/radioactive.png"); background-position: left top; } page code { display: inline-block; position: relative; width: 704px; margin-top: 18px; padding: 31px; border-width: 1px; border-style: solid; border-color: #dddddd; border-radius: 2px; background-color: #f5f5f5; font-size: 14px; color: #000000; white-space: pre; overflow-x: auto; } page code green { font-weight: bold; color: #2e8b57; } page code red { font-weight: bold; color: #b32a2a; } page code pink { color: #ff1bff; } page code purple { color: #7820f0; } page code blue { color: #1900ff; } page quote { display: inline-block; position: relative; width: 704px; margin-top: 18px; padding-left: 26px; padding-right: 32px; padding-top: 18px; padding-bottom: 18px; border-width: 6px; border-style: solid; border-color: #358ccb; border-radius: 2px; border-right: none; border-top: none; border-bottom: none; background-color: #f5f5f5; font-size: 18px; font-style: italic; color: #496479; } page quote bold { font-weight: bold; } page caution { display: inline-block; position: relative; width: 704px; margin-top: 18px; padding-left: 26px; padding-right: 32px; padding-top: 18px; padding-bottom: 18px; border-width: 6px; border-style: solid; border-color: #e74c3c; border-radius: 2px; border-right: none; border-top: none; border-bottom: none; background-color: #f5f5f5; font-size: 18px; font-style: italic; color: #496479; } page caution bold { font-weight: bold; } page img { display: inline-block; position: relative; float: left; width: 328px; height: 219px; margin-top: 18px; margin-left: 16px; padding: 15px; border-width: 1px; border-style: solid; border-color: #dddddd; border-radius: 2px; background-color: #f5f5f5; } page video { display: inline-block; position: relative; width: 704px; height: 352px; margin-top: 18px; margin-left: 16px; padding: 15px; border-width: 1px; border-style: solid; border-color: #dddddd; border-radius: 2px; background-color: #f5f5f5; } page download { display: inline-block; position: relative; margin-top: 6px; padding-left: 26px; padding-right: 32px; padding-top: 10px; padding-bottom: 10px; border-width: 6px; border-style: solid; border-color: #dddddd; border-radius: 2px; border-right: none; border-top: none; border-bottom: none; background-color: #f5f5f5; font-size: 16px; color: #e74c3c; text-decoration: underline; } page download bold { font-weight: bold; } page footer { display: inline-block; position: relative; float: right; width: 768px; margin-top: 64px; font-size: 10px; color: #b0b8c0; text-align: right; } Fichier complementaryToolOfModule.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#complementaryToolOfModule"><back>Retour</back></a> <a href="exampleGpioRead.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Les outils complémentaires de MODULE</title> <underline></underline> <text>En programmation C++ pour les microcontrôleurs de marque Microchip comme l'ATmega48P, l'ATmega88P, l'ATmega168P, l'ATmega328P, l'ATmega164P, l'ATmega324P, l'ATmega644P ou l'ATmega1284P dont il est question ici, des outils de compilation et de programmation de la puce performants et standards existent.</text> <text>Ces outils sont disponibles pour les systèmes <bold>Linux</bold> (c'est mon cas), ou <bold>Windows</bold>. Pour Mac OS il faudra effectuer des recherches car je ne connais pas ce système, mais Mac OS étant une base Unix je pense que cela ne doit pas beaucoup différer de Linux.</text> <text><bold>Outils pour Linux :</bold> <br/>Vous devez installer les paquets <bold>gcc-avr</bold>, <bold>avr-libc</bold>, <bold>binutils</bold> et <bold>avrdude</bold> pour programmer le microcontrôleur installé sur mes automates programmables MODULABLE M20 ou M32.</text> <text>Pour ma part j'utilise le système d'exploitation Linux Ubuntu (qui est une distribution Linux largement utilisée de nos jours), en exemple voici la ligne de commande à écrire dans le terminal pour télécharger et installer les paquets sur Linux Ubuntu :</text> <code>sudo apt-get install gcc-avr && sudo apt-get install avr-libc && sudo apt-get install binutils && sudo apt-get install avrdude</code> <text><bold>Outils pour Windows :</bold> <br/>Vous devez télécharger et installer un programme qui se nomme <bold>WinAVR</bold> pour programmer le microcontrôleur, ce programme contient les mêmes outils que sur Linux mais ici en version pour Windows :</text> <a href="http://winavr.sourceforge.net/download.html"><download>Site internet de <bold>WinAVR</bold></download></a> <title>Le programmateur :</title> <underline></underline> <text>Le programmateur est une petite carte qui fait l'interface entre votre ordinateur personnel et le microcontrôleur (implanté sur l'automate programmable), ce qui permet d'envoyer votre programme dans cette puce. Vous pouvez fabriquer un programmateur vous même, ou utiliser une carte toute faite. Pour ma part j'ai essayé les deux.</text> <a href="photo/dsc02494.jpg"><img src="thumbnail/dsc02494.jpg"></img></a> <text>Je vous conseille d'utiliser le programmateur <bold>USBasp</bold> qui fonctionne à merveille, disponible à l'achat ici :</text> <a href="http://www.fischl.de/usbasp/"><download>Site internet de l'<bold>USBasp</bold></download></a> <quote>Le programmateur <bold>USBasp</bold> est comme son nom l'indique équipé d'un <bold>port USB</bold>, à connecter directement à un port USB de votre ordinateur personnel, et à l'autre extrémité d'un <bold>port ISP</bold> (programmation in-situ) dédié à la programmation du microcontrôleur (c'est un port SPI avec alimentation +5V), à connecter via une nappe adaptée (généralement fournie) sur le port nommé <bold>ISP</bold> de l'automate programmable (qui lui-même alimente en +5V la totalité de l'automate programmable et est relié en SPI au microcontrôleur).</quote> <a href="photo/dsc02461.jpg"><img src="thumbnail/dsc02461.jpg"></img></a> <text><bold>À noter que la programmation ISP a plusieurs avantages par rapport à l'USB :</bold> <br/>- Évite de contenir dans la mémoire du microcontrôleur un chargeur d'amorçage (bootloader). <br/>- De ce fait, évite un délai au démarrage du microcontrôleur. <br/>- Minimise le nombre de composants embarqués sur la carte électronique. <br/>- En conséquence, dispense d'équiper la carte électronique d'un composant FTDI (permettant de faire la traduction USB/USART vers le chargeur d'amorçage) qui sur certains systèmes concurrents cause des problèmes d'impédance sur les entrées/sorties USART du microcontrôleur.</text> <a href="photo/dsc02460.jpg"><img src="thumbnail/dsc02460.jpg"></img></a> <a href="photo/dsc07327.jpg"><img src="thumbnail/dsc07327.jpg"></img></a> <title>Compiler et téléverser votre programme :</title> <underline></underline> <text>Pour compiler et téléverser votre programme dans l'automate programmable via le programmateur USBasp, il vous suffit d'exécuter (de double-cliquer) les routines contenues dans le répertoire <bold>example</bold> situé dans l'archive de MODULE (téléchargeable en page d'accueil dans la section "Téléchargements") nommées <bold>Compiler.sh</bold> si vous utilisez un système d'exploitation Linux, ou <bold>Compiler.bat</bold> si vous utilisez un système d'exploitation Windows.</text> <caution>Pour que cette opération de compilation mais surtout de téléversement fonctionne, sur <bold>Windows</bold> il faut installer <bold>le pilote de l'USBasp</bold>, sur <bold>Linux</bold> ou <bold>Mac OS</bold> en revanche il n'y a pas besoin de pilote. Par contre sur Linux Ubuntu que j'utilise il est tout de même nécessaire d'effectuer une petite opération décrite ci-dessous.</caution> <text><bold>Procédure pour Linux Ubuntu :</bold> <br/>Sur Linux Ubuntu, il convient d'écrire quelques lignes dans le terminal afin d'ouvrir un fichier qui permettra de spécifier quelques paramètres utiles pour l'USBasp :</text> <code>sudo gedit /etc/udev/rules.d/99-USBasp.rules</code> <text>Cette ligne ouvre l'éditeur de texte <bold>Gedit</bold>, ensuite il suffit de copier la ligne suivante dans cet éditeur de texte :</text> <code>SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="plugdev", MODE="0666"</code> <text>Une fois ceci effectué, vous enregistrez le fichier, et vous pouvez quitter Gedit.</text> <quote>Pour simplifier, il est également possible d'automatiser la procédure décrite ci-dessus en créant une routine (bash) ayant l'extension <bold>.sh</bold> que vous pourrez exécuter.</quote> <text>Cette routine (.sh) contient le programme suivant :</text> <code>#!/bin/bash echo "SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"05dc\", GROUP=\"plugdev\", MODE=\"0666\"" | sudo tee /etc/udev/rules.d/99-USBasp.rules read exit 0</code> <text><bold>Pilote de l'USBasp pour Windows :</bold> <br/>Sur Windows le pilote de l'USBasp n'est pas présent par défaut sur ce système. Par conséquent vous devez le télécharger et l'installer vous même.</text> <text>L'auteur de l'USBasp recommande d'utiliser un outil pour Windows qui se nomme <bold>Zadig</bold> et qui permet de rechercher ce pilote, personnellement je n'ai jamais essayé (ne possédant pas Windows) mais vu la qualité de son travail je pense que cela est de bon conseil :</text> <a href="http://zadig.akeo.ie/"><download>Site internet de <bold>Zadig</bold></download></a> <title>Les fusibles du microcontrôleur :</title> <underline></underline> <text>Quand vous achetez un microcontrôleur neuf n'ayant jamais été programmé, les fusibles qui permettent de définir des paramètres comme la vitesse de téléversement, l'utilisation d'un quartz externe ou encore le verrouillage du SPI (et bien d'autres paramètres fondamentaux pour le microcontrôleur) sont définis par défaut par le constructeur de la puce.</text> <text>Les routines décrites ci-dessus (Compiler.sh et Compiler.bat) s'occupent de modifier automatiquement les valeurs des fusibles.</text> <caution>Les valeurs des fusibles que j'ai indiqué dans les routines sont les <bold>plus optimisées pour les automates programmable MODULABLE M20 et M32</bold> que j'ai développé (dont les plans de fabrication sont disponibles dans les sections "Téléchargements" et "Fabrications et diverses réalisations" en page d'accueil).</caution> <text>Si jamais vous souhaitez programmer avec MODULE sans utiliser les routines que je propose, sachez que cette opération sur les fusibles est à effectuer une seule fois dans deux cas précis, lorsque vous recevez un <bold>microcontrôleur neuf n'ayant jamais été programmé</bold>, ou lorsque vous récupérez un microcontrôleur qui possiblement dans sa mémoire contient un chargeur d'amorçage (bootloader), ou des paramètres de fusibles inadaptés pour l'architecture de l'automate programmable et le fonctionnement des périphériques.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier download.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#download"><back>Retour</back></a> <a href="license.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Tous mes projets à télécharger</title> <underline></underline> <text>Dans cette section, vous pouvez télécharger tous mes programmes (c'est la partie logicielle) et tous mes plans de fabrication (c'est la partie matérielle) associés au projet MODULE, ainsi que le programme MODULE lui même.</text> <text>Le programme <bold>MODULE</bold> en langage C++ :</text> <a href="download/cpp/module.zip"><download>Télécharger <bold>MODULE</bold></download></a> <text>Les <bold>programmes</bold> en langage C++ associés à MODULE :</text> <a href="download/cpp/radio_control.zip"><download>Télécharger la <bold>radiocommande</bold></download></a> <br/><a href="download/cpp/quadcopter.zip"><download>Télécharger le <bold>quadri-hélicoptère</bold></download></a> <br/><a href="download/cpp/geiger_counter.zip"><download>Télécharger le <bold>compteur Geiger</bold></download></a> <br/><a href="download/cpp/intervalometer.zip"><download>Télécharger <bold>l'intervallomètre</bold> pour la photographie</download></a> <text>Les <bold>plans de fabrication</bold> de mes circuits imprimés au format Gerber associés à MODULE :</text> <a href="download/pcb/modulable_m32.zip"><download>Télécharger l'automate programmable <bold>MODULABLE M32</bold></download></a> <br/><a href="download/pcb/modulable_m20.zip"><download>Télécharger l'automate programmable <bold>MODULABLE M20</bold></download></a> <br/><a href="download/pcb/max7219_digit.zip"><download>Télécharger <bold>l'afficheur à digits</bold> MAX7219</download></a> <br/><a href="download/pcb/max7219_digit_mini.zip"><download>Télécharger le <bold>mini afficheur à digits</bold> MAX7219</download></a> <br/><a href="download/pcb/max7219_matrix.zip"><download>Télécharger <bold>l'afficheur à matrice</bold> MAX7219</download></a> <br/><a href="download/pcb/buzzer.zip"><download>Télécharger le <bold>buzzer</bold> piloté</download></a> <br/><a href="download/pcb/hold_switch.zip"><download>Télécharger l'interrupteur <bold>d'alimentation maintenue</bold></download></a> <br/><a href="download/pcb/max604.zip"><download>Télécharger le <bold>régulateur de tension +3.3V</bold></download></a> <br/><a href="download/pcb/geiger_boost_converter.zip"><download>Télécharger <bold>l'élévateur de tension +400V</bold> pour tube Geiger</download></a> <br/><a href="download/pcb/pin_header.zip"><download>Télécharger la <bold>platine de distribution</bold> 24 broches</download></a> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleAnalogRead.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleAnalogRead"><back>Retour</back></a> <a href="exampleInterruptRead.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Lire un potentiomètre avec AnalogRead.h</title> <underline></underline> <text>La classe <bold>AnalogRead.h</bold> permet de lire la <bold>tension analogique</bold> (0V à +5V) des GPIO connectées au convertisseur analogique/numérique du microcontrôleur.</text> <quote>Cette tension analogique de 0V à +5V est convertie en binaire avec une précision sur 10 bits (de 0 à 1023 en base 10).</quote> <text>Note importante concernant l'impédance de votre montage :</text> <caution>Le circuit de conversion analogique/numérique du microcontrôleur est optimisé pour fonctionner avec des impédances en entrée de <bold>10kΩ</bold>, et peut fonctionner correctement de <bold>1kΩ</bold> à <bold>100kΩ</bold>.</caution> <text><bold>Exemple d'utilisation de AnalogRead.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/AnalogRead.h"</pink> <green>int</green> main() { AnalogRead myPotentiometer = AnalogRead (<pink>25</pink>); <red>while</red> (<red>true</red>) { myPotentiometer.read(); <blue>//myPotentiometer.value est la valeur lue :</blue> <red>if</red> (myPotentiometer.value > <pink>512</pink>) { <blue>//effectuer une action si la tension lue est supérieure à +2.5V</blue> } } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myPotentiometer</bold> de type <bold>AnalogRead</bold> est déclaré, en paramètre est indiqué d'utiliser le port numéro <bold>25</bold> de l'automate programmable en entrée, puis cet objet <bold>myPotentiometer</bold> appelle la fonction <bold>read</bold> ce qui permet de lire l'entrée analogique concernée, et donc de mettre à jour la variable <bold>value</bold> attachée à cet objet.</text> <text>Puis aux lignes suivantes, si cette variable est supérieure à <bold>512</bold> (+2.5V), le déroulement du programme rentre dans la condition logique.</text> <text><bold>Ports des automates programmables concernés par l'analogique :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 15 (PC0) <br/>- Port 16 (PC1) <br/>- Port 17 (PC2) <br/>- Port 18 (PC3) <br/>- Port 19 (PC4) <br/>- Port 20 (PC5) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 25 (PA7) <br/>- Port 26 (PA6) <br/>- Port 27 (PA5) <br/>- Port 28 (PA4) <br/>- Port 29 (PA3) <br/>- Port 30 (PA2) <br/>- Port 31 (PA1) <br/>- Port 32 (PA0)</caution> <text>Récapitulatif des fonctions et variables de cette classe :</text> <code><green>unsigned int</green> value = <pink>0</pink>; AnalogRead (<green>const unsigned char</green> PIN); <green>void</green> read();</code> <title>Détection de niveau de batterie faible :</title> <underline></underline> <text>Avec une entrée analogique disponible et un montage en <bold>pont diviseur de tension</bold>, il vous est possible aisément de détecter si votre batterie électrique est déchargée.</text> <text>Imaginons le cas suivant, vous disposez comme alimentation électrique d'une batterie NIMH d'une <bold>tension maximale de +12V</bold>. Une précaution d'usage s'impose alors :</text> <caution>Ne mettez jamais sur un port d'entrée/sortie de l'automate programmable une tension supérieure à <bold>+5V</bold>, vous risqueriez d'endommager irrémédiablement le microcontrôleur !</caution> <text>Le but est donc de diviser cette tension pour qu'elle ne soit jamais supérieure à +5V <bold>accumulateur complètement chargé</bold> + <bold>marge de sécurité</bold>.</text> <text>Pour faire un pont diviseur de tension, vous devez connecter une résistance sur le <bold>pôle positif</bold> de la batterie (cathode), une autre sur le <bold>pôle négatif</bold> de la batterie (masse/anode), et relier les autres extrémités encore non connectées des deux résistances entres elles, puis relier le tout sur une broche connectée au convertisseur analogique/numérique du microcontrôleur qui va servir à mesurer et convertir cette tension.</text> <text><bold>Calcul du pont diviseur de tension :</bold></text> <quote>Tension maximale de la batterie = <bold>12V</bold> <br/>Tension niveau de batterie faible = <bold>6V</bold> <br/>Tension d'alimentation du microcontrôleur = <bold>5V</bold> <br/>Résistance connectée à la cathode de la batterie = <bold>10kΩ</bold> <br/>Résistance connectée à l'anode de la batterie = <bold>5kΩ</bold> <br/> <br/><bold>Valeurs en sortie du pont diviseur de tension :</bold> <br/>Tension maximale = (5kΩ / (10kΩ + 5kΩ)) * 12V = <bold>4V</bold> (1V de sécurité) <br/>Intensité maximale = (12V / (10kΩ + 5kΩ) = <bold>0.0008A</bold> (0.8mA) <br/>Tension niveau de batterie faible = (5kΩ / (10kΩ + 5kΩ)) * 6V = <bold>2V</bold> <br/>Convertie en base 10 = (1023 / (5V / ((5kΩ / (10kΩ + 5kΩ)) * 6V))) = <bold>409.2</bold></quote> <text>Avec ce montage, la tension entre la masse et l'entrée analogique du microcontrôleur n'excédera pas <bold>+4V</bold>, l'intensité maximale sera de <bold>0.8mA</bold>, et le seuil de niveau de batterie faible à indiquer en programmation sera de <bold>409</bold> en base 10 (arrondi à l'entier inférieur), ce qui donne le programme suivant :</text> <code><purple>#include</purple> <pink>"../module/1284p/AnalogRead.h"</pink> <green>int</green> main() { AnalogRead myVoltage = AnalogRead (<pink>25</pink>); <red>while</red> (<red>true</red>) { myVoltage.read(); <blue>//si la tension de la batterie est inférieure à +6V :</blue> <red>if</red> (myVoltage.value < <pink>409</pink>) { <blue>//niveau de batterie faible</blue> } } <red>return</red> <pink>0</pink>; }</code> <text>Si la tension de votre source d'alimentation fluctue de façon importante, il vous est possible de lisser la valeur à l'aide de la classe <bold>Filter.h</bold>, comme le montre l'exemple suivant :</text> <code><purple>#include</purple> <pink>"../module/1284p/AnalogRead.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Filter.h"</pink> <green>int</green> main() { AnalogRead myVoltage = AnalogRead (<pink>25</pink>); Filter myFilter = Filter (<pink>1000</pink>, <red>false</red>); <red>while</red> (<red>true</red>) { myVoltage.read(); myFilter.set (myVoltage.value); <blue>//si la tension filtrée de la batterie est inférieure à +6V :</blue> <red>if</red> (myFilter.value < <pink>409</pink>) { <blue>//niveau de batterie faible</blue> } } <red>return</red> <pink>0</pink>; }</code> <text>Dans ce présent cas, le filtre va effectuer une moyenne sur <bold>1000 échantillons</bold>, la tension récupérée sera alors débarrassée des fluctuations venants parasiter la mesure.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleDelay.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleDelay"><back>Retour</back></a> <a href="exampleMax7219.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Les délais simplifiés avec Delay.h</title> <underline></underline> <text>Créer une condition logique qui s'exécute de façon périodique n'a jamais été aussi simple à l'aide de la classe <bold>Delay.h</bold>.</text> <text><bold>Exemple d'utilisation de Delay.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Delay.h"</pink> <green>int</green> main() { Delay myDelay = Delay (<pink>1000</pink>, <red>true</red>); <red>while</red> (<red>true</red>) { myDelay.state(); <red>if</red> (myDelay.update == <red>true</red>) { <blue>//tâche à effectuer toutes les 1000ms</blue> } } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myDelay</bold> de type <bold>Delay</bold> est déclaré, le 1er paramètre <bold>1000</bold> fixe la durée du délai indiqué en millisecondes, et le 2ème paramètre <bold>true</bold> permet d'initialiser à vrai la valeur de la variable <bold>update</bold> qui va suivre. Plus loin dans la boucle, l'appel à la fonction <bold>state</bold> permet de mettre à jour la variable <bold>update</bold> périodiquement en fonction de la durée précédemment indiquée.</text> <text>Si vous souhaitez que la variable <bold>update</bold> renvoie vrai après le premier appel à la fonction <bold>state</bold> dans la boucle, indiquez <bold>true</bold> (vrai) en paramètre lors de la création de l'objet myDelay, dans le cas contraire indiquez <bold>false</bold> (faux) :</text> <quote>Le paramètre sur <bold>true</bold> aura pour effet de faire rentrer l'exécution dans la condition logique au démarrage du programme, alors qu'une valeur sur <bold>false</bold> (dans cet exemple) fera attendre 1000 millisecondes avant d'exécuter le contenu de la condition logique.</quote> <caution>Il est important de comprendre que la valeur de la variable <bold>update</bold> est un <bold>événement monostable</bold> (en opposition à un événement astable), qui prend l'état vrai une seule fois après le passage par la fonction <bold>state</bold>, après quoi il reprendra l'état <bold>faux</bold> aux prochains passages (en attendant que la durée spécifiée est de nouveau atteinte).</caution> <title>Faire clignoter une del périodiquement :</title> <underline></underline> <text>Même si la classe Delay.h est vouée à une utilisation plus poussée si nous le souhaitons, une façon aisée d'apprendre à l'utiliser est de reprendre l'exemple ci-dessus pour simplement commuter une del toutes les secondes.</text> <text><bold>Exemple de clignotement d'une del avec Delay.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/GpioWrite.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Delay.h"</pink> <green>int</green> main() { GpioWrite myLed = GpioWrite (<pink>1</pink>); Delay myDelay = Delay (<pink>1000</pink>, <red>true</red>); <red>while</red> (<red>true</red>) { myDelay.state(); <red>if</red> (myDelay.update == <red>true</red>) { myLed.toggle(); } } <red>return</red> <pink>0</pink>; }</code> <text>L'exemple est de lui-même explicite, la valeur de la variable <bold>update</bold> change d'état périodiquement et permet à la del de commuter toutes les 1000 millisecondes. La valeur sur <bold>true</bold> (vrai) à la déclaration de l'objet de type <bold>Delay</bold> se chargera de commuter la del (de l'allumer) dès le démarrage du programme, c'est-à-dire au premier tour de la boucle <bold>while</bold>.</text> <quote>D'autres variables et fonctions existent si besoin est, notamment <bold>started</bold> qui indique si un premier appel à la fonction <bold>state</bold> a été effectué, <bold>duration</bold> qui permet d'indiquer une durée différente que celle initialisée lors de la déclaration de l'objet (utile en cours de programme si vous souhaitez changer la périodicité), et en fin une fonction <bold>reset</bold> qui réinitialise à zéro le temps écoulé ainsi que repositionne à la valeur <bold>false</bold> (faux) la variable <bold>started</bold> et <bold>update</bold>.</quote> <text>Récapitulatif des fonctions et variables de cette classe :</text> <code><green>bool</green> started = <red>false</red>; <green>bool</green> update = <red>false</red>; Delay (<green>const unsigned long long</green> DURATION, <green>const bool</green> NO_START_DELAY); <green>void</green> state(); <green>void</green> duration (<green>const unsigned long long</green> DURATION); <green>void</green> reset();</code> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleGpioRead.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleGpioRead"><back>Retour</back></a> <a href="exampleGpioWrite.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Lire l'état d'un bouton avec GpioRead.h</title> <underline></underline> <text>La classe <bold>GpioRead.h</bold> permet de lire <bold>l'état 0 ou 1</bold> (0V ou +5V) d'un ou plusieurs ports de l'automate programmable avec la possibilité d'utiliser une <bold>résistance de rappel interne au microcontrôleur</bold>, et d'avoir un système <bold>anti-rebonds</bold> bien pratique pour filtrer les rebonds et autres parasites provoquées par les boutons et interrupteurs.</text> <quote>Gpio (pour General Purpose Input/Output ou entrée/sortie pour un usage général) est le nom que l'on donne aux ports d'entrée/sortie génériques (c'est-à-dire sans fonctions particulières) principalement dans le monde des microcontrôleurs.</quote> <text><bold>Exemple d'utilisation de GpioRead.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/GpioRead.h"</pink> <green>int</green> main() { GpioRead myButton = GpioRead (<pink>1</pink>, <red>true</red>, <pink>10</pink>); <red>while</red> (<red>true</red>) { myButton.read(); <red>if</red> (myButton.continuous == <red>true</red>) { <blue>//allumer une del</blue> } <red>else</red> { <blue>//éteindre une del</blue> } <red>if</red> (myButton.momentary == <red>true</red>) { <blue>//allumer une del pendant la durée de ce tour de boucle uniquement</blue> } } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myButton</bold> de type <bold>GpioRead</bold> est déclaré : <br/>- Le 1er paramètre indique l'utilisation du port numéro <bold>1</bold> de l'automate programmable en entrée. <br/>- Le 2ème paramètre <bold>true</bold> permet d'utiliser une <bold>résistance de rappel interne</bold>.</text> <caution>Attention, ne connectez pas un bouton sans résistance de rappel externe à un port de l'automate programmable <bold>sans avoir au préalable défini ce paramètre sur vrai</bold> afin d'utiliser une résistance de rappel interne, dans le cas contraire <bold>vous risquez de griller le microcontrôleur !</bold></caution> <text>- Le 3ème paramètre <bold>10</bold> est le <bold>temps en millisecondes</bold> pour filtrer les rebonds.</text> <quote>A noter que <bold>10ms</bold> est une valeur qui fonctionne bien pour filtrer la plupart des boutons. Plus votre bouton ou interrupteur sera d'une qualité médiocre, plus il faudra augmenter cette valeur.</quote> <text>Plus loin cet objet <bold>myButton</bold> appelle la fonction <bold>read</bold> dans une boucle ce qui permet de lire l'état du port concerné.</text> <text>Cet état <bold>0</bold> ou <bold>1</bold> est stocké dans deux variables, <bold>continuous</bold> et <bold>momentary</bold> : <br/>- continuous signifie que <bold>tant que le bouton est appuyé, cette variable renvoie vrai</bold>. <br/>- momentary signifie que si le bouton est appuyé, <bold>la variable renvoie vrai à la première lecture</bold> (1er tour de boucle généralement), mais qu'elle <bold>renvoie faux aux lectures suivantes</bold> (aux tours de boucle suivants), en attendant que le bouton soit relâché puis par la suite appuyé une seconde fois.</text> <text>Cet état momentané permet d'appeler des blocs de code une seule fois lorsqu'un bouton est pressé (sans être relâché immédiatement), cela peut être utile pour réaliser par exemple des incréments de valeurs, ou bien encore des signaux sonores lorsqu'on presse des boutons...</text> <quote>Bien entendu vous pouvez utiliser cette classe pour d'autres applications (lire autre chose que des boutons ou interrupteurs).</quote> <text><bold>Ports des automates programmables concernés par la GPIO :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 1 (PD0) <br/>- Port 2 (PD1) <br/>- Port 3 (PD2) <br/>- Port 4 (PD3) <br/>- Port 5 (PD4) <br/>- Port 6 (PD5) <br/>- Port 7 (PD6) <br/>- Port 8 (PD7) <br/>- Port 9 (PB0) <br/>- Port 10 (PB1) <br/>- Port 11 (PB2) <br/>- Port 12 (PB3) <br/>- Port 13 (PB4) <br/>- Port 14 (PB5) <br/>- Port 15 (PC0) <br/>- Port 16 (PC1) <br/>- Port 17 (PC2) <br/>- Port 18 (PC3) <br/>- Port 19 (PC4) <br/>- Port 20 (PC5) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 1 (PB0) <br/>- Port 2 (PB1) <br/>- Port 3 (PB2) <br/>- Port 4 (PB3) <br/>- Port 5 (PB4) <br/>- Port 6 (PB5) <br/>- Port 7 (PB6) <br/>- Port 8 (PB7) <br/>- Port 9 (PD0) <br/>- Port 10 (PD1) <br/>- Port 11 (PD2) <br/>- Port 12 (PD3) <br/>- Port 13 (PD4) <br/>- Port 14 (PD5) <br/>- Port 15 (PD6) <br/>- Port 16 (PD7) <br/>- Port 17 (PC0) <br/>- Port 18 (PC1) <br/>- Port 19 (PC2) <br/>- Port 20 (PC3) <br/>- Port 21 (PC4) <br/>- Port 22 (PC5) <br/>- Port 23 (PC6) <br/>- Port 24 (PC7) <br/>- Port 25 (PA7) <br/>- Port 26 (PA6) <br/>- Port 27 (PA5) <br/>- Port 28 (PA4) <br/>- Port 29 (PA3) <br/>- Port 30 (PA2) <br/>- Port 31 (PA1) <br/>- Port 32 (PA0)</caution> <text>Récapitulatif des fonctions et variables de cette classe :</text> <code><green>bool</green> continuous = <red>false</red>; <green>bool</green> momentary = <red>false</red>; GpioRead (<green>const unsigned char</green> PIN, <green>const bool</green> PULL_UP_INTERNAL, <green>const unsigned char</green> DEBOUNCING); <green>void</green> read();</code> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleGpioWrite.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleGpioWrite"><back>Retour</back></a> <a href="exampleAnalogRead.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Allumer une del avec GpioWrite.h</title> <underline></underline> <text>C'est la classe la plus simple à utiliser de MODULE et la première à avoir été écrite. Elle permet de mettre à <bold>l'état 0 ou 1</bold> (0V ou +5V) un ou plusieurs ports de l'automate programmable.</text> <text><bold>Exemple d'utilisation de GpioWrite.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/GpioWrite.h"</pink> <green>int</green> main() { GpioWrite myLed = GpioWrite (<pink>1</pink>); myLed.on(); <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myLed</bold> de type <bold>GpioWrite</bold> est déclaré, en paramètre est indiqué d'utiliser le port numéro <bold>1</bold> de l'automate programmable en sortie, puis cet objet <bold>myLed</bold> appelle la fonction <bold>on</bold> ce qui permet de mettre à l'état <bold>1</bold> le port concerné. Ainsi une diode électroluminescente connectée à ce port s'allumerait.</text> <text>D'autres fonctions existent, <bold>off</bold> pour passer le port à l'état <bold>0</bold>, et <bold>toggle</bold> pour changer l'état du port quel que soit sont état initial (0 ou 1).</text> <caution>Attention, le microcontrôleur <bold>ne peut pas fournir beaucoup de puissance</bold> sur ses broches en sortie !</caution> <text>Il est donc indispensable de piloter un transistor de puissance pour la partie puissance de votre montage. Néanmoins, si il s'agit de quelques 10ènes de milliampères comme dans le cas d'une del ou d'un buzzer, il n'y aura aucun risque à l'alimenter de cette façon.</text> <text><bold>Ports des automates programmables concernés par la GPIO :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 1 (PD0) <br/>- Port 2 (PD1) <br/>- Port 3 (PD2) <br/>- Port 4 (PD3) <br/>- Port 5 (PD4) <br/>- Port 6 (PD5) <br/>- Port 7 (PD6) <br/>- Port 8 (PD7) <br/>- Port 9 (PB0) <br/>- Port 10 (PB1) <br/>- Port 11 (PB2) <br/>- Port 12 (PB3) <br/>- Port 13 (PB4) <br/>- Port 14 (PB5) <br/>- Port 15 (PC0) <br/>- Port 16 (PC1) <br/>- Port 17 (PC2) <br/>- Port 18 (PC3) <br/>- Port 19 (PC4) <br/>- Port 20 (PC5) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 1 (PB0) <br/>- Port 2 (PB1) <br/>- Port 3 (PB2) <br/>- Port 4 (PB3) <br/>- Port 5 (PB4) <br/>- Port 6 (PB5) <br/>- Port 7 (PB6) <br/>- Port 8 (PB7) <br/>- Port 9 (PD0) <br/>- Port 10 (PD1) <br/>- Port 11 (PD2) <br/>- Port 12 (PD3) <br/>- Port 13 (PD4) <br/>- Port 14 (PD5) <br/>- Port 15 (PD6) <br/>- Port 16 (PD7) <br/>- Port 17 (PC0) <br/>- Port 18 (PC1) <br/>- Port 19 (PC2) <br/>- Port 20 (PC3) <br/>- Port 21 (PC4) <br/>- Port 22 (PC5) <br/>- Port 23 (PC6) <br/>- Port 24 (PC7) <br/>- Port 25 (PA7) <br/>- Port 26 (PA6) <br/>- Port 27 (PA5) <br/>- Port 28 (PA4) <br/>- Port 29 (PA3) <br/>- Port 30 (PA2) <br/>- Port 31 (PA1) <br/>- Port 32 (PA0)</caution> <text>Récapitulatif des fonctions de cette classe :</text> <code>GpioWrite (<green>const unsigned char</green> PIN); <green>void</green> toggle(); <green>void</green> on(); <green>void</green> off();</code> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleInterruptRead.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleInterruptRead"><back>Retour</back></a> <a href="examplePwmRead.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Les interruptions avec InterruptRead.h</title> <underline></underline> <text>Les interruptions permettent <bold>d'interrompre le déroulement normal d'un programme</bold> afin d'effectuer une tâche à un moment précis, puis de continuer l'exécution du programme la ou il s'était arrêté.</text> <text>La classe <bold>InterruptRead.h</bold> permet de détecter un <bold>front montant et/ou descendant</bold> (passage de 0V à +5V ou inversement) sur les broches du microcontrôleur concernées par les interruptions.</text> <text><bold>Ports des automates programmables concernés par les interruptions :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 3 (PD2) <br/>- Port 4 (PD3) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 3 (PB2) <br/>- Port 11 (PD2) <br/>- Port 12 (PD3)</caution> <text>L'utilité d'un tel système est de pouvoir <bold>déceler un changement d'état d'un port du microcontrôleur au moment même ou il se produit</bold>. Il n'est alors plus nécessaire d'attendre une lecture de l'état du port concerné au sein même d'une boucle de vérification, comme c'est le cas avec la classe <bold>GpioRead.h</bold> (cette dernière solution produisant une latence suivant la vitesse d'exécution totale de votre boucle de calcul).</text> <quote>Grâce à ce système, il vous est par exemple possible de quantifier et de mesurer précisément la périodicité d'un phénomène physique externe qui changerait spontanément d'état (dans les limites techniques imposées par la programmation et le microcontrôleur bien entendu).</quote> <text><bold>Exemple d'utilisation de InterruptRead.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/InterruptRead.h"</pink> <green>void</green> myEvent() { <blue>//un front montant a été détecté sur le port 3</blue> } <green>int</green> main() { InterruptRead myInterrupt = InterruptRead (<pink>3</pink>); myInterrupt.start (myEvent, <red>true</red>, <red>false</red>); <red>while</red> (<red>true</red>) { } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myInterrupt</bold> de type <bold>InterruptRead</bold> est déclaré, en paramètre est indiqué d'utiliser le port numéro <bold>3</bold> de l'automate programmable en entrée, puis afin de démarrer la lecture du port concerné, cet objet <bold>myInterrupt</bold> appelle la fonction <bold>start</bold> prenant plusieurs paramètres : <br/>- Le 1er paramètre <bold>myEvent</bold> est le nom de la fonction déclarée en amont qui va servir à exécuter du code quand l'interruption interviendra. <br/>- Le 2ème paramètre <bold>true</bold> permet de détecter les fronts montants sur le port. <br/>- Le 3ème paramètre <bold>false</bold> indique de ne pas détecter les front descendants sur le port.</text> <quote>Même si vous n'avez pas besoin d'exécuter des instructions dans la boucle <bold>while</bold>, cette dernière reste importante car elle permet au microcontrôleur de continuer l'exécution du code (qu'il soit une interruption ou pas).</quote> <caution>Dans le cas contraire, l'exécution terminerait après <bold>return 0;</bold>, et le microcontrôleur s'arrêterait là de sorte que plus aucune interruption ne pourrait être exécutée !</caution> <text>Cette classe dispose également d'une fonction <bold>stop</bold> qui permet de stopper la lecture des fronts montants et/ou descendants sur le port concerné.</text> <text>Récapitulatif des fonctions de cette classe :</text> <code>InterruptRead (<green>const unsigned char</green> PIN); <green>void</green> start (<green>void</green> functionJump(), <green>const bool</green> RISING, <green>const bool</green> FALLING); <green>void</green> stop();</code> <title>Mesure de la périodicité d'un phénomène :</title> <underline></underline> <text>La spontanéité du principe même des interruptions (quelques cycles d'horloges tout au plus) permet de mesurer avec une relative précision (pour le microcontrôleur utilisé) un phénomène périodique, avec quelques restrictions cependant :</text> <caution>La durée de la période doit être supérieure au temps d'exécution des fonctions mises en œuvre dans le programme (nous ne sommes pas en matériel pur, mais bien en logiciel).</caution> <text><bold>Exemple de mesure d'un phénomène périodique :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/InterruptRead.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Period.h"</pink> Period _myPeriod = Period(); <green>void</green> myEvent() { _myPeriod.state(); } <green>int</green> main() { InterruptRead myInterrupt = InterruptRead (<pink>3</pink>); myInterrupt.start (myEvent, <red>true</red>, <red>false</red>); <red>while</red> (<red>true</red>) { <blue>//_myPeriod.s est la période mesurée en secondes</blue> <blue>//_myPeriod.ms est la période mesurée en millisecondes</blue> <blue>//_myPeriod.us est la période mesurée en microsecondes</blue> } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple j'utilise la classe <bold>Period.h</bold> qui est dédiée à ce type de tâche bien spécifique, mais il est tout à fait possible de programmer cela avec la classe <bold>Timer.h</bold>, qui via une simple soustraction du temps écoulé courant par rapport au temps écoulé précédent remplirait la même fonction. Period.h offre l'avantage d'avoir ce principe intégré dans son fonctionnement ce qui simplifie la programmation.</text> <quote>Ce programme pourrait être associé à un capteur à effet Hall connecté au port 3 de l'automate programmable, ce qui permettrait par exemple de mesurer la période de rotation d'un moteur électrique ou thermique (et d'en déduire le nombre de tours par minute).</quote> <text>De nombreuses applications et montages sont possibles avec les interruptions, pour ne citer encore qu'un exemple, c'est avec ce principe que je détecte la fermeture du tube sur mon compteur Geiger, ce qui permet ensuite d'extrapoler et d'estimer la radioactivité en rapport au temps écoulé...</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleMax7219.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleMax7219"><back>Retour</back></a> <a href="exampleNrf24l01p.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Afficher des caractères avec Max7219.h</title> <underline></underline> <text><bold>Max7219.h</bold> est une classe qui permet d'utiliser des afficheurs à diodes électroluminescences (digits et matrice) pilotées par le composant <bold>MAX7219</bold>, ce dernier étant connecté en <bold>SPI</bold> avec le microcontrôleur (l'automate programmable) :</text> <a href="photo/dsc02464.jpg"><img src="thumbnail/dsc02464.jpg"></img></a> <a href="photo/dsc02478.jpg"><img src="thumbnail/dsc02478.jpg"></img></a> <text><bold>Ports des automates programmables concernés par le SPI :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 11 (PB2) = SS (slave select) <br/>- Port 12 (PB3) = MOSI (master output slave input) <br/>- Port 13 (PB4) = MISO (master input slave output) <br/>- Port 14 (PB5) = SCK (serial clock) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 5 (PB4) = SS (slave select) <br/>- Port 6 (PB5) = MOSI (master output slave input) <br/>- Port 7 (PB6) = MISO (master input slave output) <br/>- Port 8 (PB7) = SCK (serial clock)</caution> <text><bold>Exemple pour afficher un nombre entier :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Max7219.h"</pink> <green>int</green> main() { Max7219 myDisplay = Max7219 (<pink>5</pink>, <pink>1</pink>); myDisplay.integer (<pink>256</pink>, <pink>1</pink>, <pink>8</pink>, <red>true</red>); <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myDisplay</bold> de type <bold>Max7219</bold> est déclaré : <br/>- Le 1er paramètre indique l'utilisation du port numéro <bold>5</bold> de l'automate programmable pour sélectionner l'esclave (slave select) sur le bus <bold>SPI</bold>. <br/>- Le 2ème paramètre <bold>1</bold> signifie que l'afficheur est en <bold>position 1 en cascade</bold> sur le bus SPI.</text> <quote>Par habitude en SPI, je connecte la sélection de l'esclave au port de l'automate programmable relié à la fonction SS (slave select) du microcontrôleur quand je le peux, <bold>ce qui permet de regrouper tout le câblage relatif au SPI</bold>. <br/> <br/>Mais en réalité, cette entrée/sortie n'est en fait un port SS à la fonction spécifique que lorsque le SPI est configuré en <bold>mode esclave</bold>, ce qui n'arrive jamais avec MODULE. Vous pouvez donc choisir l'esclave sur la sortie SS du microcontrôleur, ou tout autre port d'entrée/sortie disponible (sauf MISO qui même inutilisé doit rester comme une entrée libre lorsque le SPI est en fonctionnement).</quote> <text>Puis la fonction <bold>integer</bold> de l'objet <bold>myDisplay</bold> est appelée : <br/>- Le 1er paramètre <bold>256</bold> est le nombre entier à afficher (sur 32 bits maximum). <br/>- Le 2ème paramètre <bold>1</bold> indique la position ou commence l'affichage de ce nombre (position 1). <br/>- Le 3ème paramètre <bold>8</bold> indique la position ou termine l'affichage de ce nombre (position 8). <br/>- Le 4ème paramètre <bold>true</bold> permet de caler le nombre affiché à droite (false pour le caler à gauche) dans l'intervalle de positions sélectionnée (positions 1 à 8).</text> <caution>Dans cet exemple, le nombre à afficher (256) comporte seulement <bold>3 digits</bold>, l'intervalle de positions qui lui est accordé pour être affiché comporte <bold>8 digits</bold> (positions 1 à 8) c'est-à-dire <bold>la totalité de l'afficheur</bold>. En conséquence, le 4ème paramètre (calage) est effectif lorsque le nombre à afficher prend moins de place que l'intervalle sélectionnée (ceci permet de caler le nombre sur la partie gauche ou droite de l'intervalle choisie).</caution> <title>Autres fonctions utiles :</title> <underline></underline> <text>D'autres fonctions existent, comme l'affichage des nombres décimaux, l'affichage de texte, de points ou lignes sur une matrice à dels, ou encore le réglage de la luminosité (par PWM), etc...</text> <text><bold>Exemple pour afficher un nombre décimal :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Max7219.h"</pink> <green>int</green> main() { Max7219 myDisplay = Max7219 (<pink>5</pink>, <pink>1</pink>); myDisplay.decimal (<pink>2.56</pink>, <pink>3</pink>, <pink>7</pink>, <pink>1</pink>, <red>false</red>); <red>return</red> <pink>0</pink>; }</code> <text>Paramètres de la fonction <bold>decimal</bold> de l'objet <bold>myDisplay</bold> : <br/>- Le 1er paramètre <bold>2.56</bold> est le nombre décimal à afficher (en virgule flottante 32 bits). <br/>- Le 2ème paramètre <bold>3</bold> indique la position ou commence l'affichage de ce nombre (position 3). <br/>- Le 3ème paramètre <bold>7</bold> indique la position ou termine l'affichage de ce nombre (position 7). <br/>- Le 4ème paramètre <bold>1</bold> indique le nombre de chiffres à afficher après la virgule. <br/>- Le 5ème paramètre <bold>false</bold> permet de caler le nombre affiché à gauche (true pour le caler à droite) dans l'intervalle de positions sélectionnée (positions 3 à 7).</text> <text><bold>Exemple pour afficher un nombre entier et décimal l'un à coté de l'autre :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Max7219.h"</pink> <green>int</green> main() { Max7219 myDisplay = Max7219 (<pink>5</pink>, <pink>1</pink>); myDisplay.integer (<pink>256</pink>, <pink>1</pink>, <pink>4</pink>, <red>true</red>); myDisplay.decimal (<pink>1.28</pink>, <pink>5</pink>, <pink>8</pink>, <pink>1</pink>, <red>true</red>); <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, le nombre entier <bold>256</bold> sera affiché dans l'intervalle de positions <bold>1</bold> à <bold>4</bold> et <bold>calé à droite</bold> dans son intervalle de positions.</text> <text>Le nombre décimal qu'en à lui sera affiché dans l'intervalle de positions <bold>5</bold> à <bold>8</bold>, avec <bold>1 chiffre après la virgule</bold>, et à l'instar du nombre décimal il sera <bold>calé à droite</bold> dans son intervalle de positions sur l'afficheur.</text> <caution>Le nombre entier affiché en premier ne sera pas effacé tant que des caractères ne viendront pas écraser les positions (intervalles) qu'il occupe. Si vous souhaitez effacer tout ce qui est affiché sur l'afficheur, utilisez la fonction <bold>clearDevice</bold>.</caution> <text><bold>Exemple pour afficher du texte :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Max7219.h"</pink> <green>int</green> main() { Max7219 myDisplay = Max7219 (<pink>5</pink>, <pink>1</pink>); myDisplay.word (<pink>"hello"</pink>); <red>return</red> <pink>0</pink>; }</code> <text>La fonction <bold>word</bold> de l'objet <bold>myDisplay</bold> ne prend qu'un seul paramètre, ici c'est le mot <bold>hello</bold> qui est affiché (sur un afficheur à digits).</text> <text>Il est également possible d'afficher des nombres avec cette fonction, pour cela il suffit d'écrire en paramètre par exemple <bold>"123.45"</bold>, ou bien encore d'afficher les lettres avec leurs points (virgules) correspondants (en suffixe) en écrivant <bold>"..hel.l.o"</bold>. Ici les deux <bold>l.</bold> s'afficheront avec un point en dessous.</text> <quote>Un caractère à la fonction spécifique existe, c'est la barre oblique <bold>/</bold>. Celle-ci permet de terminer le rafraîchissement de l'affichage à cet endroit, et par conséquent de ne pas écraser les digits suivants, car en effet avec la fonction word, <bold>par défaut c'est l'intégralité de l'affichage qui est mis à jour</bold>.</quote> <text><bold>Exemple pour connecter plusieurs afficheurs en cascade et/ou en parallèle sur le bus SPI :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Max7219.h"</pink> <green>int</green> main() { Max7219 myDigitDisplay = Max7219 (<pink>5</pink>, <pink>1</pink>); Max7219 myMatrixDisplay = Max7219 (<pink>5</pink>, <pink>2</pink>); Max7219 myWordDisplay = Max7219 (<pink>4</pink>, <pink>1</pink>); myDigitDisplay.integer (<pink>256</pink>, <pink>1</pink>, <pink>8</pink>, <red>true</red>); myMatrixDisplay.dot (<pink>7</pink>, <pink>2</pink>); myMatrixDisplay.dot (<pink>8</pink>, <pink>1</pink>); myWordDisplay.word (<pink>"hello "</pink>); <red>return</red> <pink>0</pink>; }</code> <text>Explication des connexions : <br/>- La broche SS (slave select) de l'afficheur relatif à l'objet <bold>myDigitDisplay</bold> est connectée au port <bold>5</bold> de l'automate programmable, il est le <bold>1er périphérique en cascade</bold> sur le bus SPI. <br/>- La broche SS de l'afficheur relatif à l'objet <bold>myMatrixDisplay</bold> est également connectée au port <bold>5</bold> de l'automate programmable, mais cet afficheur est défini comme étant le <bold>2ème périphérique en cascade</bold> sur le bus SPI. <br/>- Le 3ème afficheur relatif à l'objet <bold>myWordDisplay</bold> voit sa broche SS connectée au port <bold>4</bold> de l'automate programmable (il est donc en parallèle par rapport aux autres) et est indiqué comme étant le seul périphérique sur cette partie du bus SPI.</text> <quote>Si votre alimentation le permet, ce principe de connexions en cascade (série) et/ou en parallèle vous garanti de faire fonctionner un très grand nombre d'afficheurs sur un même automate programmable.</quote> <text><bold>Exemple pour régler la luminosité de l'affichage :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Max7219.h"</pink> <green>int</green> main() { Max7219 myDisplay = Max7219 (<pink>5</pink>, <pink>1</pink>); myDisplay.brightness (<pink>4</pink>); <red>return</red> <pink>0</pink>; }</code> <text>La fonction <bold>brightness</bold> est appelée et prend en paramètre un nombre entier de <bold>1</bold> à <bold>16</bold> (16 étant la luminosité maximale).</text> <quote>Vous pouvez réaliser des effets complexes avec toutes les fonctions qui vous sont proposées dans cette classe, libre à vous de composer votre affichage d'une manière harmonieuse !</quote> <text>Récapitulatif des fonctions de cette classe :</text> <code>Max7219 (<green>const unsigned char</green> PIN_SS, <green>const unsigned char</green> DEVICE); void brightness (<green>const unsigned char</green> BRIGHTNESS); void digit (<green>const unsigned char</green> DIGIT, <green>const bool</green> COMMA, <green>const unsigned char</green> POSITION); void integer (<green>const signed long</green> INTEGER, <green>const unsigned char</green> POSITION_MIN, <green>const unsigned char</green> POSITION_MAX, <green>const bool</green> SIDE); void decimal (<green>const float</green> DECIMAL, <green>const unsigned char</green> POSITION_MIN, <green>const unsigned char</green> POSITION_MAX, <green>const unsigned char</green> DIGIT_AFTER_COMMA, <green>const bool</green> SIDE); void character (const char *CHARACTER, <green>const unsigned char</green> POSITION); void word (const char *WORD); void byte (<green>const unsigned char</green> BYTE); void draw (<green>const unsigned char</green> DRAW, <green>const unsigned char</green> POSITION); void drawDevice (<green>const unsigned char</green> DRAW1, <green>const unsigned char</green> DRAW2, <green>const unsigned char</green> DRAW3, <green>const unsigned char</green> DRAW4, <green>const unsigned char</green> DRAW5, <green>const unsigned char</green> DRAW6, <green>const unsigned char</green> DRAW7, <green>const unsigned char</green> DRAW8); void dot (<green>const unsigned char</green> X, <green>const unsigned char</green> Y); void clearLine (<green>const unsigned char</green> LINE); void clearDevice();</code> <title>Un effet facile à réaliser avec MODULE :</title> <underline></underline> <text>Avec MODULE, il vous est possible de combiner les fonctionnalités d'une ou de toutes les classes sans problèmes d'interactions si vous le souhaitez, il devient alors très aisé de réaliser vos propres effets en utilisant plusieurs classes dédiées à la réalisation de certaines tâches simples ou complexes :</text> <video src="video/00001.mov" controls></video> <text>Le programme :</text> <code><purple>#include</purple> <pink>"../module/1284p/Max7219.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Random.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Timer.h"</pink> <green>int</green> main() { <green>unsigned char</green> line = <pink>1</pink>; Max7219 myMatrix = Max7219 (<pink>5</pink>, <pink>1</pink>); Random::seed (<pink>25</pink>); <red>while</red> (<red>true</red>) { for (line = <pink>1</pink>; line <= <pink>8</pink>; line++) { myMatrix.draw (Random::integer (<pink>0</pink>, <pink>255</pink>), line); } Timer::pause (<pink>100</pink>); } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, l'utilisation de la classe <bold>Random.h</bold> permet la génération de <bold>positions aléatoires</bold> ce qui a pour conséquence d'afficher les pixels au hasard sur la matrice.</text> <text><bold>Connexions (afficheur sur automates programmables) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SS (slave select) sur port SS ou tout autre port d'entrée/sortie disponible (sauf MISO qui doit rester libre sauf si il est déjà utilisé par un autre périphérique également SPI). <br/>- Broche MOSI (master output slave input) sur port MOSI. <br/>- Broche SCK (serial clock) sur port SCK.</caution> <a href="photo/dsc02466.jpg"><img src="thumbnail/dsc02466.jpg"></img></a> <quote>Les plans de fabrication de mes afficheurs (digits et matrice) sont disponibles dans les sections "Téléchargements" et "Fabrications et diverses réalisations" en page d'accueil.</quote> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleNrf24l01p.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleNrf24l01p"><back>Retour</back></a> <a href="projectModulableM32.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Une radiocommande avec Nrf24l01p.h</title> <underline></underline> <text><bold>Nrf24l01p.h</bold> permet de transmettre de manière <bold>multidirectionnelle</bold> (applications multiceivers, soit plusieurs tranceivers) des informations (sur 32 bits quelles qu'elles soient) sur la bande fréquence des <bold>2.4GHz</bold> entre plusieurs périphériques (deux ou plus).</text> <caution>Le composant utilisé est le <bold>nRF24L01+</bold>, ce matériel est un <bold>tranceiver</bold> pour émetteur/récepteur, la classe que je propose ici pilote ce composant et permet des <bold>applications multiceivers</bold> (réseau d'émetteurs/récepteurs), autorisant les projets les plus ambitieux notamment en robotique.</caution> <a href="photo/dsc07168.jpg"><img src="thumbnail/dsc07168.jpg"></img></a> <a href="photo/dsc07145.jpg"><img src="thumbnail/dsc07145.jpg"></img></a> <text>Le composant <bold>nRF24L01+</bold> communique en <bold>SPI</bold> avec le microcontrôleur.</text> <text><bold>Ports des automates programmables concernés par le SPI :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 11 (PB2) = SS (slave select) <br/>- Port 12 (PB3) = MOSI (master output slave input) <br/>- Port 13 (PB4) = MISO (master input slave output) <br/>- Port 14 (PB5) = SCK (serial clock) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 5 (PB4) = SS (slave select) <br/>- Port 6 (PB5) = MOSI (master output slave input) <br/>- Port 7 (PB6) = MISO (master input slave output) <br/>- Port 8 (PB7) = SCK (serial clock)</caution> <text>Dans les exemples qui suivent, il s'agit de montrer le plus simplement possible (pour la compréhension du lecteur) un émetteur et un récepteur distinct (sans créer de confusion et donc sans évoquer le coté multiceiver) :</text> <quote>Mais sachez que <bold>la programmation de multiples émetteurs/récepteurs s'effectue exactement de la même façon</bold>, avec les fonctions employées dans les exemples (transmit et receive), de manière <bold>complètement transparente pour le programmeur</bold> via l'utilisation de la classe Nrf24l01p.h.</quote> <text>Ci-dessous, un premier périphérique nommé "émetteur" envoi des données à un deuxième montage appelé "récepteur".</text> <text><bold>Exemple d'émetteur :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Nrf24l01p.h"</pink> <green>int</green> main() { Nrf24l01p myChannel = Nrf24l01p (<pink>1</pink>); <green>unsigned char</green> increment = <pink>0</pink>; Nrf24l01p::start (<pink>5</pink>, <pink>32</pink>, <pink>1524003746</pink>, <red>true</red>); <red>while</red> (<red>true</red>) { myChannel.transmit (increment); <red>if</red> (increment < <pink>255</pink>) { increment++; } <red>else</red> { increment = <pink>0</pink>; } } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myChannel</bold> de type <bold>Nrf24l01p</bold> est déclaré, en paramètre est indiqué le canal <bold>1</bold> sur lequel communiquer les informations (il y a 64 canaux en tout). À la ligne suivante une variable de type <bold>unsigned char</bold> (8 bits non signés) est déclarée avec une valeur de <bold>0</bold>, elle va servir à incrémenter un nombre entier.</text> <text>Puis, le composant nRF24L01+ est démarré en appelant la fonction statique <bold>start</bold> prenant plusieurs paramètres : <br/>- Le 1er paramètre <bold>5</bold> est le numéro du port de l'automate programmable sur lequel est connectée la broche SS (slave select) du composant nRF24L01+.</text> <quote>Ce paramètre est utile lorsque vous souhaitez connecter en SPI différents composants en série ou en parallèle avec le microcontrôleur.</quote> <text>- Le 2ème paramètre <bold>32</bold> est le numéro du port de l'automate programmable laissé libre (en l'air) relié en interne au convertisseur analogique/numérique du microcontrôleur. Ce port sert au système anti-collisions qui utilise du bruit analogique pour générer de l'aléatoire. Si vous ne souhaitez pas utiliser le système anti-collisions, indiquez <bold>0</bold> en paramètre.</text> <caution>Le système anti-collisions de la classe Nrf24l01p.h permet d'éviter que plusieurs (deux ou plus) nRF24L01+ ne se transmettent des données exactement au même moment. Il est vivement conseillé dans le cadre d'une <bold>communication multidirectionnelle d'activer le système anti-collisions</bold> en sélectionnant un port approprié.</caution> <text><bold>Ports des automates programmables concernés par l'analogique :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 15 (PC0) <br/>- Port 16 (PC1) <br/>- Port 17 (PC2) <br/>- Port 18 (PC3) <br/>- Port 19 (PC4) <br/>- Port 20 (PC5) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 25 (PA7) <br/>- Port 26 (PA6) <br/>- Port 27 (PA5) <br/>- Port 28 (PA4) <br/>- Port 29 (PA3) <br/>- Port 30 (PA2) <br/>- Port 31 (PA1) <br/>- Port 32 (PA0)</caution> <text>- Le 3ème paramètre <bold>1524003746</bold> correspond au code de radio-identification (ou RFID unique par définition) qui permet de sécuriser la communication entre plusieurs (deux ou plus) nRF24L01+.</text> <caution>C'est à vous de choisir ce code RFID, plus le nombre est complexe et plus la communication sera sécurisée et protégée contre les parasites, mais il faut reconnaître que n'importe quel nombre sur 32 bits différent de 0 avec seulement quelques chiffres, est largement suffisant.</caution> <text>- Le 4ème paramètre <bold>true</bold> indique d'émettre à la puissance maximale (0dBm). Une valeur sur <bold>false</bold> serait la puissance minimale (-18dBm), ce qui peut être suffisant en communication courte distance (par exemple en intérieur).</text> <text>Puis dans la boucle <bold>while</bold>, la fonction <bold>transmit</bold> de l'objet <bold>myChannel</bold> est utilisée pour transmettre une information 32 bits à un autre nRF24L01+. Dans ce cas c'est la valeur de la variable <bold>increment</bold> qui est transmise, variable dont la valeur est incrémentée aux lignes suivantes.</text> <quote>Ce petit bout de programme est simple, mais il permet déjà d'assurer une communication 2.4GHz efficace et sécurisée entre deux nRF24L01+.</quote> <text>Envoyer la valeur d'une variable qui s'incrémente au cours du temps peut servir à programmer simplement un système à tolérance de pannes (fail-safe) sur la partie récepteur du montage. En effet, si la valeur reçue ne s'incrémente plus pendant un certain temps (1 seconde par exemple), il peut être alors intéressant de déclencher une mise au neutre des servo-moteurs, une coupure de la motorisation d'un aéronef, une procédure de vol automatisée par gyroscope, etc...</text> <text><bold>Exemple de récepteur :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Nrf24l01p.h"</pink> <green>int</green> main() { Nrf24l01p myChannel = Nrf24l01p (<pink>1</pink>); <green>unsigned char</green> increment = <pink>0</pink>; Nrf24l01p::start (<pink>5</pink>, <pink>32</pink>, <pink>1524003746</pink>, <red>true</red>); <red>while</red> (<red>true</red>) { myChannel.receive(); <blue>//myChannel.data sont les données reçues sur ce canal :</blue> increment = myChannel.data; } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple le seul changement notable est l'appel de la fonction <bold>receive</bold> de l'objet <bold>myChannel</bold> afin de recevoir les informations émises, en l'occurrence ici la valeur de la variable incrémentée dans le montage coté émetteur.</text> <text><bold>Connexions (nRF24L01+ sur automates programmables) :</bold></text> <caution>- Broches VSS (GND) sur broche GND disponible. <br/>- Broches VDD (+3.3V) sur broche +3.3V disponible via un régulateur de tension adapté. <br/>- Broche CSN (slave select) sur port SS ou tout autre port d'entrée/sortie disponible. <br/>- Broche MOSI (master output slave input) sur port MOSI. <br/>- Broche MISO (master input slave output) sur port MISO. <br/>- Broche SCK (serial clock) sur port SCK.</caution> <a href="photo/dsc02466.jpg"><img src="thumbnail/dsc02466.jpg"></img></a> <caution>Attention, le composant <bold>nRF24L01+</bold> fonctionne avec une tension de <bold>+3.3V</bold>, il convient donc d'utiliser un régulateur de tension adapté !</caution> <quote>La classe Nrf24l01p.h dispose d'une fonction <bold>reset</bold> ce qui permet de remettre à l'état <bold>false</bold> les variables <bold>received</bold> et <bold>transmitted</bold>. Ces variables sont utiles pour savoir si une ou plusieurs données ont été reçues ou transmises avec succès. La variable <bold>data</bold> (qui correspond aux données reçues) est également réinitialisée à <bold>0</bold>. <br/> <br/>Une fonction statique <bold>stop</bold> existe également et permet d'éteindre le circuit d'émission/réception du composant nRF24L01+, un nouvel appel à la fonction <bold>start</bold> permet de redémarrer le circuit.</quote> <text>Récapitulatif des fonctions et variables de cette classe :</text> <code><green>signed long</green> data = <pink>0</pink>; <green>bool</green> received = <red>false</red>; <green>bool</green> transmitted = <red>false</red>; Nrf24l01p (<green>const unsigned char</green> ADDRESS); <green>static void</green> start (<green>const unsigned char</green> PIN_SS, <green>const unsigned char</green> PIN_ANTI_COLLISION, <green>const unsigned long</green> RFID, <green>const bool</green> POWER); <green>void</green> receive(); <green>void</green> transmit (<green>const signed long</green> DATA); <green>void</green> reset(); <green>static void</green> stop();</code> <title>Exemple d'un système R/C 5 voies :</title> <underline></underline> <text>Dans l'exemple suivant, 4 potentiomètres (2 par manche) sont connectés aux ports 25, 26, 27, et 28 de l'automate programmable. Ce sont des GPIO connectées au convertisseur analogique/numérique du microcontrôleur. Un interrupteur est également connecté au port 1 de l'automate programmable, ce qui va servir d'interrupteur de coupure moteur dans ce cas précis.</text> <quote>Les 4 potentiomètres et l'interrupteur servent <bold>d'interface utilisateur entre l'homme et la machine</bold>.</quote> <text>5 objets de type <bold>Nrf24l01p</bold> (correspondants aux 5 voies) servent à transmettre les valeurs brutes des 4 potentiomètres et de l'interrupteur (respectivement des valeurs allants de 0 à 1023 pour les potentiomètres et 0 ou 1 pour l'interrupteur).</text> <text><bold>L'émetteur :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/AnalogRead.h"</pink> <purple>#include</purple> <pink>"../module/1284p/GpioRead.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Nrf24l01p.h"</pink> <green>int</green> main() { AnalogRead myStickThrottle = AnalogRead (<pink>25</pink>); AnalogRead myStickPitch = AnalogRead (<pink>26</pink>); AnalogRead myStickRoll = AnalogRead (<pink>27</pink>); AnalogRead myStickYaw = AnalogRead (<pink>28</pink>); GpioRead myButtonCut = GpioRead (<pink>1</pink>, <red>true</red>, <pink>20</pink>); Nrf24l01p myChannelThrottle = Nrf24l01p (<pink>1</pink>); Nrf24l01p myChannelPitch = Nrf24l01p (<pink>2</pink>); Nrf24l01p myChannelRoll = Nrf24l01p (<pink>3</pink>); Nrf24l01p myChannelYaw = Nrf24l01p (<pink>4</pink>); Nrf24l01p myChannelCut = Nrf24l01p (<pink>5</pink>); Nrf24l01p::start (<pink>5</pink>, <pink>32</pink>, <pink>1524003746</pink>, <red>true</red>); <red>while</red> (<red>true</red>) { myStickThrottle.read(); myStickPitch.read(); myStickRoll.read(); myStickYaw.read(); myButtonCut.read(); myChannelThrottle.transmit (myStickThrottle.value); myChannelPitch.transmit (myStickPitch.value); myChannelRoll.transmit (myStickRoll.value); myChannelYaw.transmit (myStickYaw.value); myChannelCut.transmit (myButtonCut.continuous); } <red>return</red> <pink>0</pink>; }</code> <text>L'exemple suivant est la partie récepteur du montage. 5 objets de type <bold>PwmWrite</bold> sont utilisés pour générer des signaux <bold>PWM</bold> ce qui permet de faire fonctionner 4 servo-moteurs : <br/>- Le 1er pour les gaz (throttle). <br/>- Le 2ème pour l'axe de tangage (pitch). <br/>- Le 3ème pour l'axe de roulis (roll). <br/>- Le 4ème pour l'axe de lacet (yaw).</text> <text>Une fois reçues avec les fonctions <bold>receive</bold>, les valeurs brutes sont transformées à l'aide de la classe <bold>Math.h</bold> (qui permet de créer entre autre des courbes) en valeurs adaptées PWM (modulation de la largeur d'impulsion en microsecondes) afin de les envoyer aux servo-moteurs par les ports 1, 2, 3, et 4 de l'automate programmable.</text> <text><bold>Le récepteur :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Nrf24l01p.h"</pink> <purple>#include</purple> <pink>"../module/1284p/PwmWrite.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Math.h"</pink> <green>int</green> main() { Nrf24l01p myChannelThrottle = Nrf24l01p (<pink>1</pink>); Nrf24l01p myChannelPitch = Nrf24l01p (<pink>2</pink>); Nrf24l01p myChannelRoll = Nrf24l01p (<pink>3</pink>); Nrf24l01p myChannelYaw = Nrf24l01p (<pink>4</pink>); Nrf24l01p myChannelCut = Nrf24l01p (<pink>5</pink>); PwmWrite myServoThrottle = PwmWrite (<pink>1</pink>); PwmWrite myServoPitch = PwmWrite (<pink>2</pink>); PwmWrite myServoRoll = PwmWrite (<pink>3</pink>); PwmWrite myServoYaw = PwmWrite (<pink>4</pink>); Nrf24l01p::start (<pink>5</pink>, <pink>32</pink>, <pink>1524003746</pink>, <red>true</red>); PwmWrite::start (<pink>50</pink>); <red>while</red> (<red>true</red>) { myChannelThrottle.receive(); myChannelPitch.receive(); myChannelRoll.receive(); myChannelYaw.receive(); myChannelCut.receive(); <red>if</red> (myChannelCut.data == <red>true</red>) { myServoThrottle.us (<pink>1000</pink>); } <red>else</red> { myServoThrottle.us (Math::curve (<pink>0</pink>, myChannelThrottle.data, <pink>1023</pink>, <pink>1000</pink>, <pink>2000</pink>, <pink>0</pink>)); myServoPitch.us (Math::curve (<pink>0</pink>, myChannelPitch.data, <pink>1023</pink>, <pink>1000</pink>, <pink>2000</pink>, <pink>0</pink>)); myServoRoll.us (Math::curve (<pink>0</pink>, myChannelRoll.data, <pink>1023</pink>, <pink>1000</pink>, <pink>2000</pink>, <pink>0</pink>)); myServoYaw.us (Math::curve (<pink>0</pink>, myChannelYaw.data, <pink>1023</pink>, <pink>1000</pink>, <pink>2000</pink>, <pink>0</pink>)); } } <red>return</red> <pink>0</pink>; }</code> <text>La 5ème voie (cut) permet la <bold>coupure des gaz</bold> quel que soit la position du manche de gaz, c'est une des sécurités fondamentales notamment en aéromodélisme.</text> <caution>À ce propos, je ne pourrais être tenu pour responsable si vous faites une mauvaise utilisation de mes exemples !</caution> <text>Ce qui signifie que vous utilisez ma programmation en toute connaissance de cause et en règle avec la loi en vigueur dans votre pays (notamment en ce qui concerne les lieux de vols autorisés, les fréquences et puissances d'émissions des radio-émetteurs, etc...).</text> <quote>Libre à vous d'explorer les possibilités de <bold>MODULE</bold> afin d'utiliser et de modifier ces exemples pour vos applications !</quote> <text>En l'occurrence je pense au retour air/sol de la pression atmosphérique et de la température à l'aide du baromètre <bold>BMP180</bold> et de la classe <bold>Bmp180.h</bold>, de l'utilisation des gyroscopes <bold>MPU6050</bold> et <bold>BNO055</bold> à l'aide des classes <bold>Mpu6050.h</bold> et <bold>Bno055.h</bold>, de l'ajout de trims, d'un écran de contrôle, d'une alarme batterie faible, d'une temporisation, de réglages divers (courbes, double débattements), etc... (voir mon projet de radiocommande section "Fabrications et diverses réalisations" en page d'accueil).</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier examplePwmRead.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#examplePwmRead"><back>Retour</back></a> <a href="examplePwmWrite.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Lire un récepteur R/C avec PwmRead.h</title> <underline></underline> <text>L'une des utilisations possibles de la classe <bold>PwmRead.h</bold> est la lecture des sorties PWM d'un récepteur de modélisme R/C standard afin de piloter un modèle R/C. Bien d'autres applications sont possibles, mais c'est celle-ci qui fera l'objet d'un exemple ici.</text> <text>La <bold>modulation de la largeur d'impulsion</bold> (PWM) est un moyen pratique de communication entre deux (ou plusieurs) périphériques, ce principe ne demande qu'un seul fil de liaison.</text> <quote><bold>PwmRead.h</bold> permet de mesurer la largeur d'impulsion PWM avec une précision d'<bold>1 microseconde</bold>.</quote> <text><bold>Exemple d'utilisation de PwmRead.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/PwmRead.h"</pink> <green>int</green> main() { PwmRead myChannelThrottle = PwmRead (<pink>1</pink>, <red>true</red>); PwmRead myChannelPitch = PwmRead (<pink>2</pink>, <red>true</red>); PwmRead myChannelRoll = PwmRead (<pink>3</pink>, <red>true</red>); PwmRead myChannelYaw = PwmRead (<pink>4</pink>, <red>true</red>); PwmRead myChannelCut = PwmRead (<pink>5</pink>, <red>true</red>); PwmRead::start (<pink>100</pink>); <red>while</red> (<red>true</red>) { myChannelThrottle.read(); myChannelPitch.read(); myChannelRoll.read(); myChannelYaw.read(); myChannelCut.read(); <blue>//si l'interrupteur de coupure des gaz est enclenché :</blue> <red>if</red> (myChannelCut.us > <pink>1500</pink>) { <blue>//coupure des gaz</blue> } <red>else</red> { <blue>//sinon, utilisation des valeurs pour piloter le modèle R/C :</blue> <blue>//myChannelThrottle.us (gaz)</blue> <blue>//myChannelPitch.us (tangage)</blue> <blue>//myChannelRoll.us (roulis)</blue> <blue>//myChannelYaw.us (lacet)</blue> } } <red>return</red> <pink>0</pink>; }</code> <text>Cet exemple montre un peu comment organiser un programme pour pouvoir lire les voies PWM d'un récepteur de modélisme standard afin de piloter un modèle radio-commandé.</text> <text>Au début du code, 5 objets de type <bold>PwmRead</bold> sont déclarés : <br/>- Le 1er paramètre indique le numéro du port de l'automate programmable en entrée qui va servir à lire le signal PWM, respectivement les ports numéro <bold>1</bold>, <bold>2</bold>, <bold>3</bold>, <bold>4</bold>, et <bold>5</bold> dans l'exemple.</text> <caution>Avec la classe PwmRead.h, <bold>tous les ports de l'automate programmable</bold> peuvent servir à la lecture de signaux PWM.</caution> <text>- Le 2ème paramètre <bold>true</bold> permet de définir que la lecture du PWM débute par un <bold>front montant</bold>, et termine par un front descendant (le cas le plus courant), ou inversement si le paramètre était indiqué à <bold>false</bold>.</text> <quote>Ce paramètre n'a pas d'utilité dans le cadre de la lecture de sorties PWM type récepteurs de modélisme standards, où l'on s'attends toujours à un front montant lorsque le signal débute. En revanche, cette fonctionnalité peut être utile voir indispensable pour d'autres applications.</quote> <text>Ensuite, la lecture PWM est démarrée en appelant la fonction statique <bold>start</bold> prenant en paramètre <bold>100</bold>, un temps arbitraire (dépendant de la fréquence du PWM) indiqué en millisecondes, relatif à la sécurité de votre montage si besoin (voir plus loin).</text> <text>À la suite du programme dans la boucle, les 5 objets de type <bold>PwmRead</bold> appellent leurs fonctions <bold>read</bold> respectives, ce qui permet de mettre à jour les variables <bold>us</bold> (largeur d'impulsion en microsecondes) relatives aux objets déclarés, et de s'en servir pour piloter le modèle R/C.</text> <text><bold>Une sécurité dans le cas d'un récepteur R/C partiellement défaillant :</bold> <br/>La lecture PWM s'effectuant de manière <bold>séquentielle dans l'ordre de déclaration des objets</bold>, imaginez le cas extrême d'une défaillance de l'une des voies de votre récepteur R/C, cas ou la lecture de la voie deviendrait impossible. Il serait alors judicieux de considérer que si au bout d'un certain temps, le signal PWM ne peut être mesuré, la lecture passe à l'objet suivant (à la voie suivante) sans mettre à jour la variable <bold>us</bold> relative à l'objet considéré. C'est exactement ce que permet ce paramètre, dans l'exemple :</text> <caution><bold>100 millisecondes</bold> sera le temps au bout duquel on considère que la lecture du PWM a échouée pour cause d'une défaillance en amont.</caution> <text>Ce paramètre peut être indiqué à <bold>0</bold>, mais si vous débranchez un fil de liaison de votre récepteur R/C, par exemple la voie branchée sur l'objet <bold>myChannelPitch</bold>, dans ce cas toutes les autres voies ne seront plus mises à jour dans la boucle, alors que cela n'aurait pas été le cas si vous aviez indiqué un paramètre supérieur à 0.</text> <text>Pour choisir ce temps, il vous faut considérer la fréquence de votre PWM. Si votre récepteur R/C produit un PWM à une fréquence de <bold>50Hz</bold>, une valeur de sécurité indiquée en paramètre d'au moins <bold>40ms</bold> (2 fois la période de 50Hz) semble cohérente.</text> <text><bold>Ports des automates programmables concernés par la lecture du PWM :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 1 (PD0) <br/>- Port 2 (PD1) <br/>- Port 3 (PD2) <br/>- Port 4 (PD3) <br/>- Port 5 (PD4) <br/>- Port 6 (PD5) <br/>- Port 7 (PD6) <br/>- Port 8 (PD7) <br/>- Port 9 (PB0) <br/>- Port 10 (PB1) <br/>- Port 11 (PB2) <br/>- Port 12 (PB3) <br/>- Port 13 (PB4) <br/>- Port 14 (PB5) <br/>- Port 15 (PC0) <br/>- Port 16 (PC1) <br/>- Port 17 (PC2) <br/>- Port 18 (PC3) <br/>- Port 19 (PC4) <br/>- Port 20 (PC5) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 1 (PB0) <br/>- Port 2 (PB1) <br/>- Port 3 (PB2) <br/>- Port 4 (PB3) <br/>- Port 5 (PB4) <br/>- Port 6 (PB5) <br/>- Port 7 (PB6) <br/>- Port 8 (PB7) <br/>- Port 9 (PD0) <br/>- Port 10 (PD1) <br/>- Port 11 (PD2) <br/>- Port 12 (PD3) <br/>- Port 13 (PD4) <br/>- Port 14 (PD5) <br/>- Port 15 (PD6) <br/>- Port 16 (PD7) <br/>- Port 17 (PC0) <br/>- Port 18 (PC1) <br/>- Port 19 (PC2) <br/>- Port 20 (PC3) <br/>- Port 21 (PC4) <br/>- Port 22 (PC5) <br/>- Port 23 (PC6) <br/>- Port 24 (PC7) <br/>- Port 25 (PA7) <br/>- Port 26 (PA6) <br/>- Port 27 (PA5) <br/>- Port 28 (PA4) <br/>- Port 29 (PA3) <br/>- Port 30 (PA2) <br/>- Port 31 (PA1) <br/>- Port 32 (PA0)</caution> <text>Récapitulatif des fonctions et variables de cette classe :</text> <code><green>unsigned long</green> us = <pink>0</pink>; PwmRead (<green>const unsigned char</green> PIN, <green>const bool</green> RISING); <green>static void</green> start (<green>const unsigned int</green> TIME_OUT); <green>void</green> read();</code> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier examplePwmWrite.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#examplePwmWrite"><back>Retour</back></a> <a href="exampleSoundWrite.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Les servo-moteurs avec PwmWrite.h</title> <underline></underline> <text>Comme pour les autres classes de MODULE, <bold>PwmWrite.h</bold> n'est pas dédiée à une application en particulier (bien que l'exemple qui suit concerne les servo-moteurs). J'utilise notamment la génération de signaux <bold>PWM</bold> pour faire varier la luminosité des diodes électroluminescentes (voir l'exemple plus bas : "Faire varier la luminosité d'une del").</text> <caution>Avec la classe PwmWrite.h, <bold>tous les ports de l'automate programmable</bold> peuvent servir à la génération de signaux PWM (voir plus loin : "Le choix du PWM matériel ou logiciel").</caution> <text>L'exemple suivant permet de faire fonctionner un servo-moteur sur le port numéro <bold>1</bold> de l'automate programmable à une fréquence PWM de <bold>50Hz</bold>. Dans la boucle, le palonnier du servo-moteur se positionnera à <bold>1000μs</bold>, puis 3 secondes plus tard, se positionnera à <bold>2000μs</bold>, pour ensuite attendre de nouveau 3 secondes à cette position, après quoi le programme bouclera.</text> <text><bold>Exemple d'utilisation de PwmWrite.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/PwmWrite.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Timer.h"</pink> <green>int</green> main() { PwmWrite myServo = PwmWrite (<pink>1</pink>); PwmWrite::start (<pink>50</pink>); <red>while</red> (<red>true</red>) { myServo.us (<pink>1000</pink>); Timer::pause (<pink>3000</pink>); <blue>//pause de 3 secondes</blue> myServo.us (<pink>2000</pink>); Timer::pause (<pink>3000</pink>); <blue>//pause de 3 secondes</blue> } <red>return</red> <pink>0</pink>; }</code> <text>Un objet <bold>myServo</bold> de type <bold>PwmWrite</bold> est déclaré, en paramètre est indiqué d'utiliser le port numéro <bold>1</bold> de l'automate programmable en sortie. Puis la fonction statique <bold>start</bold> est appelée prenant en paramètre la fréquence du PWM, ce qui démarre la génération PWM à la fréquence de <bold>50Hz</bold> dans cet exemple.</text> <caution>La fréquence PWM indiquée en paramètre avec la fonction statique <bold>start</bold> sera toujours appliquée à l'ensemble des ports choisis (un seul compteur 16 bits du microcontrôleur étant dédié à cette fonction).</caution> <text>Ensuite dans la boucle, dans un premier temps l'objet <bold>myServo</bold> appelle la fonction <bold>us</bold> qui prend en paramètre <bold>1000</bold>, la largeur d'impulsion en microsecondes, ce qui vient positionner le palonnier du servo-moteur à cet endroit. Puis 3000ms (3 secondes) plus tard, positionne le servo-moteur à <bold>2000μs</bold>.</text> <caution>Il vous est possible d'appeler la fonction <bold>us</bold> avant ou après avoir démarré et choisi la fréquence du PWM avec la fonction statique <bold>start</bold>. Ceci n'a en effet aucune incidence sur le fonctionnement puisque la fonction <bold>us</bold> retient les valeurs indiquées en paramètre lorsque le PWM n'est pas encore démarré.</caution> <text>La fonction <bold>us</bold> attend en paramètre un <bold>nombre décimal</bold> (float), ou entier si vous le souhaitez. Libre à vous de déterminer dans vos montages électroniques si vous avez besoin de générer des signaux PWM avec une largeur d'impulsion précise à la fraction de microseconde (c'est le cas de certains servo-moteurs ou contrôleurs de moteurs sans charbons), ou si vous n'avez besoin que d'une précision arrondie à l'entier.</text> <quote>À noter que la largeur d'impulsion des objets créés est à une valeur par défaut de <bold>0 microseconde</bold> si aucun changement de rapport cyclique n'a encore été effectué avec la fonction <bold>us</bold>.</quote> <text>Ce programme est simple, mais il permet en quelques lignes de comprendre facilement les fonctions de la classe PwmWrite.h.</text> <quote>Si besoin est, une fonction <bold>stop</bold> existe et permet d'arrêter la génération de signaux PWM sur tout les ports utilisés par la classe PwmWrite.h, un nouvel appel à la fonction <bold>start</bold> permet de redémarrer la génération la ou elle s'était arrêtée (elle garde en mémoire les dernières valeurs de largeur d'impulsion indiquées en paramètre).</quote> <title>Faire varier la luminosité d'une del :</title> <underline></underline> <text>L'exemple suivant va vous montrer comment modifier la luminosité d'une del grâce au changement de la largeur d'impulsion d'un signal PWM.</text> <text>En effet, notre rétine étant sensible à la persistance rétinienne, une simple <bold>variation du temps d'exposition à la lumière</bold> à une fréquence supérieure au rafraîchissement de la rétine, sera perçue par le cerveau comme une <bold>variation de la luminosité</bold>.</text> <text><bold>Exemple de variation de la luminosité d'une del avec un potentiomètre :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/PwmWrite.h"</pink> <purple>#include</purple> <pink>"../module/1284p/AnalogRead.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Math.h"</pink> <green>int</green> main() { PwmWrite myLed = PwmWrite (<pink>13</pink>); AnalogRead myPotentiometer = AnalogRead (<pink>25</pink>); PwmWrite::start (<pink>1000</pink>); <red>while</red> (<red>true</red>) { myPotentiometer.read(); myLed.us (Math::curve (<pink>0</pink>, myPotentiometer.value, <pink>1023</pink>, <pink>0</pink>, <pink>1000</pink>, <pink>0</pink>)); } <red>return</red> <pink>0</pink>; }</code> <text>Dans l'exemple, la fréquence du PWM est de <bold>1000Hz</bold> (bien plus rapide que le rafraîchissement de la rétine), ce qui donne un rapport cyclique (largeur d'impulsion) pouvant varier de <bold>0μs</bold> (0%) à <bold>1000μs</bold> (100%).</text> <text>La fonction statique <bold>curve</bold> de la classe <bold>Math.h</bold> permet d'interpoler la valeur 10 bits (0 à 1023) du potentiomètre en valeurs de <bold>0μs</bold> à <bold>1000μs</bold>. À une valeur de <bold>500μs</bold> (rapport cyclique de 50%), la del éclairerait à une luminosité d'environ 50%.</text> <title>Le choix du PWM matériel ou logiciel :</title> <underline></underline> <text><bold>Tous les ports de l'automate programmable</bold> peuvent générer des signaux PWM sur une précision théorique de 16 bits avec la classe PwmWrite.h (ce qui offre une grande souplesse d'utilisation), mais la façon dont ils sont générés (purement matérielle, ou partiellement logicielle) ainsi que les limites techniques (fréquences et précision) seront <bold>différentes suivant les ports que vous utiliserez</bold>.</text> <text><bold>Ports des automates programmables concernés par la génération de PWM 16 bits purement matérielle :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 10 (PB1) <br/>- Port 11 (PB2) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 13 (PD4) <br/>- Port 14 (PD5)</caution> <quote>La sélection d'un autre port que ceux indiqués ci-dessus passera la génération PWM en mode <bold>logiciel</bold>.</quote> <text>En mode <bold>logiciel</bold>, la génération de signaux PWM s'effectuant de manière <bold>séquentielle</bold> (ports après ports), <bold>la fréquence PWM choisie</bold> ainsi que <bold>le nombre de ports utilisés</bold> permettent de déterminer la largeur d'impulsion maximale possible avec une telle configuration.</text> <text><bold>Exemple de calcul du rapport cyclique maximum suivant la fréquence et le nombre de signaux PWM à générer en mode logiciel :</bold></text> <quote>Fréquence du PWM = <bold>1000Hz</bold> <br/>Nombre de signaux PWM à générer (ports utilisés) = <bold>4 ports</bold> <br/> <br/><bold>Limites maximales :</bold> <br/>Rapport cyclique = 1000000μs / (1000Hz * 4 ports) = <bold>250μs</bold> (max)</quote> <text>Dans cette configuration, la <bold>largeur d'impulsion maximale</bold> qui pourra être générée sera de <bold>250 microsecondes</bold> (rapport cyclique de 100%). Si vous indiquez un rapport cyclique supérieur à 250μs, ceci n'aura aucun impact sur le bon fonctionnement du PWM (celui-ci sera bloqué à 250μs par port utilisé dans tous les cas).</text> <text>De façon matérielle, <bold>PwmWrite.h</bold> permet de générer des signaux PWM à des fréquences très élevées (supérieures à 1MHz), mais vous devez prendre conscience que le nombre d'états possibles (précision) à de telles fréquences sera plus faible qu'à des fréquences inférieures. Ceci est dû aux contraintes même du matériel, en particulier du compteur 16 bits, de la fréquence d'horloge de 16MHz, et des diviseurs d'horloge du microcontrôleur.</text> <text><bold>Exemple de calcul du rapport cyclique maximum suivant la fréquence PWM choisie en mode matériel :</bold></text> <quote>Fréquence du PWM = <bold>1000Hz</bold> <br/> <br/><bold>Limites maximales :</bold> <br/>Rapport cyclique = 1000000μs / 1000Hz = <bold>1000μs</bold> (max)</quote> <text>En mode matériel, la largeur d'impulsion maximale n'est pas dépendante du nombre de ports utilisés.</text> <quote>À noter que la classe PwmWrite.h calculera <bold>le diviseur d'horloge le plus adapté</bold> en rapport avec la fréquence PWM choisie, ceci afin de garantir une précision de la largeur d'impulsion <bold>la plus élevée possible</bold>.</quote> <text>Cette précision de 16 bits théorique maximum est bien entendu égale et valable pour les deux méthodes de génération du PWM (matérielle et logicielle). Seul des limites en terme de fréquence maximale du PWM distinguent l'une ou l'autre méthode.</text> <caution>Rappelez-vous que c'est la classe PwmWrite.h qui par vos choix en terme de ports utilisés, <bold>sélectionne automatiquement pour vous</bold> le mode de génération PWM matériel ou logiciel.</caution> <text>Dans tous les cas, si un problème vient à se poser à vous en terme de fréquence maximale, de précision, ou de largeur d'impulsion maximale possible, il convient alors avant toute chose de comprendre et de s'interroger sur la logique matérielle du composant, et de relire ce que j'ai indiqué plus haut afin d'en maîtriser les contraintes et les limites techniques (ceci ne doit en aucun cas être un frein à vos projets).</text> <text><bold>Ports des automates programmables concernés par la génération du PWM :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 1 (PD0) <br/>- Port 2 (PD1) <br/>- Port 3 (PD2) <br/>- Port 4 (PD3) <br/>- Port 5 (PD4) <br/>- Port 6 (PD5) <br/>- Port 7 (PD6) <br/>- Port 8 (PD7) <br/>- Port 9 (PB0) <br/>- Port 10 (PB1) <br/>- Port 11 (PB2) <br/>- Port 12 (PB3) <br/>- Port 13 (PB4) <br/>- Port 14 (PB5) <br/>- Port 15 (PC0) <br/>- Port 16 (PC1) <br/>- Port 17 (PC2) <br/>- Port 18 (PC3) <br/>- Port 19 (PC4) <br/>- Port 20 (PC5) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 1 (PB0) <br/>- Port 2 (PB1) <br/>- Port 3 (PB2) <br/>- Port 4 (PB3) <br/>- Port 5 (PB4) <br/>- Port 6 (PB5) <br/>- Port 7 (PB6) <br/>- Port 8 (PB7) <br/>- Port 9 (PD0) <br/>- Port 10 (PD1) <br/>- Port 11 (PD2) <br/>- Port 12 (PD3) <br/>- Port 13 (PD4) <br/>- Port 14 (PD5) <br/>- Port 15 (PD6) <br/>- Port 16 (PD7) <br/>- Port 17 (PC0) <br/>- Port 18 (PC1) <br/>- Port 19 (PC2) <br/>- Port 20 (PC3) <br/>- Port 21 (PC4) <br/>- Port 22 (PC5) <br/>- Port 23 (PC6) <br/>- Port 24 (PC7) <br/>- Port 25 (PA7) <br/>- Port 26 (PA6) <br/>- Port 27 (PA5) <br/>- Port 28 (PA4) <br/>- Port 29 (PA3) <br/>- Port 30 (PA2) <br/>- Port 31 (PA1) <br/>- Port 32 (PA0)</caution> <text>Récapitulatif des fonctions de cette classe :</text> <code>PwmWrite (<green>const unsigned char</green> PIN); <green>static void</green> start (<green>const unsigned long</green> FREQUENCY); <green>void</green> us (<green>const float</green> US); <green>static void</green> stop();</code> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleSoundWrite.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleSoundWrite"><back>Retour</back></a> <a href="exampleTimer.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Jouer des sons avec SoundWrite.h</title> <underline></underline> <text>Lorsque l'on développe un projet demandant une interface entre l'homme et la machine, il est généralement indispensable de pouvoir <bold>communiquer des informations à l'utilisateur à l'aide d'une interface sonore</bold> via un buzzer ou un haut-parleur, c'est ce que permet d'effectuer la classe <bold>SoundWrite.h</bold>.</text> <a href="photo/dsc07380.jpg"><img src="thumbnail/dsc07380.jpg"></img></a> <text>Avec SoundWrite.h il est possible très simplement de générer des sons de la <bold>fréquence</bold> et de la <bold>durée</bold> souhaitée, ainsi que de <bold>créer des mélodies</bold> grâce au principe d'ajout séquentiel de notes dans ce qui s'apparente à une partition.</text> <text><bold>Exemple pour jouer un son avec SoundWrite.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/SoundWrite.h"</pink> <green>int</green> main() { SoundWrite::pin (<pink>1</pink>); SoundWrite::play (<pink>440</pink>, <pink>1000</pink>); <red>while</red> (<red>true</red>) { } <red>return</red> <pink>0</pink>; }</code> <text>Dans l'exemple ci-dessus, l'instance de la classe SoundWrite.h appelle la fonction statique <bold>pin</bold>, qui prend en paramètre <bold>1</bold>, le numéro du port (ou broche) de l'automate sur lequel est connecté un périphérique audio (buzzer, haut-parleur, etc...).</text> <text>À la suite la fonction statique <bold>play</bold> est appelée, elle prend un 1er paramètre <bold>440</bold> qui est le choix de la fréquence en Hertz du son qui va être joué (ici un "la" conventionnel à 440Hz), et un 2ème paramètre <bold>1000</bold> qui défini la durée de lecture de cette sonorité exprimée en millisecondes.</text> <quote>Même si vous n'avez pas besoin d'exécuter des instructions dans la boucle <bold>while</bold>, cette dernière reste importante car elle permet au microcontrôleur de continuer l'exécution du code (qui met en fonction l'oscillateur piloté par la classe SoundWrite.h).</quote> <caution>Dans le cas contraire, l'exécution terminerait après <bold>return 0;</bold>, et le microcontrôleur s'arrêterait là de sorte qu'aucun son n'aurait le temps d'être entendu !</caution> <text><bold>Ports des automates programmables concernés par la génération de sons :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 1 (PD0) <br/>- Port 2 (PD1) <br/>- Port 3 (PD2) <br/>- Port 4 (PD3) <br/>- Port 5 (PD4) <br/>- Port 6 (PD5) <br/>- Port 7 (PD6) <br/>- Port 8 (PD7) <br/>- Port 9 (PB0) <br/>- Port 10 (PB1) <br/>- Port 11 (PB2) <br/>- Port 12 (PB3) <br/>- Port 13 (PB4) <br/>- Port 14 (PB5) <br/>- Port 15 (PC0) <br/>- Port 16 (PC1) <br/>- Port 17 (PC2) <br/>- Port 18 (PC3) <br/>- Port 19 (PC4) <br/>- Port 20 (PC5) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 1 (PB0) <br/>- Port 2 (PB1) <br/>- Port 3 (PB2) <br/>- Port 4 (PB3) <br/>- Port 5 (PB4) <br/>- Port 6 (PB5) <br/>- Port 7 (PB6) <br/>- Port 8 (PB7) <br/>- Port 9 (PD0) <br/>- Port 10 (PD1) <br/>- Port 11 (PD2) <br/>- Port 12 (PD3) <br/>- Port 13 (PD4) <br/>- Port 14 (PD5) <br/>- Port 15 (PD6) <br/>- Port 16 (PD7) <br/>- Port 17 (PC0) <br/>- Port 18 (PC1) <br/>- Port 19 (PC2) <br/>- Port 20 (PC3) <br/>- Port 21 (PC4) <br/>- Port 22 (PC5) <br/>- Port 23 (PC6) <br/>- Port 24 (PC7) <br/>- Port 25 (PA7) <br/>- Port 26 (PA6) <br/>- Port 27 (PA5) <br/>- Port 28 (PA4) <br/>- Port 29 (PA3) <br/>- Port 30 (PA2) <br/>- Port 31 (PA1) <br/>- Port 32 (PA0)</caution> <title>Jouer une mélodie :</title> <underline></underline> <text>Comme évoqué plus haut, il est possible avec la classe SoundWrite.h de jouer une <bold>suite séquentielle de sonorités</bold> par le simple ajout de notes à une partition virtuelle.</text> <text><bold>Exemple pour créer et jouer une mélodie avec SoundWrite.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/SoundWrite.h"</pink> <green>int</green> main() { SoundWrite::pin (<pink>1</pink>); SoundWrite::add (<pink>200</pink>, <pink>250</pink>); SoundWrite::add (<pink>400</pink>, <pink>250</pink>); SoundWrite::add (<pink>800</pink>, <pink>250</pink>); SoundWrite::add (<pink>1200</pink>, <pink>250</pink>); SoundWrite::add (<pink>0</pink>, <pink>500</pink>); SoundWrite::add (<pink>800</pink>, <pink>500</pink>); SoundWrite::add (<pink>400</pink>, <pink>500</pink>); SoundWrite::play (<pink>0</pink>, <pink>0</pink>); <red>while</red> (<red>true</red>) { } <red>return</red> <pink>0</pink>; }</code> <text>Dans la même logique que l'exemple précédent, après avoir défini le numéro du port (à l'aide de la fonction pin) qui sera utilisé pour générer des sons, une fonction <bold>add</bold> est appelée autant de fois qu'il est nécessaire d'ajouter des sons (ou notes), et prend les mêmes paramètres que la fonction <bold>play</bold> (fréquence et durée), seul la finalité est différente. En effet avec <bold>play</bold> le son est immédiatement joué, alors qu'avec <bold>add</bold> les sons sont stockés les uns à la suite des autres, après quoi la partition ainsi créée sera jouée en appelant la fonction <bold>play</bold> avec en paramètres une fréquence et une durée égales à 0.</text> <caution>À noter qu'un <bold>maximum de 64 notes consécutives</bold> (avant l'appel à la fonction play) peuvent être créées, ce qui pourra répondre au besoin de la majorité des projets.</caution> <text>Il est possible de créer des <bold>blancs</bold> (temps morts), c'est-à-dire des moments dans la mélodie où aucune sonorité n'est jouée. Pour se faire il suffit simplement d'indiquer une <bold>fréquence égale à 0</bold> lors de l'appel à la fonction <bold>add</bold>.</text> <quote>Il existe également une fonction <bold>modulate</bold>, permettant de moduler la fréquence du son en cours de lecture (pour créer un son d'une durée non définie avec la fonction play, indiquez une durée égale à 0), et également une fonction <bold>stop</bold>, qui a pour but d'arrêter la lecture des sons immédiatement et de vider la partition virtuelle.</quote> <text>Récapitulatif des fonctions de cette classe :</text> <code><green>static void</green> pin (<green>const unsigned char</green> PIN); <green>static void</green> play (<green>const unsigned int</green> FREQUENCY, <green>const unsigned int</green> DURATION); <green>static void</green> add (<green>const unsigned int</green> FREQUENCY, <green>const unsigned int</green> DURATION); <green>static void</green> modulate (<green>const unsigned int</green> FREQUENCY); <green>static void</green> stop();</code> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier exampleTimer.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#exampleTimer"><back>Retour</back></a> <a href="exampleDelay.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>La gestion du temps avec Timer.h</title> <underline></underline> <text>La plupart des projets requièrent la dimension temporelle pour pouvoir fonctionner, c'est pourquoi <bold>Timer.h</bold> apporte la temporisation des événements et des actions à effectuer dans un programme.</text> <caution>Contrairement à d'autres plates-formes de développement pour microcontrôleurs à registres 8 bits, la classe Timer.h utilise un compteur qui <bold>fonctionne à une fréquence de 2MHz sur une largeur mémoire de 64 bits</bold>, de sorte que le temps peut être compté à partir de zéro <bold>toutes les microsecondes</bold> pendant bien plus longtemps que la durée de vie du microcontrôleur lui-même (plusieurs centaines de milliers d'années), en effet une largeur mémoire de seulement 32 bits imposerait un retour à zéro (overflow) au bout d'un peu plus d'une demi-heure tout au plus, ce qui serait très limitant pour bons nombres de projets !</caution> <text>Les compteurs (ou timers) que vous déclarez avec la classe Timer.h se présentent sous la forme d'objets (c'est le principe de beaucoup de mes classes), il est donc possible de créer <bold>plusieurs compteurs ayant tous des fonctions indépendantes</bold> dans votre programme.</text> <text><bold>Exemple d'utilisation de Timer.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/Timer.h"</pink> <green>int</green> main() { Timer myTimer = Timer(); myTimer.start (<pink>0</pink>); <red>while</red> (<red>true</red>) { myTimer.state(); <blue>//myTimer.s est le temps écoulé en secondes</blue> <blue>//myTimer.ms est le temps écoulé en millisecondes</blue> <blue>//myTimer.us est le temps écoulé en microsecondes</blue> } <red>return</red> <pink>0</pink>; }</code> <text>Dans cet exemple, un objet <bold>myTimer</bold> de type <bold>Timer</bold> est déclaré, puis via cet objet, la fonction <bold>start</bold> est appelée prenant en paramètre <bold>0</bold>, le temps de départ indiqué en millisecondes :</text> <quote>Dans la plupart des cas nous souhaitons qu'un compteur <bold>démarre à 0</bold> (comme l'exemple) lorsque la fonction <bold>start</bold> est appelée, mais si vous le souhaitez vous pouvez le faire partir à une autre valeur.</quote> <text>Plus loin cet objet <bold>myTimer</bold> appelle la fonction <bold>state</bold> (état) dans une boucle ce qui permet de mettre à jour les variables <bold>s</bold> (secondes), <bold>ms</bold> (millisecondes), et <bold>us</bold> (microsecondes) que vous pourrez utiliser dans vos conditions logiques et divers calculs.</text> <title>La fonction pause :</title> <underline></underline> <text>Malgré que l'utilisation première de la classe Timer.h permet la création d'objets instanciés indépendants, il est néanmoins parfois utile de pouvoir bénéficier de <bold>pauses bloquantes</bold> appelées de façon statique sans objet, directement à partir de la classe concernée. La fonction <bold>pause</bold> remplie cette fonctionnalité.</text> <text><bold>Exemple de clignotement d'une del avec Timer.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/GpioWrite.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Timer.h"</pink> <green>int</green> main() { GpioWrite myLed = GpioWrite (<pink>1</pink>); <red>while</red> (<red>true</red>) { myLed.toggle(); Timer::pause (<pink>1000</pink>); } <red>return</red> <pink>0</pink>; }</code> <text>Contrairement au premier exemple et l'utilisation d'un objet, ici la fonction statique <bold>pause</bold> est directement appelée à partir de la classe <bold>Timer.h</bold>. Cette fonction prend en paramètre <bold>1000</bold>, la durée de la pause en millisecondes.</text> <quote>Dans l'exemple ci-dessus, si une del était branchée sur le port 1 de l'automate programmable, elle clignoterait toutes les secondes (1000 millisecondes), mais dans ces conditions <bold>le programme ne pourrait pas faire autre chose que gérer la commutation du port numéro 1</bold>, la pause est dite <bold>bloquante</bold> car rien d'autre ne peut être effectué en parallèle. L'exemple suivant résout ce problème.</quote> <text><bold>Exemple de clignotement d'une del sans pause bloquante avec Timer.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/GpioWrite.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Timer.h"</pink> <green>int</green> main() { GpioWrite myLed = GpioWrite (<pink>1</pink>); Timer myTimer = Timer(); myTimer.start (<pink>0</pink>); <red>while</red> (<red>true</red>) { myTimer.state(); <blue>//tâche à effectuer toutes les 1000ms :</blue> <red>if</red> (myTimer.ms >= <pink>1000</pink>) { myLed.toggle(); myTimer.start (<pink>0</pink>); } <blue>//autres tâches à effectuer en parallèle...</blue> } <red>return</red> <pink>0</pink>; }</code> <text>L'exemple ci-dessus montre bien que lors d'un tour de boucle, si à partir du démarrage du compteur <bold>le temps écoulé est supérieur ou égal à 1000 millisecondes</bold>, l'exécution rentre dans la condition logique, effectue la commutation de la del, redémarre le compteur à zéro, et à la suite exécute toutes les autres tâches du programme <bold>sans passer par un état bloquant</bold> comme c'était le cas précédemment.</text> <quote>Dans une problématique comme celle-ci, plusieurs solutions sont souvent possibles, c'est ce que montre l'exemple suivant avec l'utilisation d'une <bold>variable qui est incrémentée pour suivre l'avancée du temps imposé par le compteur</bold> (ce qui évite un cumul d'erreurs dans le temps), ainsi ce dernier n'a pas besoin d'être redémarré à zéro à chaque fois.</quote> <text><bold>Autre exemple de clignotement d'une del sans pause bloquante avec Timer.h :</bold></text> <code><purple>#include</purple> <pink>"../module/1284p/GpioWrite.h"</pink> <purple>#include</purple> <pink>"../module/1284p/Timer.h"</pink> <green>int</green> main() { GpioWrite myLed = GpioWrite (<pink>1</pink>); Timer myTimer = Timer(); <green>unsigned long long</green> timePrevious = <pink>0</pink>; myTimer.start (<pink>0</pink>); <red>while</red> (<red>true</red>) { myTimer.state(); <blue>//tâche à effectuer toutes les 1000ms :</blue> <red>if</red> (myTimer.ms - timePrevious >= <pink>1000</pink>) { myLed.toggle(); timePrevious += <pink>1000</pink>; } <blue>//autres tâches à effectuer en parallèle...</blue> } <red>return</red> <pink>0</pink>; }</code> <text>Cet exemple-ci est plus précis que les trois précédents car il met en jeu la variable <bold>timePrevious</bold> qui au passage dans la condition logique n'est pas initialisée sur le temps écoulé du compteur comme on pourrait être tenté de le programmer, mais plutôt bêtement incrémentée de <bold>1000</bold>, ce qui compense et ne tient pas compte du temps d'exécution de la condition logique elle-même, de la commutation de la del, et du reste du programme.</text> <quote>Pour parfaire l'utilisation de la classe Timer.h, une fonction <bold>stop</bold> existe et permet d'arrêter l'écoulement du temps, dans cette situation les variables <bold>s</bold> (secondes), <bold>ms</bold> (millisecondes), et <bold>us</bold> (microsecondes) resteront à leurs dernières valeurs mises à jour lors de l'appel de la fonction <bold>state</bold>, ceci avant l'appel à la fonction <bold>stop</bold>.</quote> <text>Récapitulatif des fonctions et variables de cette classe :</text> <code><green>unsigned long long</green> s = <pink>0</pink>; <green>unsigned long long</green> ms = <pink>0</pink>; <green>unsigned long long</green> us = <pink>0</pink>; Timer(); <green>void</green> start (<green>const unsigned long long</green> TIME_START); <green>void</green> state(); <green>void</green> stop(); <green>static void</green> pause (<green>const unsigned long long</green> DURATION);</code> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier howToInstallModule.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#howToInstallModule"><back>Retour</back></a> <a href="howToProgramWidthModule.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Comment installer MODULE</title> <underline></underline> <text>Installer MODULE est un grand mot, en réalité MODULE ne demande qu'à être téléchargé et décompressé dans le répertoire de votre choix :</text> <a href="download/cpp/module.zip"><download>Télécharger <bold>MODULE</bold></download></a> <text><bold>Dans l'archive module.zip vous trouverez 2 répertoires :</bold> <br/>- module, contenant la programmation C++ de MODULE. <br/>- example, contenant un exemple de fichier main.cpp et les routines de compilation pour Linux et Windows.</text> <text>Le répertoire <bold>module</bold> contient 8 sous-répertoires : <br/>- 48p, pour programmer l'ATmega48P. <br/>- 88p, pour programmer l'ATmega88P. <br/>- 168p, pour programmer l'ATmega168P. <br/>- 328p, pour programmer l'ATmega328P. <br/>- 164p, pour programmer l'ATmega164P. <br/>- 324p, pour programmer l'ATmega324P. <br/>- 644p, pour programmer l'ATmega644P. <br/>- 1284p, pour programmer l'ATmega1284P.</text> <text>Dans ces répertoires se trouvent toutes les classes du programme MODULE optimisées respectivement pour l'ATmega48P, l'ATmega88P, l'ATmega168P, l'ATmega328P, l'ATmega164P, l'ATmega324P, l'ATmega644P ou l'ATmega1284P, ce qui comprend les <bold>fichiers d'en-tête</bold> (.h) que vous aurez à inclure dans vos projets si besoin, et les <bold>fichiers C++</bold> (.cpp) dans lesquels on trouve les fonctions.</text> <caution>Vous pouvez modifier le contenu de ces répertoires ou de ces fichiers si vous souhaitez modifier et améliorer MODULE !</caution> <text>Le répertoire <bold>example</bold> contient la <bold>routine Linux</bold> (Compiler.sh) et la <bold>routine Windows</bold> (Compiler.bat) pour compiler et envoyer votre programme dans l'automate programmable (le microcontrôleur plus exactement) via un programmateur. Il contient également un fichier <bold>main.cpp</bold>, c'est le plus important car c'est dans ce fichier que vous écrirez votre programme en langage C++.</text> <quote>Ce répertoire <bold>example</bold> est un exemple pour comprendre comment démarrer simplement la programmation de vos projets avec MODULE.</quote> <text>Si vous utilisez le système d'exploitation Linux vous pouvez utiliser la routine Linux (Compiler.sh), et de même si vous utilisez le système d'exploitation Windows vous pouvez utiliser la routine Windows (Compiler.bat).</text> <title>Le fichier main.cpp et l'ATmega1284P ?</title> <underline></underline> <text>Par défaut, dans le fichier <bold>main.cpp</bold> (qui sert à écrire votre programme) présent dans le répertoire <bold>example</bold>, les inclusions (include) des <bold>fichiers d'en-tête</bold> (.h) sont précédés du répertoire <bold>1284p</bold> dans le chemin d'accès. Ceci permet donc comme expliqué précédemment, de programmer l'automate programmable équipé de l'ATmega1284P, c'est-à-dire l'automate programmable <bold>MODULABLE M32</bold>.</text> <caution>Si vous souhaitez programmer un autre microcontrôleur que l'ATmega1284P, par exemple l'ATmega328P, il vous suffit de modifier les chemins d'accès aux fichiers d'en-tête <bold>1284p</bold> par <bold>328p</bold> (et d'utiliser l'automate programmable MODULABLE M20).</caution> <text>Libre à vous de choisir d'utiliser l'automate programmable <bold>MODULABLE M20</bold> qui peut être équipé des microcontrôleurs ATmega48P, ATmega88P, ATmega168P, ou ATmega328P, ou l'automate programmable <bold>MODULABLE M32</bold> qui peut être équipé des microcontrôleurs ATmega164P, ATmega324P, ATmega644P ou ATmega1284P.</text> <text>Pour connaître précisément les caractéristiques de ces deux automates programmables et télécharger les plans de fabrication, je vous conseille d'aller voir dans les sections "Téléchargements" et "Fabrications et diverses réalisations" en page d'accueil.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier howToProgramWidthModule.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#howToProgramWidthModule"><back>Retour</back></a> <a href="complementaryToolOfModule.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Comment programmer avec MODULE</title> <underline></underline> <text>Pour programmer avec MODULE, vous avez à disposition <bold>26 classes</bold> organisées par fonctions (sous la forme de fichiers d'en-tête et de fichiers C++). Toutes ces classes sont à la fois complètement indépendantes les unes des autres (au niveau du code source C++) et peuvent aussi fonctionner toutes ensembles sans problèmes d'interactions.</text> <text><bold>Les classes de MODULE :</bold></text> <quote>GpioRead.h <br/>GpioWrite.h <br/>AnalogRead.h <br/>InterruptRead.h <br/>PwmRead.h <br/>PwmWrite.h <br/>SoundWrite.h <br/> <br/>Timer.h <br/>Delay.h <br/>Period.h <br/> <br/>Math.h <br/>Iteration.h <br/>Average.h <br/>Filter.h <br/>Hysteresis.h <br/>Random.h <br/> <br/>Max7219.h <br/>Mpu6050.h <br/>Bno055.h <br/>Hmc5883l.h <br/>Bmp180.h <br/>Nrf24l01p.h <br/> <br/>Network.h <br/> <br/>Memory.h <br/>Power.h <br/>Tool.h</quote> <text><bold>Pour comprendre comment utiliser les classes de MODULE :</bold> <br/>- Vous pouvez lire les exemples que je vous propose (voir plus bas) qui s'étofferont au fil du temps (disponibles dans la section "Exemples simples à l'aide de MODULE" en page d'accueil). <br/>- Vous pouvez copier le code source des mes projets.</text> <text>Ou bien il est possible de regarder dans le répertoire <bold>module</bold> (dans l'archive de MODULE téléchargeable en page d'accueil dans la section "Téléchargements") le contenu des fichiers d'en-tête <bold>.h</bold> des classes correspondantes au microcontrôleur que vous souhaitez programmer, ce qui vous donnera une bonne idée de comment utiliser les fonctions et variables si vous êtes déjà bien familiarisé à la programmation C++.</text> <title>Les exemples pour l'ATmega1284P :</title> <underline></underline> <text>Historiquement, j'ai débuté la programmation de MODULE avec l'ATmega328P et finalisé un certain nombre de projets avec. Mais depuis j'ai conçu un automate programmable plus intéressant sur bons nombres de points qui peut être équipé (entre autres) de l'ATmega1284P (que j'utilise beaucoup), ce qui explique que les exemples que vous pouvez lire soient orientés vers ce microcontrôleur.</text> <caution>Tous les exemples proposés dans la section "Exemples simples à l'aide de MODULE" en page d'accueil sont <bold>écrits pour l'automate programmable MODULABLE M32 équipé d'un ATmega1284P</bold>, mais bien évidement cela reste de votre choix de programmer pour l'un des 7 autres microcontrôleurs pris en charge par MODULE !</caution> <text>Si par exemple vous souhaitez programmer pour le microcontrôleur ATmega328P plutôt que l'ATmega1284P, il vous suffit de modifier les chemins d'accès aux fichiers d'en-tête <bold>1284p</bold> par <bold>328p</bold> dans les exemples proposés, ainsi que d'adapter le numéro de certains ports de l'automate programmable par rapport au microcontrôleur choisi.</text> <quote>Dans tous les cas, <bold>vous disposez exactement des mêmes fonctionnalités avec MODULE</bold> qu'il s'agisse de programmer l'ATmega48P, l'ATmega88P, l'ATmega168P, l'ATmega328P, l'ATmega164P, l'ATmega324P, l'ATmega644P ou l'ATmega1284P.</quote> <text>Seul <bold>le nombre de ports disponibles</bold> par fonctionnalité et <bold>leurs distribution sur les automates programmables</bold> peut varier (c'est-à-dire les ports reliés aux fonctions USART, SPI, TWI, PWM, convertisseur analogique/numérique, le nombre de GPIO, etc...).</text> <text>Libre à vous de choisir d'utiliser l'automate programmable <bold>MODULABLE M20</bold> qui peut être équipé des microcontrôleurs ATmega48P, ATmega88P, ATmega168P, ou ATmega328P, ou l'automate programmable <bold>MODULABLE M32</bold> qui peut être équipé des microcontrôleurs ATmega164P, ATmega324P, ATmega644P ou ATmega1284P.</text> <text>Pour connaître précisément les caractéristiques de ces deux automates programmables et télécharger les plans de fabrication, je vous conseille d'aller voir dans les sections "Téléchargements" et "Fabrications et diverses réalisations" en page d'accueil.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier index.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Accueil</title> <underline></underline> <text>Toutes les photos de mes projets :</text> <a href="photo.html"><img src="thumbnail/dsc06923.jpg"></img></a> <a href="photo.html"><img src="thumbnail/dsc06711.jpg"></img></a> <title>Le projet MODULE :</title> <underline></underline> <text>Toutes les informations pour comprendre le projet MODULE :</text> <a id="understandWhatIsModule" href="understandWhatIsModule.html"><download><bold>Comprendre</bold> ce qu'est MODULE</download></a> <br/><a id="howToInstallModule" href="howToInstallModule.html"><download><bold>Comment installer</bold> MODULE</download></a> <br/><a id="howToProgramWidthModule" href="howToProgramWidthModule.html"><download><bold>Comment programmer</bold> avec MODULE</download></a> <br/><a id="complementaryToolOfModule" href="complementaryToolOfModule.html"><download><bold>Les outils complémentaires</bold> de MODULE</download></a> <title>Exemples simples à l'aide de MODULE :</title> <underline></underline> <text>Pour comprendre et débuter rapidement la programmation avec MODULE :</text> <a id="exampleGpioRead" href="exampleGpioRead.html"><download>Lire l'état d'un bouton avec <bold>GpioRead.h</bold></download></a> <br/><a id="exampleGpioWrite" href="exampleGpioWrite.html"><download>Allumer une del avec <bold>GpioWrite.h</bold></download></a> <br/><a id="exampleAnalogRead" href="exampleAnalogRead.html"><download>Lire un potentiomètre avec <bold>AnalogRead.h</bold></download></a> <br/><a id="exampleInterruptRead" href="exampleInterruptRead.html"><download>Les interruptions avec <bold>InterruptRead.h</bold></download></a> <br/><a id="examplePwmRead" href="examplePwmRead.html"><download>Lire un récepteur R/C avec <bold>PwmRead.h</bold></download></a> <br/><a id="examplePwmWrite" href="examplePwmWrite.html"><download>Les servo-moteurs avec <bold>PwmWrite.h</bold></download></a> <br/><a id="exampleSoundWrite" href="exampleSoundWrite.html"><download>Jouer des sons avec <bold>SoundWrite.h</bold></download></a> <br/><a id="exampleTimer" href="exampleTimer.html"><download>La gestion du temps avec <bold>Timer.h</bold></download></a> <br/><a id="exampleDelay" href="exampleDelay.html"><download>Les délais simplifiés avec <bold>Delay.h</bold></download></a> <br/><a id="exampleMax7219" href="exampleMax7219.html"><download>Afficher des caractères avec <bold>Max7219.h</bold></download></a> <br/><a id="exampleNrf24l01p" href="exampleNrf24l01p.html"><download>Une radiocommande avec <bold>Nrf24l01p.h</bold></download></a> <title>Fabrications et diverses réalisations :</title> <underline></underline> <text>Toutes mes fabrications et réalisations présentées et expliquées ici.</text> <text><bold>Cartes électroniques</bold> (détails de mes circuits imprimés) :</text> <a id="projectModulableM32" href="projectModulableM32.html"><download>L'automate programmable <bold>MODULABLE M32</bold></download></a> <br/><a id="projectModulableM20" href="projectModulableM20.html"><download>L'automate programmable <bold>MODULABLE M20</bold></download></a> <br/><a id="projectMax7219Digit" href="projectMax7219Digit.html"><download><bold>L'afficheur à digits</bold> MAX7219</download></a> <br/><a id="projectMax7219DigitMini" href="projectMax7219DigitMini.html"><download>Le <bold>mini afficheur à digits </bold> MAX7219</download></a> <br/><a id="projectMax7219Matrix" href="projectMax7219Matrix.html"><download><bold>L'afficheur à matrice</bold> MAX7219</download></a> <br/><a id="projectBuzzer" href="projectBuzzer.html"><download>Le <bold>buzzer</bold> piloté</download></a> <br/><a id="projectHoldSwitch" href="projectHoldSwitch.html"><download>L'interrupteur <bold>d'alimentation maintenue</bold></download></a> <br/><a id="projectMax604" href="projectMax604.html"><download>Le <bold>régulateur de tension +3.3V</bold></download></a> <br/><a id="projectGeigerBoostConverter" href="projectGeigerBoostConverter.html"><download><bold>L'élévateur de tension +400V</bold> pour tube Geiger</download></a> <br/><a id="projectPinHeader" href="projectPinHeader.html"><download>La <bold>platine de distribution</bold> 24 broches</download></a> <text><bold>Projets divers</bold> (en rapport ou non avec le projet MODULE) :</text> <a id="projectRadioControl" href="projectRadioControl.html"><download>La <bold>radiocommande</bold></download></a> <br/><a id="projectQuadcopter" href="projectQuadcopter.html"><download>Le <bold>quadri-hélicoptère</bold></download></a> <br/><a id="projectGeigerCounter" href="projectGeigerCounter.html"><download>Le <bold>compteur Geiger</bold></download></a> <br/><a id="projectIntervalometer" href="projectIntervalometer.html"><download><bold>L'intervallomètre</bold> pour la photographie</download></a> <br/><a id="projectUselessMachine" href="projectUselessMachine.html"><download>Les machines <bold>inutiles</bold></download></a> <br/><a id="projectSite" href="projectSite.html"><download>Le <bold>code source du site</bold></download></a> <title>Outils divers :</title> <underline></underline> <text>Routine d'automatisation de tâches pour dessiner avec le logiciel KiCad :</text> <a id="toolBmpToMod" href="toolBmpToMod.html"><download>Conversion d'images <bold>.bmp vers .mod</bold></download></a> <title>Téléchargements :</title> <underline></underline> <text>Le programme <bold>MODULE</bold> en langage C++ :</text> <a href="download/cpp/module.zip"><download>Télécharger <bold>MODULE</bold></download></a> <text>Les programmes et les plans de fabrication associés au projet MODULE :</text> <a id="download" href="download.html"><download>Tous mes projets à <bold>télécharger</bold></download></a> <title>Services :</title> <underline></underline> <text>Il m'est possible si vous le souhaitez de fabriquer pour vous un circuit (à l'unité, ou très petites séries), dans la liste présentée ci-dessus dont vous auriez besoin pour vos projets, et de vous l'envoyer par la poste.</text> <caution>Bien entendu, tout sera à vos frais (coût de la plaque PCB, composants électroniques, main-d'œuvre d'assemblage, expédition).</caution> <text>Si tel est le cas, n'hésitez pas à me contacter par mail (contact@sylvainmahe.site) pour me faire part de votre demande.</text> <title>Licence officielle :</title> <underline></underline> <text>La licence officielle du projet MODULE, des différents programmes, des documentations, des circuits électroniques, et du site associé au projet :</text> <a id="license" href="license.html"><download>La <bold>licence officielle</bold></download></a> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier license.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#license"><back>Retour</back></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>La licence officielle</title> <underline></underline> <text>Tout ce qui est proposé en téléchargement et visualisation sur mon site (hors liens hypertexte vers des sources externes), est <bold>libre de droits d'auteur et à sources ouvertes et modifiables</bold> (open source), ce qui comprend les fichiers de programmes (codes sources), les différents exemples mis à disposition, les plans de fabrication de mes circuits électroniques, ainsi que le site lui-même (voir le code source du site disponible dans la section "Fabrications et diverses réalisations" en page d'accueil).</text> <quote>Il existe bon nombre de licences officielles disponibles et valides d'un point de vue juridique en ce qui concerne le logiciel libre, mais ne me reconnaissant dans aucunes de ces licences, j'ai préféré écrire quelques phrases simples qui me semblent de bon sens (voir ci-dessous).</quote> <text>Bien évidemment, sans être naïf et tout en prenant conscience du caractère non-officiel de ma propre licence au regard de la loi et de la société en général telle qu'elle a été établie à notre insu sans être consulté (finalement qu'est ce qui est officiel et qui ne l'est pas ?).</text> <text>Voici <bold>quelques pratiques de bon sens</bold> et une <bold>éthique à vous engager de respecter</bold> si vous faites usage de mes produits :</text> <caution>Tout ce qui est proposé en téléchargement et visualisation sur mon site peut être récupéré, utilisé, et modifié sur un système informatique autre que mon ordinateur personnel ainsi que le serveur qui héberge mon site (de sorte de maintenir les versions officielles des fichiers sur mon site, le site lui-même y compris).</caution> <caution>Tout ce qui est proposé en téléchargement et visualisation sur mon site ne peut être utilisé à des fins de pouvoir sur autrui, de destruction de la nature, pour contraindre ou discriminer une personne ou un peuple, ou encore asservir (esclavage) ou détruire des animaux (humains ou non-humains).</caution> <caution>Je ne fabrique pas de composants électroniques, ils sont donc soumis aux lois et règles établies par les constructeurs eux-mêmes (il vous appartient donc de vous renseigner en lisant les documentations techniques officielles des composants que vous mettez en œuvre dans vos projets).</caution> <caution>Les déchets résultants de la fabrication et de l'utilisation de mes circuits électroniques et des différents composants qui les animent doivent être traités dans un cycle adapté (démantèlement, tri sélectif, recyclage, réparation, réutilisation, etc...).</caution> <caution>Je ne pourrais être tenu pour responsable si vous faites une mauvaise utilisation des mes produits (c'est-à-dire de tout ce qui est proposé sur mon site).</caution> <caution>Seule la présente licence est valide et ne peut être modifiée.</caution> <text>Il vous appartient donc de faire une bonne utilisation des fichiers de programmes, documentations (exemples de programmation), circuits électroniques (etc...), proposés sur mon site.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier photo.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html"><back>Retour</back></a> <a href="understandWhatIsModule.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Toutes les photos de mes projets</title> <underline></underline> <text>Tous mes projets récents et plus anciens en photos (triées par ordre anti-chronologique) :</text> <a href="photo/dsc07897.jpg"><img src="thumbnail/dsc07897.jpg"></img></a> <a href="photo/dsc07895.jpg"><img src="thumbnail/dsc07895.jpg"></img></a> <a href="photo/dsc07892.jpg"><img src="thumbnail/dsc07892.jpg"></img></a> <a href="photo/dsc07891.jpg"><img src="thumbnail/dsc07891.jpg"></img></a> <a href="photo/dsc07890.jpg"><img src="thumbnail/dsc07890.jpg"></img></a> <a href="photo/dsc07888.jpg"><img src="thumbnail/dsc07888.jpg"></img></a> <a href="photo/dsc07887.jpg"><img src="thumbnail/dsc07887.jpg"></img></a> <a href="photo/dsc07886.jpg"><img src="thumbnail/dsc07886.jpg"></img></a> <a href="photo/dsc07885.jpg"><img src="thumbnail/dsc07885.jpg"></img></a> <a href="photo/dsc07884.jpg"><img src="thumbnail/dsc07884.jpg"></img></a> <a href="photo/dsc07875.jpg"><img src="thumbnail/dsc07875.jpg"></img></a> <a href="photo/dsc07874.jpg"><img src="thumbnail/dsc07874.jpg"></img></a> <a href="photo/dsc07870.jpg"><img src="thumbnail/dsc07870.jpg"></img></a> <a href="photo/dsc07869.jpg"><img src="thumbnail/dsc07869.jpg"></img></a> <a href="photo/dsc07868.jpg"><img src="thumbnail/dsc07868.jpg"></img></a> <a href="photo/dsc07867.jpg"><img src="thumbnail/dsc07867.jpg"></img></a> <a href="photo/dsc07865.jpg"><img src="thumbnail/dsc07865.jpg"></img></a> <a href="photo/dsc07860.jpg"><img src="thumbnail/dsc07860.jpg"></img></a> <a href="photo/dsc07859.jpg"><img src="thumbnail/dsc07859.jpg"></img></a> <a href="photo/dsc07858.jpg"><img src="thumbnail/dsc07858.jpg"></img></a> <a href="photo/dsc07851.jpg"><img src="thumbnail/dsc07851.jpg"></img></a> <a href="photo/dsc07847.jpg"><img src="thumbnail/dsc07847.jpg"></img></a> <a href="photo/dsc07846.jpg"><img src="thumbnail/dsc07846.jpg"></img></a> <a href="photo/dsc07841.jpg"><img src="thumbnail/dsc07841.jpg"></img></a> <a href="photo/dsc07839.jpg"><img src="thumbnail/dsc07839.jpg"></img></a> <a href="photo/dsc07838.jpg"><img src="thumbnail/dsc07838.jpg"></img></a> <a href="photo/dsc07836.jpg"><img src="thumbnail/dsc07836.jpg"></img></a> <a href="photo/dsc07835.jpg"><img src="thumbnail/dsc07835.jpg"></img></a> <a href="photo/dsc07833.jpg"><img src="thumbnail/dsc07833.jpg"></img></a> <a href="photo/dsc07832.jpg"><img src="thumbnail/dsc07832.jpg"></img></a> <a href="photo/dsc07830.jpg"><img src="thumbnail/dsc07830.jpg"></img></a> <a href="photo/dsc07829.jpg"><img src="thumbnail/dsc07829.jpg"></img></a> <a href="photo/dsc07828.jpg"><img src="thumbnail/dsc07828.jpg"></img></a> <a href="photo/dsc07827.jpg"><img src="thumbnail/dsc07827.jpg"></img></a> <a href="photo/dsc07826.jpg"><img src="thumbnail/dsc07826.jpg"></img></a> <a href="photo/dsc07825.jpg"><img src="thumbnail/dsc07825.jpg"></img></a> <a href="photo/dsc07823.jpg"><img src="thumbnail/dsc07823.jpg"></img></a> <a href="photo/dsc07822.jpg"><img src="thumbnail/dsc07822.jpg"></img></a> <a href="photo/dsc07821.jpg"><img src="thumbnail/dsc07821.jpg"></img></a> <a href="photo/dsc07820.jpg"><img src="thumbnail/dsc07820.jpg"></img></a> <a href="photo/dsc07819.jpg"><img src="thumbnail/dsc07819.jpg"></img></a> <a href="photo/dsc07818.jpg"><img src="thumbnail/dsc07818.jpg"></img></a> <a href="photo/dsc07817.jpg"><img src="thumbnail/dsc07817.jpg"></img></a> <a href="photo/dsc07816.jpg"><img src="thumbnail/dsc07816.jpg"></img></a> <a href="photo/dsc07815.jpg"><img src="thumbnail/dsc07815.jpg"></img></a> <a href="photo/dsc07814.jpg"><img src="thumbnail/dsc07814.jpg"></img></a> <a href="photo/dsc07807.jpg"><img src="thumbnail/dsc07807.jpg"></img></a> <a href="photo/dsc07806.jpg"><img src="thumbnail/dsc07806.jpg"></img></a> <a href="photo/dsc07803.jpg"><img src="thumbnail/dsc07803.jpg"></img></a> <a href="photo/dsc07802.jpg"><img src="thumbnail/dsc07802.jpg"></img></a> <a href="photo/dsc07801.jpg"><img src="thumbnail/dsc07801.jpg"></img></a> <a href="photo/dsc07800.jpg"><img src="thumbnail/dsc07800.jpg"></img></a> <a href="photo/dsc07799.jpg"><img src="thumbnail/dsc07799.jpg"></img></a> <a href="photo/dsc07798.jpg"><img src="thumbnail/dsc07798.jpg"></img></a> <a href="photo/dsc07793.jpg"><img src="thumbnail/dsc07793.jpg"></img></a> <a href="photo/dsc07792.jpg"><img src="thumbnail/dsc07792.jpg"></img></a> <a href="photo/dsc07791.jpg"><img src="thumbnail/dsc07791.jpg"></img></a> <a href="photo/dsc07790.jpg"><img src="thumbnail/dsc07790.jpg"></img></a> <a href="photo/dsc07789.jpg"><img src="thumbnail/dsc07789.jpg"></img></a> <a href="photo/dsc07781.jpg"><img src="thumbnail/dsc07781.jpg"></img></a> <a href="photo/dsc07779.jpg"><img src="thumbnail/dsc07779.jpg"></img></a> <a href="photo/dsc07778.jpg"><img src="thumbnail/dsc07778.jpg"></img></a> <a href="photo/dsc07777.jpg"><img src="thumbnail/dsc07777.jpg"></img></a> <a href="photo/dsc07776.jpg"><img src="thumbnail/dsc07776.jpg"></img></a> <a href="photo/dsc07775.jpg"><img src="thumbnail/dsc07775.jpg"></img></a> <a href="photo/dsc07774.jpg"><img src="thumbnail/dsc07774.jpg"></img></a> <a href="photo/dsc07755.jpg"><img src="thumbnail/dsc07755.jpg"></img></a> <a href="photo/dsc07741.jpg"><img src="thumbnail/dsc07741.jpg"></img></a> <a href="photo/dsc07739.jpg"><img src="thumbnail/dsc07739.jpg"></img></a> <a href="photo/dsc07735.jpg"><img src="thumbnail/dsc07735.jpg"></img></a> <a href="photo/dsc07734.jpg"><img src="thumbnail/dsc07734.jpg"></img></a> <a href="photo/dsc07733.jpg"><img src="thumbnail/dsc07733.jpg"></img></a> <a href="photo/dsc07732.jpg"><img src="thumbnail/dsc07732.jpg"></img></a> <a href="photo/dsc07729.jpg"><img src="thumbnail/dsc07729.jpg"></img></a> <a href="photo/dsc07728.jpg"><img src="thumbnail/dsc07728.jpg"></img></a> <a href="photo/dsc07725.jpg"><img src="thumbnail/dsc07725.jpg"></img></a> <a href="photo/dsc07721.jpg"><img src="thumbnail/dsc07721.jpg"></img></a> <a href="photo/dsc07720.jpg"><img src="thumbnail/dsc07720.jpg"></img></a> <a href="photo/dsc07703.jpg"><img src="thumbnail/dsc07703.jpg"></img></a> <a href="photo/dsc07702.jpg"><img src="thumbnail/dsc07702.jpg"></img></a> <a href="photo/dsc07697.jpg"><img src="thumbnail/dsc07697.jpg"></img></a> <a href="photo/dsc07692.jpg"><img src="thumbnail/dsc07692.jpg"></img></a> <a href="photo/dsc07687.jpg"><img src="thumbnail/dsc07687.jpg"></img></a> <a href="photo/dsc07686.jpg"><img src="thumbnail/dsc07686.jpg"></img></a> <a href="photo/dsc07683.jpg"><img src="thumbnail/dsc07683.jpg"></img></a> <a href="photo/dsc07666.jpg"><img src="thumbnail/dsc07666.jpg"></img></a> <a href="photo/dsc07664.jpg"><img src="thumbnail/dsc07664.jpg"></img></a> <a href="photo/dsc07663.jpg"><img src="thumbnail/dsc07663.jpg"></img></a> <a href="photo/dsc07659.jpg"><img src="thumbnail/dsc07659.jpg"></img></a> <a href="photo/dsc07656.jpg"><img src="thumbnail/dsc07656.jpg"></img></a> <a href="photo/dsc07654.jpg"><img src="thumbnail/dsc07654.jpg"></img></a> <a href="photo/dsc07651.jpg"><img src="thumbnail/dsc07651.jpg"></img></a> <a href="photo/dsc07649.jpg"><img src="thumbnail/dsc07649.jpg"></img></a> <a href="photo/dsc07644.jpg"><img src="thumbnail/dsc07644.jpg"></img></a> <a href="photo/dsc07638.jpg"><img src="thumbnail/dsc07638.jpg"></img></a> <a href="photo/dsc07621.jpg"><img src="thumbnail/dsc07621.jpg"></img></a> <a href="photo/dsc07618.jpg"><img src="thumbnail/dsc07618.jpg"></img></a> <a href="photo/dsc07594.jpg"><img src="thumbnail/dsc07594.jpg"></img></a> <a href="photo/dsc07589.jpg"><img src="thumbnail/dsc07589.jpg"></img></a> <a href="photo/dsc07582.jpg"><img src="thumbnail/dsc07582.jpg"></img></a> <a href="photo/dsc07579.jpg"><img src="thumbnail/dsc07579.jpg"></img></a> <a href="photo/dsc07577.jpg"><img src="thumbnail/dsc07577.jpg"></img></a> <a href="photo/dsc07569.jpg"><img src="thumbnail/dsc07569.jpg"></img></a> <a href="photo/dsc07565.jpg"><img src="thumbnail/dsc07565.jpg"></img></a> <a href="photo/dsc07556.jpg"><img src="thumbnail/dsc07556.jpg"></img></a> <a href="photo/dsc07553.jpg"><img src="thumbnail/dsc07553.jpg"></img></a> <a href="photo/dsc07551.jpg"><img src="thumbnail/dsc07551.jpg"></img></a> <a href="photo/dsc07550.jpg"><img src="thumbnail/dsc07550.jpg"></img></a> <a href="photo/dsc07547.jpg"><img src="thumbnail/dsc07547.jpg"></img></a> <a href="photo/dsc07472.jpg"><img src="thumbnail/dsc07472.jpg"></img></a> <a href="photo/dsc07464.jpg"><img src="thumbnail/dsc07464.jpg"></img></a> <a href="photo/dsc07454.jpg"><img src="thumbnail/dsc07454.jpg"></img></a> <a href="photo/dsc07453.jpg"><img src="thumbnail/dsc07453.jpg"></img></a> <a href="photo/dsc07447.jpg"><img src="thumbnail/dsc07447.jpg"></img></a> <a href="photo/dsc07444.jpg"><img src="thumbnail/dsc07444.jpg"></img></a> <a href="photo/dsc07441.jpg"><img src="thumbnail/dsc07441.jpg"></img></a> <a href="photo/dsc07430.jpg"><img src="thumbnail/dsc07430.jpg"></img></a> <a href="photo/dsc07425.jpg"><img src="thumbnail/dsc07425.jpg"></img></a> <a href="photo/dsc07416.jpg"><img src="thumbnail/dsc07416.jpg"></img></a> <a href="photo/dsc07405.jpg"><img src="thumbnail/dsc07405.jpg"></img></a> <a href="photo/dsc07397.jpg"><img src="thumbnail/dsc07397.jpg"></img></a> <a href="photo/dsc07391.jpg"><img src="thumbnail/dsc07391.jpg"></img></a> <a href="photo/dsc07387.jpg"><img src="thumbnail/dsc07387.jpg"></img></a> <a href="photo/dsc07380.jpg"><img src="thumbnail/dsc07380.jpg"></img></a> <a href="photo/dsc07374.jpg"><img src="thumbnail/dsc07374.jpg"></img></a> <a href="photo/dsc07365.jpg"><img src="thumbnail/dsc07365.jpg"></img></a> <a href="photo/dsc07362.jpg"><img src="thumbnail/dsc07362.jpg"></img></a> <a href="photo/dsc07357.jpg"><img src="thumbnail/dsc07357.jpg"></img></a> <a href="photo/dsc07353.jpg"><img src="thumbnail/dsc07353.jpg"></img></a> <a href="photo/dsc07352.jpg"><img src="thumbnail/dsc07352.jpg"></img></a> <a href="photo/dsc07351.jpg"><img src="thumbnail/dsc07351.jpg"></img></a> <a href="photo/dsc07333.jpg"><img src="thumbnail/dsc07333.jpg"></img></a> <a href="photo/dsc07327.jpg"><img src="thumbnail/dsc07327.jpg"></img></a> <a href="photo/dsc07320.jpg"><img src="thumbnail/dsc07320.jpg"></img></a> <a href="photo/dsc07319.jpg"><img src="thumbnail/dsc07319.jpg"></img></a> <a href="photo/dsc07312.jpg"><img src="thumbnail/dsc07312.jpg"></img></a> <a href="photo/dsc07221.jpg"><img src="thumbnail/dsc07221.jpg"></img></a> <a href="photo/dsc07218.jpg"><img src="thumbnail/dsc07218.jpg"></img></a> <a href="photo/dsc07214.jpg"><img src="thumbnail/dsc07214.jpg"></img></a> <a href="photo/dsc07209.jpg"><img src="thumbnail/dsc07209.jpg"></img></a> <a href="photo/dsc07205.jpg"><img src="thumbnail/dsc07205.jpg"></img></a> <a href="photo/dsc07203.jpg"><img src="thumbnail/dsc07203.jpg"></img></a> <a href="photo/dsc07200.jpg"><img src="thumbnail/dsc07200.jpg"></img></a> <a href="photo/dsc07197.jpg"><img src="thumbnail/dsc07197.jpg"></img></a> <a href="photo/dsc07169.jpg"><img src="thumbnail/dsc07169.jpg"></img></a> <a href="photo/dsc07168.jpg"><img src="thumbnail/dsc07168.jpg"></img></a> <a href="photo/dsc07166.jpg"><img src="thumbnail/dsc07166.jpg"></img></a> <a href="photo/dsc07165.jpg"><img src="thumbnail/dsc07165.jpg"></img></a> <a href="photo/dsc07164.jpg"><img src="thumbnail/dsc07164.jpg"></img></a> <a href="photo/dsc07163.jpg"><img src="thumbnail/dsc07163.jpg"></img></a> <a href="photo/dsc07161.jpg"><img src="thumbnail/dsc07161.jpg"></img></a> <a href="photo/dsc07160.jpg"><img src="thumbnail/dsc07160.jpg"></img></a> <a href="photo/dsc07154.jpg"><img src="thumbnail/dsc07154.jpg"></img></a> <a href="photo/dsc07153.jpg"><img src="thumbnail/dsc07153.jpg"></img></a> <a href="photo/dsc07147.jpg"><img src="thumbnail/dsc07147.jpg"></img></a> <a href="photo/dsc07145.jpg"><img src="thumbnail/dsc07145.jpg"></img></a> <a href="photo/dsc07140.jpg"><img src="thumbnail/dsc07140.jpg"></img></a> <a href="photo/dsc07133.jpg"><img src="thumbnail/dsc07133.jpg"></img></a> <a href="photo/dsc07124.jpg"><img src="thumbnail/dsc07124.jpg"></img></a> <a href="photo/dsc07100.jpg"><img src="thumbnail/dsc07100.jpg"></img></a> <a href="photo/dsc07092.jpg"><img src="thumbnail/dsc07092.jpg"></img></a> <a href="photo/dsc07090.jpg"><img src="thumbnail/dsc07090.jpg"></img></a> <a href="photo/dsc07088.jpg"><img src="thumbnail/dsc07088.jpg"></img></a> <a href="photo/dsc07087.jpg"><img src="thumbnail/dsc07087.jpg"></img></a> <a href="photo/dsc07085.jpg"><img src="thumbnail/dsc07085.jpg"></img></a> <a href="photo/dsc07083.jpg"><img src="thumbnail/dsc07083.jpg"></img></a> <a href="photo/dsc07078.jpg"><img src="thumbnail/dsc07078.jpg"></img></a> <a href="photo/dsc07077.jpg"><img src="thumbnail/dsc07077.jpg"></img></a> <a href="photo/dsc07076.jpg"><img src="thumbnail/dsc07076.jpg"></img></a> <a href="photo/dsc07075.jpg"><img src="thumbnail/dsc07075.jpg"></img></a> <a href="photo/dsc07074.jpg"><img src="thumbnail/dsc07074.jpg"></img></a> <a href="photo/dsc06995.jpg"><img src="thumbnail/dsc06995.jpg"></img></a> <a href="photo/dsc06986.jpg"><img src="thumbnail/dsc06986.jpg"></img></a> <a href="photo/dsc06985.jpg"><img src="thumbnail/dsc06985.jpg"></img></a> <a href="photo/dsc06977.jpg"><img src="thumbnail/dsc06977.jpg"></img></a> <a href="photo/dsc06975.jpg"><img src="thumbnail/dsc06975.jpg"></img></a> <a href="photo/dsc06968.jpg"><img src="thumbnail/dsc06968.jpg"></img></a> <a href="photo/dsc06962.jpg"><img src="thumbnail/dsc06962.jpg"></img></a> <a href="photo/dsc06954.jpg"><img src="thumbnail/dsc06954.jpg"></img></a> <a href="photo/dsc06941.jpg"><img src="thumbnail/dsc06941.jpg"></img></a> <a href="photo/dsc06932.jpg"><img src="thumbnail/dsc06932.jpg"></img></a> <a href="photo/dsc06931.jpg"><img src="thumbnail/dsc06931.jpg"></img></a> <a href="photo/dsc06929.jpg"><img src="thumbnail/dsc06929.jpg"></img></a> <a href="photo/dsc06927.jpg"><img src="thumbnail/dsc06927.jpg"></img></a> <a href="photo/dsc06923.jpg"><img src="thumbnail/dsc06923.jpg"></img></a> <a href="photo/dsc06915.jpg"><img src="thumbnail/dsc06915.jpg"></img></a> <a href="photo/dsc06908.jpg"><img src="thumbnail/dsc06908.jpg"></img></a> <a href="photo/dsc06805.jpg"><img src="thumbnail/dsc06805.jpg"></img></a> <a href="photo/dsc06804.jpg"><img src="thumbnail/dsc06804.jpg"></img></a> <a href="photo/dsc06782.jpg"><img src="thumbnail/dsc06782.jpg"></img></a> <a href="photo/dsc06781.jpg"><img src="thumbnail/dsc06781.jpg"></img></a> <a href="photo/dsc06780.jpg"><img src="thumbnail/dsc06780.jpg"></img></a> <a href="photo/dsc06779.jpg"><img src="thumbnail/dsc06779.jpg"></img></a> <a href="photo/dsc06777.jpg"><img src="thumbnail/dsc06777.jpg"></img></a> <a href="photo/dsc06772.jpg"><img src="thumbnail/dsc06772.jpg"></img></a> <a href="photo/dsc06771.jpg"><img src="thumbnail/dsc06771.jpg"></img></a> <a href="photo/dsc06768.jpg"><img src="thumbnail/dsc06768.jpg"></img></a> <a href="photo/dsc06767.jpg"><img src="thumbnail/dsc06767.jpg"></img></a> <a href="photo/dsc06766.jpg"><img src="thumbnail/dsc06766.jpg"></img></a> <a href="photo/dsc06758.jpg"><img src="thumbnail/dsc06758.jpg"></img></a> <a href="photo/dsc06711.jpg"><img src="thumbnail/dsc06711.jpg"></img></a> <a href="photo/dsc06707.jpg"><img src="thumbnail/dsc06707.jpg"></img></a> <a href="photo/dsc06704.jpg"><img src="thumbnail/dsc06704.jpg"></img></a> <a href="photo/dsc06699.jpg"><img src="thumbnail/dsc06699.jpg"></img></a> <a href="photo/dsc06692.jpg"><img src="thumbnail/dsc06692.jpg"></img></a> <a href="photo/dsc06691.jpg"><img src="thumbnail/dsc06691.jpg"></img></a> <a href="photo/dsc06689.jpg"><img src="thumbnail/dsc06689.jpg"></img></a> <a href="photo/dsc06686.jpg"><img src="thumbnail/dsc06686.jpg"></img></a> <a href="photo/dsc06448.jpg"><img src="thumbnail/dsc06448.jpg"></img></a> <a href="photo/dsc06413.jpg"><img src="thumbnail/dsc06413.jpg"></img></a> <a href="photo/dsc06398.jpg"><img src="thumbnail/dsc06398.jpg"></img></a> <a href="photo/dsc06392.jpg"><img src="thumbnail/dsc06392.jpg"></img></a> <a href="photo/dsc06385.jpg"><img src="thumbnail/dsc06385.jpg"></img></a> <a href="photo/dsc06380.jpg"><img src="thumbnail/dsc06380.jpg"></img></a> <a href="photo/dsc06378.jpg"><img src="thumbnail/dsc06378.jpg"></img></a> <a href="photo/dsc06377.jpg"><img src="thumbnail/dsc06377.jpg"></img></a> <a href="photo/dsc06376.jpg"><img src="thumbnail/dsc06376.jpg"></img></a> <a href="photo/dsc06375.jpg"><img src="thumbnail/dsc06375.jpg"></img></a> <a href="photo/dsc06374.jpg"><img src="thumbnail/dsc06374.jpg"></img></a> <a href="photo/dsc06373.jpg"><img src="thumbnail/dsc06373.jpg"></img></a> <a href="photo/dsc06371.jpg"><img src="thumbnail/dsc06371.jpg"></img></a> <a href="photo/dsc06368.jpg"><img src="thumbnail/dsc06368.jpg"></img></a> <a href="photo/dsc06361.jpg"><img src="thumbnail/dsc06361.jpg"></img></a> <a href="photo/dsc06359.jpg"><img src="thumbnail/dsc06359.jpg"></img></a> <a href="photo/dsc06358.jpg"><img src="thumbnail/dsc06358.jpg"></img></a> <a href="photo/dsc06357.jpg"><img src="thumbnail/dsc06357.jpg"></img></a> <a href="photo/dsc03796.jpg"><img src="thumbnail/dsc03796.jpg"></img></a> <a href="photo/dsc03690.jpg"><img src="thumbnail/dsc03690.jpg"></img></a> <a href="photo/dsc03682.jpg"><img src="thumbnail/dsc03682.jpg"></img></a> <a href="photo/dsc03647.jpg"><img src="thumbnail/dsc03647.jpg"></img></a> <a href="photo/dsc03641.jpg"><img src="thumbnail/dsc03641.jpg"></img></a> <a href="photo/dsc03640.jpg"><img src="thumbnail/dsc03640.jpg"></img></a> <a href="photo/dsc03356.jpg"><img src="thumbnail/dsc03356.jpg"></img></a> <a href="photo/dsc03349.jpg"><img src="thumbnail/dsc03349.jpg"></img></a> <a href="photo/dsc03348.jpg"><img src="thumbnail/dsc03348.jpg"></img></a> <a href="photo/dsc02925.jpg"><img src="thumbnail/dsc02925.jpg"></img></a> <a href="photo/dsc02924.jpg"><img src="thumbnail/dsc02924.jpg"></img></a> <a href="photo/dsc02920.jpg"><img src="thumbnail/dsc02920.jpg"></img></a> <a href="photo/dsc02915.jpg"><img src="thumbnail/dsc02915.jpg"></img></a> <a href="photo/dsc02912.jpg"><img src="thumbnail/dsc02912.jpg"></img></a> <a href="photo/dsc02909.jpg"><img src="thumbnail/dsc02909.jpg"></img></a> <a href="photo/dsc02890.jpg"><img src="thumbnail/dsc02890.jpg"></img></a> <a href="photo/dsc02889.jpg"><img src="thumbnail/dsc02889.jpg"></img></a> <a href="photo/dsc02880.jpg"><img src="thumbnail/dsc02880.jpg"></img></a> <a href="photo/dsc02879.jpg"><img src="thumbnail/dsc02879.jpg"></img></a> <a href="photo/dsc02873.jpg"><img src="thumbnail/dsc02873.jpg"></img></a> <a href="photo/dsc02871.jpg"><img src="thumbnail/dsc02871.jpg"></img></a> <a href="photo/dsc02870.jpg"><img src="thumbnail/dsc02870.jpg"></img></a> <a href="photo/dsc02869.jpg"><img src="thumbnail/dsc02869.jpg"></img></a> <a href="photo/dsc02868.jpg"><img src="thumbnail/dsc02868.jpg"></img></a> <a href="photo/dsc02866.jpg"><img src="thumbnail/dsc02866.jpg"></img></a> <a href="photo/dsc02861.jpg"><img src="thumbnail/dsc02861.jpg"></img></a> <a href="photo/dsc02860.jpg"><img src="thumbnail/dsc02860.jpg"></img></a> <a href="photo/dsc02856.jpg"><img src="thumbnail/dsc02856.jpg"></img></a> <a href="photo/dsc02851.jpg"><img src="thumbnail/dsc02851.jpg"></img></a> <a href="photo/dsc02848.jpg"><img src="thumbnail/dsc02848.jpg"></img></a> <a href="photo/dsc02847.jpg"><img src="thumbnail/dsc02847.jpg"></img></a> <a href="photo/dsc02842.jpg"><img src="thumbnail/dsc02842.jpg"></img></a> <a href="photo/dsc02839.jpg"><img src="thumbnail/dsc02839.jpg"></img></a> <a href="photo/dsc02835.jpg"><img src="thumbnail/dsc02835.jpg"></img></a> <a href="photo/dsc02833.jpg"><img src="thumbnail/dsc02833.jpg"></img></a> <a href="photo/dsc02826.jpg"><img src="thumbnail/dsc02826.jpg"></img></a> <a href="photo/dsc02824.jpg"><img src="thumbnail/dsc02824.jpg"></img></a> <a href="photo/dsc02823.jpg"><img src="thumbnail/dsc02823.jpg"></img></a> <a href="photo/dsc02821.jpg"><img src="thumbnail/dsc02821.jpg"></img></a> <a href="photo/dsc02808.jpg"><img src="thumbnail/dsc02808.jpg"></img></a> <a href="photo/dsc02805.jpg"><img src="thumbnail/dsc02805.jpg"></img></a> <a href="photo/dsc02803.jpg"><img src="thumbnail/dsc02803.jpg"></img></a> <a href="photo/dsc02793.jpg"><img src="thumbnail/dsc02793.jpg"></img></a> <a href="photo/dsc02788.jpg"><img src="thumbnail/dsc02788.jpg"></img></a> <a href="photo/dsc02784.jpg"><img src="thumbnail/dsc02784.jpg"></img></a> <a href="photo/dsc02783.jpg"><img src="thumbnail/dsc02783.jpg"></img></a> <a href="photo/dsc02782.jpg"><img src="thumbnail/dsc02782.jpg"></img></a> <a href="photo/dsc02777.jpg"><img src="thumbnail/dsc02777.jpg"></img></a> <a href="photo/dsc02775.jpg"><img src="thumbnail/dsc02775.jpg"></img></a> <a href="photo/dsc02768.jpg"><img src="thumbnail/dsc02768.jpg"></img></a> <a href="photo/dsc02761.jpg"><img src="thumbnail/dsc02761.jpg"></img></a> <a href="photo/dsc02757.jpg"><img src="thumbnail/dsc02757.jpg"></img></a> <a href="photo/dsc02756.jpg"><img src="thumbnail/dsc02756.jpg"></img></a> <a href="photo/dsc02754.jpg"><img src="thumbnail/dsc02754.jpg"></img></a> <a href="photo/dsc02752.jpg"><img src="thumbnail/dsc02752.jpg"></img></a> <a href="photo/dsc02751.jpg"><img src="thumbnail/dsc02751.jpg"></img></a> <a href="photo/dsc02748.jpg"><img src="thumbnail/dsc02748.jpg"></img></a> <a href="photo/dsc02741.jpg"><img src="thumbnail/dsc02741.jpg"></img></a> <a href="photo/dsc02512.jpg"><img src="thumbnail/dsc02512.jpg"></img></a> <a href="photo/dsc02511.jpg"><img src="thumbnail/dsc02511.jpg"></img></a> <a href="photo/dsc02503.jpg"><img src="thumbnail/dsc02503.jpg"></img></a> <a href="photo/dsc02501.jpg"><img src="thumbnail/dsc02501.jpg"></img></a> <a href="photo/dsc02499.jpg"><img src="thumbnail/dsc02499.jpg"></img></a> <a href="photo/dsc02494.jpg"><img src="thumbnail/dsc02494.jpg"></img></a> <a href="photo/dsc02489.jpg"><img src="thumbnail/dsc02489.jpg"></img></a> <a href="photo/dsc02478.jpg"><img src="thumbnail/dsc02478.jpg"></img></a> <a href="photo/dsc02466.jpg"><img src="thumbnail/dsc02466.jpg"></img></a> <a href="photo/dsc02464.jpg"><img src="thumbnail/dsc02464.jpg"></img></a> <a href="photo/dsc02461.jpg"><img src="thumbnail/dsc02461.jpg"></img></a> <a href="photo/dsc02460.jpg"><img src="thumbnail/dsc02460.jpg"></img></a> <a href="photo/dsc02459.jpg"><img src="thumbnail/dsc02459.jpg"></img></a> <a href="photo/dsc02457.jpg"><img src="thumbnail/dsc02457.jpg"></img></a> <a href="photo/dsc02456.jpg"><img src="thumbnail/dsc02456.jpg"></img></a> <a href="photo/dsc02454.jpg"><img src="thumbnail/dsc02454.jpg"></img></a> <a href="photo/dsc02452.jpg"><img src="thumbnail/dsc02452.jpg"></img></a> <a href="photo/dsc02450.jpg"><img src="thumbnail/dsc02450.jpg"></img></a> <a href="photo/dsc02449.jpg"><img src="thumbnail/dsc02449.jpg"></img></a> <a href="photo/dsc02448.jpg"><img src="thumbnail/dsc02448.jpg"></img></a> <a href="photo/dsc02447.jpg"><img src="thumbnail/dsc02447.jpg"></img></a> <a href="photo/dsc02345.jpg"><img src="thumbnail/dsc02345.jpg"></img></a> <a href="photo/dsc02341.jpg"><img src="thumbnail/dsc02341.jpg"></img></a> <a href="photo/dsc02334.jpg"><img src="thumbnail/dsc02334.jpg"></img></a> <a href="photo/dsc02333.jpg"><img src="thumbnail/dsc02333.jpg"></img></a> <a href="photo/dsc02331.jpg"><img src="thumbnail/dsc02331.jpg"></img></a> <a href="photo/dsc02330.jpg"><img src="thumbnail/dsc02330.jpg"></img></a> <a href="photo/dsc02329.jpg"><img src="thumbnail/dsc02329.jpg"></img></a> <a href="photo/dsc02328.jpg"><img src="thumbnail/dsc02328.jpg"></img></a> <a href="photo/dsc02327.jpg"><img src="thumbnail/dsc02327.jpg"></img></a> <a href="photo/dsc02323.jpg"><img src="thumbnail/dsc02323.jpg"></img></a> <a href="photo/dsc02322.jpg"><img src="thumbnail/dsc02322.jpg"></img></a> <a href="photo/dsc02321.jpg"><img src="thumbnail/dsc02321.jpg"></img></a> <a href="photo/dsc02320.jpg"><img src="thumbnail/dsc02320.jpg"></img></a> <a href="photo/dsc02318.jpg"><img src="thumbnail/dsc02318.jpg"></img></a> <a href="photo/dsc02050.jpg"><img src="thumbnail/dsc02050.jpg"></img></a> <a href="photo/dsc02048.jpg"><img src="thumbnail/dsc02048.jpg"></img></a> <a href="photo/dsc02044.jpg"><img src="thumbnail/dsc02044.jpg"></img></a> <a href="photo/dsc02038.jpg"><img src="thumbnail/dsc02038.jpg"></img></a> <a href="photo/dsc02027.jpg"><img src="thumbnail/dsc02027.jpg"></img></a> <a href="photo/dsc02015.jpg"><img src="thumbnail/dsc02015.jpg"></img></a> <a href="photo/dsc01939.jpg"><img src="thumbnail/dsc01939.jpg"></img></a> <a href="photo/dsc01928.jpg"><img src="thumbnail/dsc01928.jpg"></img></a> <a href="photo/dsc01916.jpg"><img src="thumbnail/dsc01916.jpg"></img></a> <a href="photo/dsc01906.jpg"><img src="thumbnail/dsc01906.jpg"></img></a> <a href="photo/dsc01905.jpg"><img src="thumbnail/dsc01905.jpg"></img></a> <a href="photo/dsc01891.jpg"><img src="thumbnail/dsc01891.jpg"></img></a> <a href="photo/dsc01885.jpg"><img src="thumbnail/dsc01885.jpg"></img></a> <a href="photo/dsc01871.jpg"><img src="thumbnail/dsc01871.jpg"></img></a> <a href="photo/dsc01806.jpg"><img src="thumbnail/dsc01806.jpg"></img></a> <a href="photo/dsc01802.jpg"><img src="thumbnail/dsc01802.jpg"></img></a> <a href="photo/dsc01800.jpg"><img src="thumbnail/dsc01800.jpg"></img></a> <a href="photo/dsc01795.jpg"><img src="thumbnail/dsc01795.jpg"></img></a> <a href="photo/dsc01793.jpg"><img src="thumbnail/dsc01793.jpg"></img></a> <a href="photo/dsc01790.jpg"><img src="thumbnail/dsc01790.jpg"></img></a> <a href="photo/dsc01789.jpg"><img src="thumbnail/dsc01789.jpg"></img></a> <a href="photo/dsc01770.jpg"><img src="thumbnail/dsc01770.jpg"></img></a> <a href="photo/dsc01743.jpg"><img src="thumbnail/dsc01743.jpg"></img></a> <a href="photo/dsc01728.jpg"><img src="thumbnail/dsc01728.jpg"></img></a> <a href="photo/dsc01721.jpg"><img src="thumbnail/dsc01721.jpg"></img></a> <a href="photo/dsc01688.jpg"><img src="thumbnail/dsc01688.jpg"></img></a> <a href="photo/dsc01673.jpg"><img src="thumbnail/dsc01673.jpg"></img></a> <a href="photo/dsc01667.jpg"><img src="thumbnail/dsc01667.jpg"></img></a> <a href="photo/dsc01654.jpg"><img src="thumbnail/dsc01654.jpg"></img></a> <a href="photo/dsc01637.jpg"><img src="thumbnail/dsc01637.jpg"></img></a> <a href="photo/dsc01629.jpg"><img src="thumbnail/dsc01629.jpg"></img></a> <a href="photo/dsc01594.jpg"><img src="thumbnail/dsc01594.jpg"></img></a> <a href="photo/dsc01583.jpg"><img src="thumbnail/dsc01583.jpg"></img></a> <a href="photo/dsc01573.jpg"><img src="thumbnail/dsc01573.jpg"></img></a> <a href="photo/dsc01556.jpg"><img src="thumbnail/dsc01556.jpg"></img></a> <a href="photo/dsc01548.jpg"><img src="thumbnail/dsc01548.jpg"></img></a> <a href="photo/dsc01541.jpg"><img src="thumbnail/dsc01541.jpg"></img></a> <a href="photo/dsc01508.jpg"><img src="thumbnail/dsc01508.jpg"></img></a> <a href="photo/dsc01493.jpg"><img src="thumbnail/dsc01493.jpg"></img></a> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectBuzzer.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectBuzzer"><back>Retour</back></a> <a href="projectHoldSwitch.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Le buzzer piloté</title> <underline></underline> <text>Cette carte permet via un signal périodique de piloter un <bold>buzzer piézoélectrique ou magnétique</bold> (sans oscillateur intégré au boîtier) :</text> <a href="photo/dsc07405.jpg"><img src="thumbnail/dsc07405.jpg"></img></a> <a href="photo/dsc07374.jpg"><img src="thumbnail/dsc07374.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/buzzer.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Un simple buzzer demandant un courant de seulement <bold>35mA</bold> maximum (comme ceux que j'utilise dans mes montages), peut être alimenté sans risques directement sur les broches d'un microcontrôleur, ce qui conviendra à bon nombre d'applications. Mais il est plus propre de dédier une petite carte qui <bold>filtrera quelques parasites</bold>, via un <bold>transistor de puissance</bold> pilotera le buzzer et par la même occasion <bold>protégera</bold> ce dernier à l'aide d'une diode.</text> <text><bold>Connexions (buzzer piloté sur automate programmable) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche WAVE (onde) sur port GPIO générant un signal périodique (via la classe SoundWrite.h, ou PwmWrite.h par exemple).</caution> <quote>À noter que la disposition des broches de cette carte correspond aux ports de mes automates programmables (GND, +5V, GPIO). Vous pouvez donc connecter cette carte à mes automates programmables directement avec une nappe de 3 fils adaptée.</quote> <a href="photo/dsc07380.jpg"><img src="thumbnail/dsc07380.jpg"></img></a> <text><bold>Les caractéristiques de la carte :</bold> <br/>- 1 broche GND (masse) pour l'alimentation. <br/>- 1 broche +5V (pôle positif) pour l'alimentation. <br/>- 1 broche WAVE (onde) pour l'entrée d'un signal périodique. <br/>- Dimensions : 26.67mm x 22.86mm. <br/>- Entre-axes de fixations : 19.05mm x 15.24mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Buzzer magnétique CEM-1203(42) (diamètre 12mm, hauteur 8.5mm, pas 6.5mm) <br/>1x Résistance 1kΩ carbone 0.25W (tolérance 5%) <br/>1x Résistance 10kΩ carbone 0.25W (tolérance 5%) <br/>1x Condensateur 100nF céramique (pas 5.08mm, tension >5V) <br/>1x Diode Schottky 1N5817 <br/>1x Transistor bipolaire 2N3904 (boîtier TO-92) <br/>3x Broches mâles (pas 2.54mm)</quote> <text>À gauche les composants nécessaires, à droite le PCB nu :</text> <a href="photo/dsc07472.jpg"><img src="thumbnail/dsc07472.jpg"></img></a> <a href="photo/dsc07353.jpg"><img src="thumbnail/dsc07353.jpg"></img></a> <text>Le buzzer indiqué dans la liste des composants dispose d'une <bold>fréquence de résonance de 2048Hz</bold>. Ceci est intéressant parce qu'il est alors possible de loger dans des boîtiers tout à fait hermétiques et exigus ce buzzer, mais de néanmoins l'entendre assez fort en lui appliquant un <bold>signal périodique carré d'une fréquence de 2048Hz</bold> ce qui le fait rentrer en résonance, et donc amplifie grandement la pression acoustique.</text> <caution>En résonance à 2048Hz, la pression acoustique de ce buzzer <bold>dépasse 85dB</bold>, il est important alors de se protéger avec un équipement de protection individuel adapté (bouchons d'oreilles, casque anti-bruit) afin de ne pas mettre en danger votre oreille interne. Je ne pourrais être tenu pour responsable si vous faites une mauvaise utilisation de cette carte électronique et de ma classe SoundWrite.h !</caution> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectGeigerBoostConverter.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectGeigerBoostConverter"><back>Retour</back></a> <a href="projectPinHeader.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>L'élévateur de tension +400V pour tube Geiger</title> <underline></underline> <text>Le tube d'un <bold>compteur Geiger</bold> a besoin d'être alimenté avec une tension (différence de potentielle entre sa cathode et son anode) suffisamment élevée afin de détecter des particules.</text> <a href="photo/dsc02333.jpg"><img src="thumbnail/dsc02333.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/geiger_boost_converter.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Cette élévation de tension est obtenue à l'aide d'un montage qui dans son principe de fonctionnement est assez simple : <br/>- Charge d'une inductance. <br/>- Décharge de l'inductance dans un condensateur en passant par une diode de redressement. <br/>- Charge du condensateur. <br/>- Alimentation du tube Geiger via le condensateur.</text> <text>Cette carte électronique permet donc d'élever la tension d'alimentation de <bold>+5V</bold> (délivrée par mes automates programmables) à <bold>+400V</bold>, elle détecte également la <bold>fermeture du tube Geiger</bold> (ici connectée sur le tube Geiger SBM20 de conception Russe, à gauche le prototype, à droite la carte finale) :</text> <a href="photo/dsc02511.jpg"><img src="thumbnail/dsc02511.jpg"></img></a> <a href="photo/dsc02334.jpg"><img src="thumbnail/dsc02334.jpg"></img></a> <text><bold>Connexions (élévateur de tension +400V sur automate programmable) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SHOCK (coups) sur port d'interruption externe (INT0, INT1, etc...) pour détecter la fermeture du tube Geiger.</caution> <text><bold>Les caractéristiques de la carte :</bold> <br/>- 1 broche GND (masse) pour l'alimentation. <br/>- 1 broche +5V (pôle positif) pour l'alimentation. <br/>- 1 broche SHOCK (coups) pour détecter la fermeture du tube Geiger (0V = fermé, +5V = ouvert). <br/>- 1 connecteur à souder GEIGER TUBE GND (masse) pour alimenter un tube Geiger. <br/>- 1 connecteur à souder GEIGER TUBE +400V (pôle positif) pour alimenter un tube Geiger. <br/>- Dimensions : 51.435mm x 25.4mm. <br/>- Entre-axes de fixations : 43.815mm x 17.78mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Oscillateur NE555 (boîtier DIP-8) <br/>2x Résistances 1kΩ carbones 0.25W (tolérance 5%) <br/>1x Résistance 1kΩ métal 0.25W (tolérance 1%) <br/>1x Résistance 2.2kΩ carbone 0.25W (tolérance 5%) <br/>2x Résistances 10kΩ carbones 0.25W (tolérance 5%) <br/>1x Résistance 10kΩ métal 0.25W (tolérance 1%) <br/>1x Résistance 10MΩ carbone 0.25W (tolérance 5%) <br/>1x Condensateur 100pF céramique (pas 5.08mm, tension >400V) <br/>1x Condensateur 4.7nF céramique (pas 5.08mm, tension >400V) <br/>1x Condensateur 33nF céramique (pas 5.08mm, tension >5V) <br/>2x Condensateurs 100nF céramiques (pas 5.08mm, tension >5V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >5V) <br/>1x Inductance 15mH self (pas 5.08mm, boîtier radial) <br/>1x Diode 1N4007 <br/>1x Transistor bipolaire 2N3904 (boîtier TO-92) <br/>1x Transistor bipolaire MPSA44 (boîtier TO-92) <br/>1x Support DIP-8 300mil <br/>3x Broches mâles (pas 2.54mm)</quote> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectGeigerCounter.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectGeigerCounter"><back>Retour</back></a> <a href="projectIntervalometer.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Le compteur Geiger</title> <underline></underline> <text>Le <bold>compteur Geiger</bold> (ou radiamètre) à tube LND712 est né de ma passion pour la science (physique nucléaire) et pour l'instrumentation scientifique en général :</text> <a href="photo/dsc02873.jpg"><img src="thumbnail/dsc02873.jpg"></img></a> <a href="photo/dsc02833.jpg"><img src="thumbnail/dsc02833.jpg"></img></a> <text>Si nous voulons comprendre les atomes, nous devons nous intéresser à la physique nucléaire, entendre par la <bold>nucléons</bold> (protons et neutrons), c'est-à-dire les constituants du noyau des atomes.</text> <text><bold>Antériorité du projet :</bold> <br/>À l'époque ou j'ai commencé à m'intéresser à la radioactivité (années 1990 suite à l'accident de Tchernobyl), ce type d'appareil de mesure me semblait infaisable par un amateur, et en l'occurrence se trouvait être (et est toujours aujourd'hui) très onéreux dans le commerce.</text> <text>Bien plus tard, je débute l'électronique en 2014, précisément dans l'objectif de comprendre comment réaliser cet instrument, ainsi au fil de mon apprentissage et de persévérance, cela m'est apparut comme tout à fait réalisable, d'où cette présentation du projet finalisé.</text> <a href="photo/dsc06707.jpg"><img src="thumbnail/dsc06707.jpg"></img></a> <text><bold>Les caractéristiques du compteur Geiger :</bold> <br/>- Automate programmable MODULABLE M20 équipé du microcontrôleur ATmega328P. <br/>- Élévateur de tension à découpage (+5V vers +400V). <br/>- Tube de détection LND712 (détection des Alphas, Betas, Gammas, et rayonnement X) <br/>- Affichage digital avec afficheurs à digits MAX7219. <br/>- Affichage analogique à l'aide d'un galvanomètre et d'une del. <br/>- Buzzer de signalement. <br/>- Bouton rotatif de sélection des modes. <br/>- Interrupteurs de visualisation des coups / seconde et doses maximales relevées. <br/>- Interrupteur d'allumage (on/off). <br/>- Accumulateur NIMH (+1.2V par élément) 10S 600mAh (+12V). <br/>- Alarme niveau de batterie faible. <br/>- Boîtier ouvert en aluminium, cuivre, acier inoxydable, laiton, et ertalon.</text> <text><bold>L'affichage permet de visualiser plusieurs unités :</bold></text> <quote>- Le cumule des coups. <br/>- Les coups / seconde instantanés. <br/>- Les coups / seconde maximums relevés. <br/>- La dose cumulée au cours du temps. <br/>- La dose instantanée. <br/>- La dose maximale relevée.</quote> <text>Cette dose est le rapport (coefficient sans unité) à la radioactivité naturelle. À ne pas confondre avec le débit de dose (comme la plupart des radiamètres du commerce) qui serait exprimé en Sievert par unité de temps.</text> <a href="photo/dsc02880.jpg"><img src="thumbnail/dsc02880.jpg"></img></a> <a href="photo/dsc02890.jpg"><img src="thumbnail/dsc02890.jpg"></img></a> <video src="video/00005.mov" controls></video> <title>Qu'est-ce que la radioactivité ?</title> <underline></underline> <text>La radioactivité est la conséquence et la manifestation de <bold>l'instabilité du noyau des atomes</bold> qui composent la matière qui nous entoure et qui nous constitue.</text> <text>Cet état instable peut avoir plusieurs causes au niveau atomique : <br/>- Le noyau de l'atome a un excédant de neutrons (par rapport à la vallée de stabilité). <br/>- Le noyau de l'atome se réorganise (un neutron devient un proton). <br/>- Le noyau de l'atome est excité, il possède un excédant d'énergie (qu'il doit libérer).</text> <text>Dans tous les cas, l'atome souhaite retrouver un état plus stable.</text> <text><bold>Cette radioactivité se manifeste sous plusieurs formes :</bold></text> <caution>- <bold>Alpha</bold> (α) : 2 protons + 2 neutrons (4 nucléons) sont éjectés du noyau, c'est l'Helium 4. <br/>- <bold>Beta-</bold> (β-) : 1 neutron (1 quark up + 2 quarks down) devient 1 proton (2 quarks up + 1 quark down), ceci est accompagné de l'émission d'1 électron + 1 anti-neutrino. <br/>- <bold>Beta+</bold> (β+) : 1 proton (2 quarks up + 1 quark down) devient 1 neutron (1 quark up + 2 quarks down), ceci est accompagné de l'émission d'1 positon + 1 neutrino. <br/>- <bold>Gamma</bold> (γ) : résultat de la collision d'1 particule avec son anti-particule, 1 ou plusieurs photons (rayonnement de nature électro-magnétique) peuvent êtres libérés de l'atome du fait de sa désexcitation. La fréquence vibratoire de cette onde est supérieure à 30 exahertz (30000000000000000000 hertz). <br/>- <bold>X</bold> : 1 électron passe d'un niveau d'énergie à un autre, ce qui s'accompagne d'une émission (photon) de même nature que le rayonnement Gamma mais de fréquence vibratoire inférieure (de 30 petahertz à 30 exahertz).</caution> <text>Ces émissions se comportent différemment selon le matériau traversé :</text> <quote>- <bold>l'Alpha</bold> est arrêté au contact d'une feuille de papier. <br/>- Le <bold>Beta</bold> est arrêté au contact d'une tôle d'aluminium. <br/>- Le <bold>Gamma</bold> est atténué en traversant plusieurs mètres de béton ou plusieurs centimètres de plomb, mais n'est pas arrêté.</quote> <text><radioactive></radioactive> <bold>Quantifier la radioactivité :</bold> <br/>Plusieurs unités de mesure standards (ou dérivées du système standard) existent et permettent de quantifier le niveau de radioactivité et la dose reçue. Chaque unité est à placer dans un contexte précis de mesures par rapport aux conditions et à l'environnement associé, ceci afin d'éviter de fausses interprétations des résultats.</text> <text>Plusieurs paramètres interviennent pour quantifier la radioactivité : <br/>- <bold>La nature de l'émission</bold> (Alpha, Beta, Gamma, X). <br/>- <bold>La distance</bold> (à 1 cm, à 1 mètre, etc...). <br/>- <bold>La durée d'exposition</bold> (1 seconde, 1 heure, etc...). <br/>- <bold>Les parties du corps exposées au rayonnement</bold> (les effets seront bien différents selon la zone exposée). <br/>- <bold>La sensibilité du matériel utilisé</bold> pour effectuer les mesures.</text> <text>Voici une liste de quelques unités de mesure :</text> <quote>- Le <bold>Sievert</bold> (Sv) : établi une estimation de l'impact biologique de la radioactivité sur le corps humain (par unité de temps en heures ou en années). <br/>- Le <bold>Becquerel</bold> (Bq) : est l'activité d'un radio-nucléide. Souvent indiqué par kilogramme de matière, 1 Becquerel signifie 1 désintégration d'atome / seconde. <br/>- Le <bold>coup / seconde</bold> (Cps) : de même nature que le Becquerel mais sans quantification de la quantité de matière. <br/>- Le <bold>Gray</bold> (Gy) : représente l'énergie (en Joules) apportée à une masse homogène d'1kg.</quote> <text>La dose reçue liée à la radioactivité naturelle en France est en moyenne de <bold>1 millisievert / an par habitant</bold>. Pour les travailleurs du secteur du nucléaire en France, la dose maximale admissible est de <bold>20 millisievert sur 12 mois glissants par personne</bold>. Les risques de maladies et de cancers commencent à apparaître à partir de <bold>100 millisievert</bold> (pas forcément lié à une unité de temps cette fois-ci), mais d'une façon plus générale, toute dose ajoutée à la radioactivité naturelle est susceptible d'augmenter les risques de développer une pathologie (on parle alors des risques liés aux faibles doses d'exposition).</text> <text>Quelques notions sur les grandeurs physiques :</text> <caution>- 0.1 microsievert / heure par habitant est environ égal à 1 millisievert / an par habitant. <br/>- En règle générale (cela dépend de la zone du corps exposée), 1 Gray est égal à 1 Sievert (unités de même dimension). <br/>- 1 Joule est égal à 1 Watt / seconde.</caution> <text>Ces mesures sont déterminés par l'intermédiaire du <bold>tube Geiger</bold>, qui est <bold>l'élément sensitif</bold> d'un détecteur de radioactivité. Le tube Geiger est un dipôle (cathode + anode) qui, rempli d'un gaz rare à basse pression (généralement le néon) et soumis à une différence de potentielle élevée (haute tension), est ainsi placé dans un état de métastabilité.</text> <text>Il suffit donc d'une particule (électron, positon, proton, neutron, ou photon) traversant le tube Geiger pour <bold>ioniser le gaz</bold> (les atomes perdent ou gagnent des électrons), se qui a pour conséquence de créer une avalanche d'électrons se déplaçant de la cathode vers l'anode. Le tube est alors en saturation (le dipôle est fermé, comme un interrupteur), c'est le coup (quantifié ensuite en coups / seconde).</text> <text>Ci-dessous, un exemple de mesure de la radioactivité naturelle avec le tube Geiger <bold>LND712</bold> (le relevé indique 0.45 coups / seconde) :</text> <a href="photo/dsc02912.jpg"><img src="thumbnail/dsc02912.jpg"></img></a> <a href="photo/dsc02915.jpg"><img src="thumbnail/dsc02915.jpg"></img></a> <text>La radioactivité naturelle (aussi appelé bruit de fond) a toujours été présente sur la planète, elle fait partie intégrante de la croûte terrestre, de l'atmosphère, des océans, et du vivant.</text> <quote>Au cours de l'histoire et de l'évolution de la Terre, des réacteurs naturels ont existé bien avant l'apparition de l'homme. On en trouve des traces (vitrification des roches au voisinage de minerai d'Uranium) au Gabon, à la mine d'Uranium d'Oklo.</quote> <title>Une histoire d'isotopes et de descendants :</title> <underline></underline> <text><radioactive></radioactive> <bold>Les isotopes radioactifs :</bold> <br/>Un isotope est un atome ayant un nombre différent de neutrons. De fait, <bold>l'Uranium 236</bold> est un isotope plus lourd (il a 1 neutron de plus) que <bold>l'Uranium 235</bold>.</text> <text>En revanche, un atome n'est pas un isotope d'un autre atome ayant un nombre différent de protons (comme le Cesium 55 n'est pas un isotope du Xénon 54), ce sont bien deux éléments chimiques différents.</text> <text>Cette opération de transformation d'un élément chimique en un autre élément chimique s'appelle la <bold>transmutation</bold>.</text> <quote>Le corps humain est constitué de Potassium 40, un isotope radioactif !</quote> <text>Le Potassium 40 (19 protons + 21 neutrons) est instable, il se désintègre par <bold>radioactivité Beta-</bold> dans 88.8% des cas en Calcium 40 (20 protons + 20 neutrons), un élément chimique stable.</text> <text>Un isotope radioactif (instable donc) ne se désintègre pas forcément d'une seule manière, dans un certain nombre de cas (exemple ci-dessus : 88.8% des cas) cela peut être via <bold>radioactivité Alpha</bold>, dans d'autres cas par <bold>Beta-</bold> ou <bold>Beta+</bold>, ceci est variable selon l'isotope et la situation.</text> <text>Dans la plupart des cas <bold>l'Uranium 236</bold> fissionne, mais dans un autre pourcentage de cas il se désintègre par radioactivité Alpha en <bold>Thorium 232</bold>, et dans un certain nombre (faible) de cas à l'aide d'un bombardement intense de neutrons qu'il capture, il se transforme en Uranium 237, puis par radioactivité Beta- devient du <bold>Neptunium 237</bold>.</text> <text><radioactive></radioactive> <bold>La désintégration d'un atome peut être spontanée :</bold> <br/>Un matériau constitué d'isotopes radioactifs perds la moitié de sa radioactivité durant une demi-période, puis une autre moitié durant une autre demi-période, et ainsi de suite, de sorte que la décroissance radioactive d'un matériau suit une courbe exponentielle. Ce temps est dépendant de l'isotope considéré, en effet plus il est instable, plus sa demi-période est courte, et plus ses émissions radioactives sont fortes.</text> <text>Il n'est pas possible de prédire la désintégration d'un seul atome, ce phénomène peut intervenir à n'importe quel moment (aléatoire), par contre il est possible de prédire la désintégration de la moitié d'un groupe d'atomes :</text> <quote>1kg d'Uranium 235 perds la moitié de sa radioactivité (ou de sa masse) en <bold>703.8 millions d'années</bold>. Il reste alors 0.5kg d'Uranium 235 encore non désintégré, qui perds à son tour la moitié de sa radioactivité en 703.8 millions d'années supplémentaires, etc...</quote> <text>Les premiers 500g d'Uranium 235 désintégrés ne sont pas volatilisés, il se sont transformés en <bold>Thorium 231</bold> par désintégration <bold>Alpha</bold>, puis ce Thorium par désintégration <bold>Beta-</bold> se transformera en <bold>Protactinium 231</bold>, de sorte qu'un seul isotope radioactif au départ produit une grande quantité de descendants radioactifs dont il faut tenir compte pour les mesures effectuées dans le cadre de la radio-protection.</text> <text><radioactive></radioactive> <bold>La désintégration d'un atome peut être induite :</bold> <br/>Par capture d'un neutron lent, l'Uranium 235 devient de l'Uranium 236, beaucoup plus instable dans la plupart des cas, qui en conséquence se désintègre (fission) en ce scindant en deux atomes, ce sont les produits de fission. L'un des possibles est la désintégration en <bold>Krypton 92</bold> et en <bold>Baryum 141</bold>, deux isotopes radioactifs aux demi-périodes très courtes.</text> <quote>Remarquons que 236 - (92 + 141) = 3, ce qui signifie que 3 neutrons rapides sont éjectés lors de cette réaction de fission.</quote> <text>Les 3 neutrons rapides ainsi libérés, si ils sont ralentis (par exemple en traversant un volume d'eau), peuvent être à nouveau capturés par de l'Uranium 235, qui à son tour deviendra un Uranium 236 par nature instable qui se désintégrera et éjectera à nouveau 2 ou 3 neutrons : <br/>C'est la <bold>réaction en chaîne !</bold></text> <text>La réaction en chaîne est obtenue sous plusieurs conditions :</text> <caution>- <bold>La masse critique doit être atteinte</bold> (c'est-à-dire un certain volume de radio-isotopes dans le but de favoriser la capture de neutrons). <br/>- <bold>La géométrie du réacteur</bold> (endroit ou se produit la réaction) doit être considérée avec importance. <br/>- <bold>Des réflecteurs à neutrons</bold> (en carbure de tungstène) doivent êtres disposés autour des assemblages de radio-isotopes (crayons de combustible). <br/>- <bold>Les neutrons rapides doivent êtres ralentis par des modérateurs</bold> (eau, Béryllium, ou Graphite) afin qu'ils soient capturés par les noyaux d'atomes. Ceci n'est pas valable pour les réacteurs à neutrons rapides, dont le fonctionnement est différent.</caution> <text>Cette réaction en chaîne est accompagnée d'une <bold>forte émission Gamma</bold>, résultat de la perte de masse entre le début et la fin de la réaction, et du trop plein d'énergie à évacuer.</text> <text>Toutes ses émissions (Alpha, Beta, et Gamma) échauffent les différents matériaux utilisés au sein d'un réacteur d'une centrale nucléaire, ce qui permet de chauffer l'eau lourde, produire de la vapeur d'eau sous pression via un échangeur (interface entre le circuit primaire et secondaire), faire tourner des turbines, alternateurs, et produire de l'électricité sur le réseau.</text> <title>Différents combustibles nucléaires :</title> <underline></underline> <text><radioactive></radioactive> <bold>Le minerai d'Uranium 235 et ses dérivés :</bold> <br/>Le minerai d'Uranium se trouve à l'état naturel la plupart du temps dans des roches Pechblende (littéralement : minerai de malheur) sous la forme <bold>UO2</bold> (dioxyde d'Uranium). L'Uranium se présente généralement dans des proportions de 0.7% <bold>d'Uranium 235</bold> (fissile), et 99.3% <bold>d'Uranium 238</bold> (fertile), c'est pourquoi l'isotope 235 doit être enrichit (augmenter le ratio de 0.7%) pour que le réacteur ait un meilleur rendement. Néanmoins, il a existé par le passé des réacteurs à Uranium pauvre (non enrichit) nommés <bold>pile atomique</bold> :</text> <quote>La première <bold>pile atomique</bold> (premier réacteur nucléaire) à avoir existé fut celle d'Enrico Fermi en 1942 aux États-Unis (dans une ancienne salle de squash sous les gradins du Stagg Field à Chicago).</quote> <text>Ci-dessous un échantillon de minerai naturel d'Uranium que j'ai vitrifié pour plus de sécurité :</text> <a href="photo/dsc02924.jpg"><img src="thumbnail/dsc02924.jpg"></img></a> <a href="photo/dsc03356.jpg"><img src="thumbnail/dsc03356.jpg"></img></a> <text>Graphique suivant, une mesure de la radioactivité (principalement Gamma) par rapport au bruit de fond. Effectuée à une distance variable de 1cm à 20cm de l'échantillon, la courbe bleue est le niveau moyen sur une durée de 10 minutes par mesure, la courbe rouge représente les pics maximums relevés :</text> <a href="photo/dsc02925.jpg"><img src="thumbnail/dsc02925.jpg"></img></a> <text><radioactive></radioactive> <bold>L'Uranium 238 pour fabriquer le Plutonium 239 :</bold> <br/>Dans un réacteur nucléaire, comme évoqué <bold>l'Uranium 238</bold> n'est pas fissile, il est fertile, ce qui signifie que par capture de neutrons il peut servir à la fabrication d'un isotope fissile. Ainsi bombardé de neutrons lents (neutrons thermiques), l'Uranium 238 se transforme alors en son isotope 239, très instable, qui par désintégration Beta- se transforme à son tour en Neptunium 239, ce dernier étant lui aussi radioactif Beta-, se transforme alors en <bold>Plutonium 239</bold>, un élément chimique fissile cette fois-ci.</text> <quote>Le <bold>Plutonium 239</bold> a servit à créer le cœur de la <bold>première bombe atomique de l'histoire</bold> (cœur qui mesurait seulement 93mm de diamètre), elle fut testée grandeur nature lors de l'essai Trinity réalisé par l'armée Américaine le 16 Juillet 1945 dans le cadre du projet Manhattan.</quote> <text>Le <bold>Plutonium 241</bold> quand à lui se forme à partir du Plutonium 239 puis 240 par capture de neutrons. Également, le Plutonium 238 peut être formé par captures de neutrons successives par de l'Uranium 236 n'ayant pas fissionné (U236 +1n > U237 Beta- > Np237 +1n > Np238 Beta- > Pu238).</text> <text>Il existe 15 isotopes connus du Plutonium (tous radioactifs), les plus produits en réacteur sont :</text> <quote>- Le Pu238 <br/>- Le Pu239 <br/>- Le Pu240 <br/>- Le <bold>Pu241</bold> (voir plus bas : "La radio-toxicité du Plutonium 241") <br/>- Le Pu242</quote> <text>Le Plutonium 238 est souvent utilisé dans des missions spatiales de part le fait qu'il a une demi-période courte (87.75 années) et donc une énergie issue de sa désintégration très élevée (environ 567 Watts / kg). Ce radio-isotope dégage une grande quantité de chaleur qui peut être utilisée pour produire de l'électricité à bord des astronefs dans des <bold>générateurs thermo-électriques à radio-isotopes</bold>. Sa désintégration spontanée Alpha n'étant pas accompagnée de rayonnements Gamma pénétrants, il est donc un bon candidat pour les longues expéditions habitées.</text> <text>Le Plutonium est utilisé plus généralement dans les centrales électrogènes (nucléaires) sous la forme de <bold>crayons de combustibles</bold> en Zirconium, dans lequels se trouvent enfermé un composé de dioxyde de Plutonium (PuO2) et de dioxyde d'Uranium (UO2). Ce combustible est appelé MOX par la filière nucléaire.</text> <quote>Certains isotopes du Plutonium plus lourds que le Pu242, comme par exemple le <bold>Pu246</bold>, n'ont étés produits que lors des explosions atomiques car étant très lourds et instables, leurs fabrication requiert un bombardement de neutrons très intense.</quote> <title>L'exposition et la contamination :</title> <underline></underline> <text><radioactive></radioactive> <bold>L'exposition externe :</bold> <br/>L'exposition à la radioactivité est dite externe lorsque la source d'émission est situé à l'extérieur du corps. Cela peut être provoqué par la radioactivité naturelle (minerai) ou artificielle (stockage de déchets ou pollution).</text> <quote>La durée d'exposition est très importante dans un calcul, associée à la dose reçue et à la zone du corps touchée, elle conditionne les facteurs de risques encourus.</quote> <text>Dans les usines de retraitement du combustible usé, les techniciens accumulent une certaine dose de rayonnement ionisant. Pour éviter d'être contaminé, les éléments chimiques les plus dangereux sont manipulés à l'aide de boites à gants étanches ou télémanipulateurs mécaniques et robotisés à assistance électrique, ceci derrière des vitres blindées composées de Plomb (ce qui atténue les rayonnements).</text> <text><radioactive></radioactive> <bold>L'exposition interne :</bold> <br/>L'exposition interne qu'en à elle intervient lorsque la source d'émission ce situe à l'intérieur du corps, c'est alors la <bold>contamination</bold>. Ceci est très dangereux parce que l'énergie émise par un radio-isotope décroit au carré de la distance. Ce qui signifie qu'un atome d'Uranium 235 à quelques mètres de distance (sans danger immédiat), ne comporte pas les mêmes risques sur la santé que directement au contact des cellules du corps humain (dans le cas d'une ingestion ou inhalation).</text> <text>Émise depuis une source externe au corps humain, la <bold>particule Alpha</bold> (Helium 4) est généralement inoffensive du fait qu'elle est peu pénétrante (elle s'arrête à la surface de la peau sans occasionner de lésions). En revanche, lors d'une contamination, l'émission Alpha (la plus ionisante comparé aux autres types de radiations) déposera toute son énergie dans le corps, ce qui pourra provoquer de façon irréversible beaucoup plus de dommages que les Beta, Gamma, ou encore rayonnements X (notamment la mutations des chromosomes).</text> <text>On différencie la <bold>contamination interne et externe</bold>, car si vous portez sur vous la source de radiation (exemple : une petite poussière radioactive sur votre EPI), vous êtes dans ce cas également contaminé. Il est alors possible de se décontaminer en effectuant différents lavages des équipements de protection et/ou douches successives (tout dépend du degré de contamination).</text> <text><radioactive></radioactive> <bold>La radio-toxicité du Plutonium 241 :</bold> <br/>Le radio-isotope <bold>Pu241</bold> est l'élément le plus dangereux connu (plus de 1000 fois plus que les autres isotopes). Il a une demi-période radioactive de <bold>14.4 années</bold>, et une activité massique de 3848000000000 Becquerels / gramme.</text> <text>Il est estimé que l'ingestion de seulement <bold>9 milligrammes</bold> de Pu241 provoquerait chez l'homme une mortalité probable de 50% au bout de 30 jours (au bout d'un an avec 0.9mg, et au bout de 1000 jours avec 0.4mg).</text> <text>Les descendants du Pu241 sont à considérer avec importance :</text> <caution>Le <bold>Plutonium 241</bold> se désintègre par <bold>radioactivité Beta-</bold> en <bold>Americium 241</bold>, un émetteur de rayonnement Gamma également particulièrement dangereux.</caution> <text>A l'instar du Pu241, d'autres isotopes comme le <bold>Pu239</bold> ont également une radio-toxicité particulièrement élevée. Par expérimentations, il est estimé que l'apparition de tumeurs pulmonaires chez l'homme après inhalation seraient provoquées par un dépôt de 200000 Bequerels soit environ <bold>87 microgrammes</bold> d'oxyde de Plutonium 239.</text> <caution>La production mondiale de Plutonium depuis sa découverte dans les années 1940 s'élève aujourd'hui à plus de <bold>500 Tonnes</bold> réparties en différents pays.</caution> <text><radioactive></radioactive> <bold>Le cas de l'Iode 131 :</bold> <br/><bold>L'Iode 131</bold> est très radioactif parce qu'il a une demi-période de seulement <bold>8.02 jours</bold>. À relativement faible dose, l'Iode 131 provoque des mutations génétiques dans les cellules ou il pénètre et les cellules voisines, ce qui est le germe du cancer.</text> <text>Paradoxalement, c'est la raison pour laquelle ce radio-isotope est plus dangereux à faibles doses qu'à fortes doses. En effet, les cellules irradiées fortement étant détruites, elles ont moins de risque de propager un cancer. Notez que l'apoptose (mort cellulaire programmée) est essentiel dans l'équilibre et la survie des organismes multi-cellulaires en réponse à la <bold>prolifération cellulaire</bold>.</text> <quote>L'Iode 131 prend place dans la <bold>thyroïde</bold> chez l'homme.</quote> <text>L'Iode 131 est un isotope volatile, il est produit en grandes quantités dans les réacteurs nucléaires, et se désintègre par <bold>radioactivité Beta-</bold> (95% des cas) en <bold>Xénon 131</bold>, c'est pourquoi les populations en zones classées à risque radiologique (accidents nucléaires) sont tenues informées et doivent le cas échéant prendre des pastilles d'Iode <bold>stable</bold> (non radioactif) afin de saturer la thyroïde, ce qui a pour effet d'empêcher l'isotope 131 d'y prendre place.</text> <text>Notez que cette prise d'Iode stable devrait s'effectuer 1 heure au moins avant la contamination, et que même l'Iode stable en grande quantité dans la thyroïde n'est pas sans effets sur la santé.</text> <text><radioactive></radioactive> <bold>La contamination au Cesium 137 :</bold> <br/>L'isotope <bold>Cesium 137</bold> est lui aussi produit en abondance dans les réacteurs nucléaires, et est l'un des nombreux produits de fission de L'Uranium. Le Cesium 137 se désintègre par <bold>radioactivité Beta-</bold> en <bold>Baryum 137m</bold> instable (m pour isomère), puis en Baryum 137 cette fois-ci stable.</text> <text>Le Cesium 137 a une demi-période de 30.15 années. Avec le Strontium 90, il fait partie des déchets radioactifs à vie moyenne.</text> <caution>Le Cesium 137 est la principale source de contamination de la chaîne alimentaire due aux essais nucléaires, et aux accidents de Tchernobyl et Fukushima.</caution> <text>Le Cesium 137 est assez mobile, il se répand sur les sols, les minéraux, se fixe dans les végétaux et les êtres vivants (notamment au niveau des muscles).</text> <text>La communauté scientifique internationale émet l'hypothèse que le Cesium 137 se réparti de façon homogène dans la masse musculaire de l'homme, tandis-que certains scientifiques Russes prétendent qu'il pourrait se concentrer au niveau du cœur de l'individu, provoquant diverses pathologies cardiaques (notamment des arythmies).</text> <text>Si il ne se stock pas définitivement dans le corps, le Cesium 137 à une période biologique d'environ 100 jours (temps après lequel il est évacué par l'organisme), ce qui dans ce cas précis signifie qu'1 noyau de Cesium 137 seulement sur 160 a le temps de se désintégrer à l'intérieur du corps.</text> <text><radioactive></radioactive> <bold>La chaîne de désintégration du Radium 226 :</bold> <br/>Le <bold>Radium 226</bold> par <bold>radioactivité Alpha</bold> et demi-période de 1602 ans, se désintègre en <bold>Radon 222</bold>, un gaz radioactif à la demi-période très courte (3.824 jours) et donc très radioactif. Plus largement, le Radon fait partie de la chaîne de désintégration de l'Uranium et du Thorium, on en trouve donc dans les mines d'Uranium, et les constructions en granite.</text> <quote>Le Radium fut découvert par Pierre et Marie Curie en 1898 et a trouvé de multiples applications. Il est aujourd'hui interdit à cause de sa radio-toxicité.</quote> <text>À l'époque (années 1920/1930) ou on ne connaissait pas bien encore les dangers de la radioactivité, le Radium (sous différents isotopes) a été largement utilisé (car brillant dans le noir et aux soit-disant effets thérapeutiques) dans <bold>des produits du quotidien</bold> (chiffres et aiguilles des réveils, pendules, boussoles, différentes crèmes pour le visage, laine pour bébés au Radium, etc...) et à usage professionnel (instruments pour le médical, cadrans des instruments de navigation en avionique, etc...). On ventait également ses bienfaits dans des stations thermales (aux eaux radioactives).</text> <text>Les femmes qui peignaient au Radium (mélange de poudre de Radium, d'eau, et de colle) dans les manufactures étaient des ouvrières non informées sur les risques, elles affinaient la pointe de leurs pinceaux enduits de Radium (dont les poils finissaient par s'abîmer) avec leurs lèvres et leurs langues afin de continuer à peindre avec précision. Les conséquences sanitaires ne se sont pas fait attendre : cancers de la mâchoire et du cou.</text> <caution>Le <bold>Plomb 214 et 210</bold> (deux descendants du Radium 226) ne sont pas stables, ils peuvent rester dans les poumons lorsque le Radon 222 est inhalé avant de se stabiliser en <bold>Plomb 206</bold> (isotope stable) en passant par différentes étapes de désintégration (isotopes radioactifs de Polonium et de Bismuth).</caution> <text>Pour se faire une idée de la complexité des descendants d'un isotope radioactif, ci-dessous la chaîne de désintégration de <bold>l'Uranium 238</bold> (appelée chaîne du Radium) qui passe par le <bold>Radium 226</bold> (la demi-période est notée entre parenthèses) :</text> <quote><bold>Uranium 238</bold> > Radioactivité Alpha (4.4688 milliards d'années) <br/>Thorium 234 > Radioactivité Beta- + Gamma (24.1 jours) <br/>Protactinium 234 > Radioactivité Beta- + Gamma (1.17 minutes) <br/>Uranium 234 > Radioactivité Alpha (245500 années) <br/>Thorium 230 > Radioactivité Alpha + Gamma (75380 années) <br/><bold>Radium 226</bold> > Radioactivité Alpha + Gamma (1602 années) <br/><bold>Radon 222</bold> > Radioactivité Alpha (3.8235 jours) <br/>Polonium 218 > Radioactivité Alpha (3.1 minutes) <br/><bold>Plomb 214</bold> > Radioactivité Beta- + Gamma (26.8 minutes) <br/>Bismuth 214 > Radioactivité Beta- + Gamma (19.9 minutes) <br/>Polonium 214 > Radioactivité Alpha (164.3 microsecondes) <br/><bold>Plomb 210</bold> > Radioactivité Beta- + Gamma (22.2 années) <br/>Bismuth 210 > Radioactivité Beta- (5.012 jours) <br/>Polonium 210 > Radioactivité Alpha (138.376 jours) <br/><bold>Plomb 206</bold> (stable)</quote> <text>Il est important de notifier que certaines des désintégrations <bold>Alpha</bold> ou <bold>Beta-</bold> à différentes étapes de la chaîne sont accompagnées d'émissions <bold>Gamma</bold> plus ou moins importantes.</text> <text>Ceci n'est pas le seul parcourt possible, par exemple dans un certain nombre de cas le Polonium 218 peut se désintégrer par radioactivité Beta- et devenir de l'Astate 218, le Bismuth 214 peut se désintégrer par radioactivité Alpha et se transformer en Thallium 210, etc...</text> <quote>Cet interlude était un aperçu pour les non-initiés de ce qu'est la radioactivité, j'espère vous avoir donné envie d'en savoir plus !</quote> <title>Quelques informations sur le compteur Geiger :</title> <underline></underline> <text><bold>Programmation de l'automate programmable MODULABLE M20 avec MODULE :</bold> <br/>Le programme en langage C++ fonctionnant avec MODULE est téléchargeable ici :</text> <a href="download/cpp/geiger_counter.zip"><download>Télécharger le programme en langage C++</download></a> <a href="photo/dsc02826.jpg"><img src="thumbnail/dsc02826.jpg"></img></a> <a href="photo/dsc02824.jpg"><img src="thumbnail/dsc02824.jpg"></img></a> <text><bold>Connexions (automate programmable MODULABLE M20 sur les différents systèmes embarqués) :</bold></text> <caution>- Port 1 sur anode del (témoin lumineux des coups du tube Geiger). <br/>- Port 2 sur cathode galvanomètre (lecture analogique des coups du tube Geiger). <br/>- Port 3 sur cathode buzzer de signalement (témoin sonore des coups du tube Geiger). <br/>- Port 4 sur broche SHOCK (coups) élévateur de tension +400V (détection de la fermeture du tube Geiger). <br/>- Port 11 sur broche SS (slave select) afficheur à digits 1. <br/>- Port 12 sur broche MOSI (master output slave input) afficheur à digits 1. <br/>- Port 14 sur broche SCK (serial clock) afficheur à digits 1. <br/>- Port 16 sur curseur bouton rotatif (sélection des modes). <br/>- Port 17 sur interrupteur de visualisation des coups / seconde maximums relevés. <br/>- Port 18 sur interrupteur de visualisation des doses maximales relevées. <br/>- Port 20 sur sortie pont diviseur de tension 10kΩ / 1kΩ (alarme niveau de batterie faible).</caution> <text><bold>Quelques étapes de l'assemblage des autres parties du projet :</bold> <br/>Fabrication des cartes électroniques pour l'affichage :</text> <a href="photo/dsc02741.jpg"><img src="thumbnail/dsc02741.jpg"></img></a> <a href="photo/dsc02782.jpg"><img src="thumbnail/dsc02782.jpg"></img></a> <a href="photo/dsc02788.jpg"><img src="thumbnail/dsc02788.jpg"></img></a> <a href="photo/dsc02808.jpg"><img src="thumbnail/dsc02808.jpg"></img></a> <text><bold>Élévateur de tension +400V pour l'alimentation du tube Geiger :</bold> <br/>Prototypage et conception finale :</text> <a href="photo/dsc02511.jpg"><img src="thumbnail/dsc02511.jpg"></img></a> <a href="photo/dsc02334.jpg"><img src="thumbnail/dsc02334.jpg"></img></a> <text><bold>Usinage des différentes pièces :</bold> <br/>Aluminium, ertalon, et découpe des tôles de cuivre :</text> <a href="photo/dsc02318.jpg"><img src="thumbnail/dsc02318.jpg"></img></a> <a href="photo/dsc02320.jpg"><img src="thumbnail/dsc02320.jpg"></img></a> <a href="photo/dsc02847.jpg"><img src="thumbnail/dsc02847.jpg"></img></a> <a href="photo/dsc02321.jpg"><img src="thumbnail/dsc02321.jpg"></img></a> <text><bold>Matériel utilisé pour l'usinage des pièces :</bold> <br/>Fraiseuse, perceuse à colonne, tour à métal :</text> <a href="photo/dsc02323.jpg"><img src="thumbnail/dsc02323.jpg"></img></a> <a href="photo/dsc02327.jpg"><img src="thumbnail/dsc02327.jpg"></img></a> <text><bold>Modification d'un petit Galvanomètre :</bold> <br/>Et assemblage sur les pièces usinées :</text> <a href="photo/dsc02805.jpg"><img src="thumbnail/dsc02805.jpg"></img></a> <a href="photo/dsc02835.jpg"><img src="thumbnail/dsc02835.jpg"></img></a> <a href="photo/dsc02842.jpg"><img src="thumbnail/dsc02842.jpg"></img></a> <a href="photo/dsc02851.jpg"><img src="thumbnail/dsc02851.jpg"></img></a> <text><bold>Câblage et montage final de l'ensemble :</bold> <br/>Puis validation du fonctionnement :</text> <a href="photo/dsc02823.jpg"><img src="thumbnail/dsc02823.jpg"></img></a> <a href="photo/dsc02866.jpg"><img src="thumbnail/dsc02866.jpg"></img></a> <a href="photo/dsc02856.jpg"><img src="thumbnail/dsc02856.jpg"></img></a> <a href="photo/dsc02861.jpg"><img src="thumbnail/dsc02861.jpg"></img></a> <a href="photo/dsc06711.jpg"><img src="thumbnail/dsc06711.jpg"></img></a> <a href="photo/dsc02868.jpg"><img src="thumbnail/dsc02868.jpg"></img></a> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectHoldSwitch.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectHoldSwitch"><back>Retour</back></a> <a href="projectMax604.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>L'interrupteur d'alimentation maintenue</title> <underline></underline> <text>Ce petit circuit électronique permet de <bold>maintenir l'alimentation d'un montage</bold> lorsque l'interrupteur de coupure d'alimentation passe à l'état ouvert. Seul l'automate programmable <bold>décidera lui-même de couper l'alimentation générale</bold> en temps voulu.</text> <a href="photo/dsc07820.jpg"><img src="thumbnail/dsc07820.jpg"></img></a> <a href="photo/dsc07817.jpg"><img src="thumbnail/dsc07817.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/hold_switch.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Cette carte dispose de <bold>2 entrées pour l'alimentation</bold> (une qui par exemple peut servir à connecter une batterie, l'autre pouvant servir à connecter un cordon de charge de la batterie), <bold>1 sortie d'alimentation maintenue</bold> par l'automate programmable, et <bold>1 pont diviseur de tension</bold> (10kΩ / 1kΩ) afin de récupérer la valeur de la tension d'alimentation sur un microcontrôleur sans risques.</text> <quote>L'utilité du maintien d'une alimentation lorsque l'utilisateur décide l'arrêt d'un système peut avoir de nombreuses applications possibles : <br/>- Sécurité qui laisse un système critique actif avant l'extinction totale. <br/>- Sauvegarde de données dans une mémoire EEPROM avant la coupure de l'alimentation.</quote> <text>Ou plus simplement, jouer une musique à l'allumage et à l'extinction de votre montage électronique...</text> <caution>Par sécurité, l'alimentation maintenue ne peut être coupée par l'automate programmable que <bold>lorsque l'interrupteur de coupure générale est ouvert !</bold> Il est donc impossible de couper l'alimentation inopinément (via une erreur dans le programme par exemple).</caution> <a href="photo/dsc07814.jpg"><img src="thumbnail/dsc07814.jpg"></img></a> <a href="photo/dsc07818.jpg"><img src="thumbnail/dsc07818.jpg"></img></a> <text><bold>Connexions (source d'alimentation sur interrupteur d'alimentation maintenue) :</bold></text> <caution>- Anode ou masse de la source d'alimentation sur connecteur à souder INPUT GND (masse). <br/>- Cathode de la source d'alimentation sur connecteur à souder INPUT +6V/+26V (pôle positif).</caution> <text><bold>Connexions (interrupteur d'alimentation maintenue sur automate programmable) :</bold></text> <caution>- Connecteur à souder OUTPUT GND (masse) sur broche ou connecteur à souder POWER GND. <br/>- Connecteur à souder OUTPUT +6V/+26V (pôle positif) sur broche ou connecteur à souder POWER +6V/+26V. <br/>- Broche STATE (état de l'interrupteur) sur port GPIO (ou interruption) pour détecter lorsque l'interrupteur est ouvert ou fermé. <br/>- Broche HOLD (auto-maintien) sur port GPIO afin de maintenir l'alimentation. <br/>- Broche VOLT (tension de l'alimentation via le pont diviseur de tension 10kΩ / 1kΩ) sur port GPIO connecté au convertisseur analogique/numérique afin de récupérer la tension d'alimentation sans risques (facultatif).</caution> <a href="photo/dsc07821.jpg"><img src="thumbnail/dsc07821.jpg"></img></a> <a href="photo/dsc07819.jpg"><img src="thumbnail/dsc07819.jpg"></img></a> <text><bold>Les caractéristiques de la carte :</bold> <br/>- 2 connecteurs à souder INPUT GND (masse) pour l'alimentation. <br/>- 2 connecteurs à souder INPUT +6V/+26V (pôle positif) pour l'alimentation. <br/>- 1 connecteur à souder OUTPUT GND (masse) pour l'alimentation maintenue. <br/>- 1 connecteur à souder OUTPUT +6V/+26V (pôle positif) pour l'alimentation maintenue. <br/>- 1 broche STATE (état) pour détecter la position de l'interrupteur (0V = ouvert, +5V = fermé). <br/>- 1 broche HOLD (auto-maintien) pour piloter le maintien de l'alimentation. <br/>- 1 broche VOLT (tension) reliée à la sortie du pont diviseur de tension 10kΩ / 1kΩ intégré (pour récupérer la tension de l'alimentation sur l'automate programmable sans risques). <br/>- Dimensions : 36.83mm x 35.56mm. <br/>- Fixation de l'ensemble par le pas de vis de l'interrupteur.</text> <text><bold>Liste des composants :</bold></text> <quote>1x Interrupteur inverseur (on/on) unipolaire à levier (3 broches, pas 4.7mm) <br/>1x Régulateur de tension LM2931 (version fixée +5V, boîtier TO-92) <br/>5x Résistances 1kΩ carbones 0.25W (tolérance 5%) <br/>1x Résistance 1kΩ métal 0.25W (tolérance 1%) <br/>4x Résistances 10kΩ carbones 0.25W (tolérance 5%) <br/>1x Résistance 10kΩ métal 0.25W (tolérance 1%) <br/>1x Résistance 22kΩ carbone 0.25W (tolérance 5%) <br/>2x Résistances 100kΩ carbones 0.25W (tolérance 5%) <br/>1x Condensateur 100pF céramique (pas 5.08mm, tension >5V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >26V) <br/>1x Condensateur 22μF électrolytique tantale (pas 2.54mm, tension >5V) <br/>2x Diodes Schottky 1N5819 <br/>3x Transistors bipolaires 2N3904 (boîtier TO-92) <br/>1x Transistor bipolaire 2N3906 (boîtier TO-92) <br/>1x Transistor bipolaire BC638 (boîtier TO-92) <br/>3x Broches mâles (pas 2.54mm)</quote> <a href="photo/dsc07789.jpg"><img src="thumbnail/dsc07789.jpg"></img></a> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectIntervalometer.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectIntervalometer"><back>Retour</back></a> <a href="projectUselessMachine.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>L'intervallomètre pour la photographie</title> <underline></underline> <text><bold>L'intervallomètre</bold> est un projet dont j'avais de plus en plus la nécessité en photo, en effet il permet de piloter le déclencheur d'un appareil photo numérique :</text> <a href="photo/dsc06392.jpg"><img src="thumbnail/dsc06392.jpg"></img></a> <a href="photo/dsc03690.jpg"><img src="thumbnail/dsc03690.jpg"></img></a> <caution>Le déclenchement est réglable et s'effectue à intervalles réguliers (d'où l'appellation). Il permet de prendre des photos par exemple toutes les secondes.</caution> <text>Pour effectuer une prise de vue en mouvement, j'ai équipé mon boîtier d'un bouton rotatif et d'une <bold>sortie PWM</bold> ce qui permet de faire fonctionner un servo-moteur, et donc de mettre en mouvement à vitesse fixe ou variable, dans un sens ou dans l'autre un chariot (slider) sur lequel est fixé l'appareil photo.</text> <text>Un buzzer de signalement indique le nombre de secondes de vidéo prises (à 24 images / seconde), cela signifie que toutes les 24 photos le buzzer émet un signal. Ceci permet de connaître l'état en cours de la prise de vue pour un montage futur en post-production. Ce buzzer sert également d'alarme <bold>niveau faible de la batterie</bold> (en dessous de +6V) et est accompagné du clignotement d'un témoin lumineux (la del d'alimentation).</text> <a href="photo/dsc06385.jpg"><img src="thumbnail/dsc06385.jpg"></img></a> <a href="photo/dsc06413.jpg"><img src="thumbnail/dsc06413.jpg"></img></a> <text>Une <bold>prise de charge</bold> externe (standard XT30) permet de recharger la batterie via un cordon et un chargeur NIMH adapté.</text> <quote>L'intervallomètre peut être utilisé comme appareil pour effectuer des photographies longues poses, utiles notamment en astro-photographie.</quote> <text>Il peut être utilisé dans une prise de vue fixe, en mouvement sur un chariot, ou éventuellement à main-levée comme c'est le cas ici dans cet essai :</text> <video src="video/00006.mov" controls></video> <text>Ci-dessous, photo de gauche, le boîtier fixé sur un stabilisateur de caméra (Glidecam HD-2000) que j'utilise habituellement dans d'autres circonstances, en l'occurrence pour réaliser des séquences filmées. Photo de droite, la batterie NIMH d'alimentation fabriquée sur-mesure pour que l'ensemble soit compact :</text> <a href="photo/dsc03796.jpg"><img src="thumbnail/dsc03796.jpg"></img></a> <a href="photo/dsc06373.jpg"><img src="thumbnail/dsc06373.jpg"></img></a> <text><bold>Programmation de l'automate programmable MODULABLE M20 avec MODULE :</bold> <br/>Le programme en langage C++ fonctionnant avec MODULE est téléchargeable ici :</text> <a href="download/cpp/intervalometer.zip"><download>Télécharger le programme en langage C++</download></a> <text><bold>Connexions (automate programmable MODULABLE M20 sur les différents systèmes embarqués) :</bold></text> <caution>- Port 1 sur signal PWM servo-moteur (chariot). <br/>- Port 2 sur cathode buzzer de signalement. <br/>- Port 12 sur anode del (témoin d'alimentation). <br/>- Port 15 sur curseur bouton rotatif (vitesse et sens du chariot). <br/>- Port 16 sur sortie pont diviseur de tension 10kΩ / 4.7kΩ (alarme niveau de batterie faible). <br/>- Port 18 sur entrée déclencheur (vers l'appareil photo). <br/>- Port 19 sur interrupteur chariot (démarrage du servo-moteur). <br/>- Port 20 sur interrupteur photo (démarrage d'une séquence photo).</caution> <text><bold>Les caractéristiques de l'intervallomètre :</bold> <br/>- Automate programmable MODULABLE M20 équipé du microcontrôleur ATmega328P. <br/>- Interrupteur d'allumage (on/off). <br/>- Interrupteur 3 positions de démarrage de la prise de vue (off/chariot/chariot + photo). <br/>- Bouton rotatif de réglage de la vitesse du chariot. <br/>- Témoin d'alimentation (del) et buzzer de signalement. <br/>- Sortie déclencheur pour l'appareil photo. <br/>- Sortie PWM pour le servo-moteur du chariot. <br/>- Accumulateur NIMH (+2.4V par élément) 4S 300mAh (+9.6V). <br/>- Prise de charge de la batterie (XT30). <br/>- Alarme niveau de batterie faible. <br/>- Boitier en aluminium très robuste. <br/>- Fixations par vis M6 (perçage taraudé).</text> <quote>L'interrupteur 3 positions permet d'amener le chariot en position souhaitée sans prendre de photos.</quote> <text>Photo ci-dessous, la fermeture de la boîte, il n'y a pas beaucoup de place !</text> <a href="photo/dsc06448.jpg"><img src="thumbnail/dsc06448.jpg"></img></a> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectMax604.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectMax604"><back>Retour</back></a> <a href="projectGeigerBoostConverter.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Le régulateur de tension +3.3V</title> <underline></underline> <text>Le régulateur de tension <bold>+3.3V</bold> est indispensable pour alimenter certains composants électroniques comme par exemple le nRF24L01+ qui est un émetteur/récepteur 2.4GHz, ou encore le gyroscope MPU6050.</text> <a href="photo/dsc07425.jpg"><img src="thumbnail/dsc07425.jpg"></img></a> <a href="photo/dsc07092.jpg"><img src="thumbnail/dsc07092.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/max604.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>La régulation est basée sur le composant <bold>MAX604</bold> et permet d'obtenir une tension stable de <bold>+3.3V</bold> avec un courant maximum de <bold>500mA</bold>. Cette carte peut être alimentée avec une tension pouvant varier de <bold>+4.3V</bold> à <bold>+11.5V</bold>.</text> <text><bold>Connexions (automate programmable sur régulateur de tension +3.3V) :</bold></text> <caution>- Broche GND disponible sur broche INPUT GND (masse). <br/>- Broche +5V disponible sur broche INPUT +4.3V/+11.5V (pôle positif).</caution> <text><bold>Connexions (régulateur de tension +3.3V sur périphérique à alimenter) :</bold></text> <caution>- Broche OUTPUT GND (masse) sur broche GND. <br/>- Broche OUTPUT +3.3V (pôle positif) sur broche +3.3V.</caution> <a href="photo/dsc07454.jpg"><img src="thumbnail/dsc07454.jpg"></img></a> <text><bold>Les caractéristiques de la carte :</bold> <br/>- Régulateur de tension MAX604 +3.3V 500mA. <br/>- 1 broche INPUT GND (masse) pour l'alimentation. <br/>- 1 broche INPUT +4.3V/+11.5V (pôle positif) pour l'alimentation. <br/>- 1 broche OUTPUT GND (masse) pour alimenter un périphérique. <br/>- 1 broche OUTPUT +3.3V (pôle positif) pour alimenter un périphérique. <br/>- Dimensions : 29.21mm x 22.86mm. <br/>- Entre-axes de fixations : 21.59mm x 15.24mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Régulateur de tension MAX604 (version fixée +5V, boîtier DIP-8) <br/>1x Résistance 100Ω carbone 0.25W (tolérance 5%) <br/>1x Condensateur 100nF électrolytique tantale (pas 2.54mm, tension >3.3V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >3.3V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >11.5V) <br/>1x Diode Schottky 1N5817 <br/>1x Del 3mm (pas 2.54mm, couleur de votre choix) <br/>1x Support DIP-8 300mil <br/>4x Broches mâles (pas 2.54mm)</quote> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectMax7219Digit.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectMax7219Digit"><back>Retour</back></a> <a href="projectMax7219DigitMini.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>L'afficheur à digits MAX7219</title> <underline></underline> <text><bold>L'afficheur à diodes électroluminescences</bold> est le compagnon idéal de l'automate programmable parce qu'il permet de créer une interface visuelle entre l'utilisateur et la machine :</text> <a href="photo/dsc07755.jpg"><img src="thumbnail/dsc07755.jpg"></img></a> <a href="photo/dsc07734.jpg"><img src="thumbnail/dsc07734.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/max7219_digit.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Cet afficheur est très utile pour réaliser des projets demandant un <bold>retour d'informations visuelles</bold> de la par de l'automate programmable. Il est équipé du très populaire <bold>MAX7219</bold>, un composant qui communique en <bold>SPI</bold> avec le microcontrôleur.</text> <text><bold>Ports des automates programmables concernés par le SPI :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 11 (PB2) = SS (slave select) <br/>- Port 12 (PB3) = MOSI (master output slave input) <br/>- Port 13 (PB4) = MISO (master input slave output) <br/>- Port 14 (PB5) = SCK (serial clock) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 5 (PB4) = SS (slave select) <br/>- Port 6 (PB5) = MOSI (master output slave input) <br/>- Port 7 (PB6) = MISO (master input slave output) <br/>- Port 8 (PB7) = SCK (serial clock)</caution> <text><bold>Connexions (afficheur sur automate programmable) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SS (slave select) sur port SS ou tout autre port d'entrée/sortie disponible (sauf MISO qui doit rester libre sauf si il est déjà utilisé par un autre périphérique également SPI). <br/>- Broche MOSI (master output slave input) sur port MOSI. <br/>- Broche SCK (serial clock) sur port SCK.</caution> <text><bold>Connexions (afficheur en cascade sur autre afficheur) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SS (slave select) sur broche SS disponible. <br/>- Broche MISO (master input slave output) sur broche MOSI. <br/>- Broche SCK (serial clock) sur broche SCK disponible.</caution> <a href="photo/dsc02466.jpg"><img src="thumbnail/dsc02466.jpg"></img></a> <text><bold>Les caractéristiques de la carte :</bold> <br/>- 2 broches GND (masse) pour l'alimentation. <br/>- 2 broches +5V (pôle positif) pour l'alimentation. <br/>- 2 broches SS (slave select) pour la communication SPI. <br/>- 1 broche MOSI (master output slave input) pour la communication SPI. <br/>- 1 broche MISO (master input slave output) pour la communication SPI. <br/>- 2 broches SCK (serial clock) pour la communication SPI. <br/>- Branchements en cascade. <br/>- 8 digits pour l'affichage des caractères. <br/>- Dimensions : 116.84mm x 21.59mm. <br/>- Entre-axes de fixations : 109.22mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Contrôleur d'affichage MAX7219 (boîtier DIP-24) <br/>8x Afficheurs à digits SC56-11 (couleur de votre choix) <br/>1x Résistance 9.53kΩ métal 0.25W (tolérance 1%) <br/>1x Condensateur 100nF céramique (pas 5.08mm, tension >5V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >5V) <br/>1x Support DIP-24 300mil <br/>10x Broches mâles (pas 2.54mm)</quote> <a href="photo/dsc07721.jpg"><img src="thumbnail/dsc07721.jpg"></img></a> <title>Conseils pour l'assemblage :</title> <underline></underline> <text>Les afficheurs à digits <bold>SC56-11</bold> doivent être soudés en dernier, en effet ils masquent les broches des autres composants sur la face opposée du PCB, rendant dans le cas contraire leur soudure impossible :</text> <a href="photo/dsc07729.jpg"><img src="thumbnail/dsc07729.jpg"></img></a> <a href="photo/dsc07732.jpg"><img src="thumbnail/dsc07732.jpg"></img></a> <text>Cet ordre de montage respecté, il est ensuite conseillé d'écourter toutes les broches des composants avec une pince coupante adaptée, ceci permettant d'éviter un éventuel <bold>défaut de planéité des afficheurs sur le PCB</bold> (dans le cas ou un afficheur toucherait les broches traversantes d'un autre composant).</text> <a href="photo/dsc07720.jpg"><img src="thumbnail/dsc07720.jpg"></img></a> <a href="photo/dsc07733.jpg"><img src="thumbnail/dsc07733.jpg"></img></a> <a href="photo/dsc07739.jpg"><img src="thumbnail/dsc07739.jpg"></img></a> <a href="photo/dsc07735.jpg"><img src="thumbnail/dsc07735.jpg"></img></a> <text>Une fois ces opérations effectuées, le montage se finalise normalement.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectMax7219DigitMini.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectMax7219DigitMini"><back>Retour</back></a> <a href="projectMax7219Matrix.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Le mini afficheur à digits MAX7219</title> <underline></underline> <text>Cet afficheur à diodes électroluminescences est ici en <bold>version compacte</bold>, équipé d'un affichage composé d'éléments SC3611 plus petits que les SC5611 :</text> <a href="photo/dsc07807.jpg"><img src="thumbnail/dsc07807.jpg"></img></a> <a href="photo/dsc07800.jpg"><img src="thumbnail/dsc07800.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/max7219_digit_mini.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Cet afficheur de part ses faibles dimensions, permet l'élaboration de systèmes embarqués assez légers, compacts et maniables (appareils de mesures, instruments divers, etc...).</text> <a href="photo/dsc07874.jpg"><img src="thumbnail/dsc07874.jpg"></img></a> <text>Comme mes autres afficheurs, ce présent système d'affichage multiplexé fonctionne à l'aide du composant <bold>MAX7219</bold>, et communique en <bold>SPI</bold> avec le microcontrôleur.</text> <text><bold>Ports des automates programmables concernés par le SPI :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 11 (PB2) = SS (slave select) <br/>- Port 12 (PB3) = MOSI (master output slave input) <br/>- Port 13 (PB4) = MISO (master input slave output) <br/>- Port 14 (PB5) = SCK (serial clock) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 5 (PB4) = SS (slave select) <br/>- Port 6 (PB5) = MOSI (master output slave input) <br/>- Port 7 (PB6) = MISO (master input slave output) <br/>- Port 8 (PB7) = SCK (serial clock)</caution> <text><bold>Connexions (afficheur sur automate programmable) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SS (slave select) sur port SS ou tout autre port d'entrée/sortie disponible (sauf MISO qui doit rester libre sauf si il est déjà utilisé par un autre périphérique également SPI). <br/>- Broche MOSI (master output slave input) sur port MOSI. <br/>- Broche SCK (serial clock) sur port SCK.</caution> <text><bold>Connexions (afficheur en cascade sur autre afficheur) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SS (slave select) sur broche SS disponible. <br/>- Broche MISO (master input slave output) sur broche MOSI. <br/>- Broche SCK (serial clock) sur broche SCK disponible.</caution> <a href="photo/dsc02466.jpg"><img src="thumbnail/dsc02466.jpg"></img></a> <text><bold>Les caractéristiques de la carte :</bold> <br/>- 2 broches GND (masse) pour l'alimentation. <br/>- 2 broches +5V (pôle positif) pour l'alimentation. <br/>- 2 broches SS (slave select) pour la communication SPI. <br/>- 1 broche MOSI (master output slave input) pour la communication SPI. <br/>- 1 broche MISO (master input slave output) pour la communication SPI. <br/>- 2 broches SCK (serial clock) pour la communication SPI. <br/>- Branchements en cascade. <br/>- 8 digits pour l'affichage des caractères. <br/>- Dimensions (face avant) : 76.2mm x 21.59mm. <br/>- Dimensions (face arrière) : 55.88mm x 21.59mm. <br/>- Entre-axes de fixations : 68.58mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Contrôleur d'affichage MAX7219 (boîtier DIP-24) <br/>8x Afficheurs à digits SC36-11 (couleur de votre choix) <br/>1x Résistance 9.53kΩ métal 0.25W (tolérance 1%) <br/>1x Condensateur 100nF céramique (pas 5.08mm, tension >5V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >5V) <br/>1x Support DIP-24 300mil <br/>26x Broches mâles (pas 2.54mm)</quote> <a href="photo/dsc07774.jpg"><img src="thumbnail/dsc07774.jpg"></img></a> <title>Conseils pour l'assemblage :</title> <underline></underline> <text>Cette carte est <bold>composée de deux parties distinctes</bold> qu'il convient de finaliser entièrement avant de les assembler l'une avec l'autre. La première partie permet la fixation des blocs d'affichage à digits SC3611, la deuxième partie loge les autres composants (le circuit intégré, son support, une résistance, deux condensateurs, les broches de fixation des deux PCB, ainsi que les broches de l'interface de communication et d'alimentation) :</text> <a href="photo/dsc07792.jpg"><img src="thumbnail/dsc07792.jpg"></img></a> <a href="photo/dsc07806.jpg"><img src="thumbnail/dsc07806.jpg"></img></a> <text>En premier lieu, il est conseillé de souder les broches de fixation sur le PCB équipé des blocs d'affichage à digits SC3611, et à posteriori de positionner et souder ces derniers sur l'autre face du PCB. Ensuite, je recommande de <bold>couper au plus court les broches des blocs SC3611</bold> qui dépassent afin d'éviter par la suite qu'elles ne viennent toucher (et court-circuiter par la même occasion) le circuit contenant tout les autres composants de cet assemblage.</text> <a href="photo/dsc07778.jpg"><img src="thumbnail/dsc07778.jpg"></img></a> <a href="photo/dsc07779.jpg"><img src="thumbnail/dsc07779.jpg"></img></a> <a href="photo/dsc07781.jpg"><img src="thumbnail/dsc07781.jpg"></img></a> <a href="photo/dsc07776.jpg"><img src="thumbnail/dsc07776.jpg"></img></a> <text>Après quoi il est nécessaire d'assembler entièrement et indépendamment la deuxième partie contenant tout les autres composants, <bold>avant de la positionner en sandwich sur la première partie</bold>. Dans le cas contraire d'un assemblage final avant d'avoir encore soudé tout les composants, il serait alors fort délicat de venir les braser correctement (les broches traversantes se trouvant plus ou moins masquées).</text> <a href="photo/dsc07777.jpg"><img src="thumbnail/dsc07777.jpg"></img></a> <a href="photo/dsc07791.jpg"><img src="thumbnail/dsc07791.jpg"></img></a> <text>Une fois dans la situation de la photo de droite ci-dessus, il ne reste plus qu'à superposer les deux parties, et les solidariser entres-elles. À noter que les broches de fixation servent à la fois pour le multiplexage, et pour la solidité de l'ensemble.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectMax7219Matrix.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectMax7219Matrix"><back>Retour</back></a> <a href="projectBuzzer.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>L'afficheur à matrice MAX7219</title> <underline></underline> <text>À l'instar de l'afficheur à digits, <bold>l'afficheur à matrice 8 x 8</bold> permet un visuel graphique (pixels) et offre l'avantage de pouvoir dessiner des formes ou des symbols :</text> <a href="photo/dsc02450.jpg"><img src="thumbnail/dsc02450.jpg"></img></a> <a href="photo/dsc02478.jpg"><img src="thumbnail/dsc02478.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/max7219_matrix.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Cet afficheur est équipé du <bold>MAX7219</bold>, un composant qui gère le <bold>multiplexage des dels</bold>, il communique en <bold>SPI</bold> avec le microcontrôleur.</text> <text>La vitesse de communication SPI et le nombre de ports disponibles sur mes automates programmables (M20 ou M32) sont suffisants pour pouvoir réaliser un montage avec de nombreux afficheurs (projet de borne de jeu d'arcade par exemple).</text> <text><bold>Ports des automates programmables concernés par le SPI :</bold></text> <caution><bold>Automate programmable MODULABLE M20 :</bold> <br/>- Port 11 (PB2) = SS (slave select) <br/>- Port 12 (PB3) = MOSI (master output slave input) <br/>- Port 13 (PB4) = MISO (master input slave output) <br/>- Port 14 (PB5) = SCK (serial clock) <br/> <br/><bold>Automate programmable MODULABLE M32 :</bold> <br/>- Port 5 (PB4) = SS (slave select) <br/>- Port 6 (PB5) = MOSI (master output slave input) <br/>- Port 7 (PB6) = MISO (master input slave output) <br/>- Port 8 (PB7) = SCK (serial clock)</caution> <text><bold>Connexions (afficheur sur automate programmable) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SS (slave select) sur port SS ou tout autre port d'entrée/sortie disponible (sauf MISO qui doit rester libre sauf si il est déjà utilisé par un autre périphérique également SPI). <br/>- Broche MOSI (master output slave input) sur port MOSI. <br/>- Broche SCK (serial clock) sur port SCK.</caution> <text><bold>Connexions (afficheur en cascade sur autre afficheur) :</bold></text> <caution>- Broche GND (masse) sur broche GND disponible. <br/>- Broche +5V (pôle positif) sur broche +5V disponible. <br/>- Broche SS (slave select) sur broche SS disponible. <br/>- Broche MISO (master input slave output) sur broche MOSI. <br/>- Broche SCK (serial clock) sur broche SCK disponible.</caution> <a href="photo/dsc02466.jpg"><img src="thumbnail/dsc02466.jpg"></img></a> <text><bold>Les caractéristiques de la carte :</bold> <br/>- 2 broches GND (masse) pour l'alimentation. <br/>- 2 broches +5V (pôle positif) pour l'alimentation. <br/>- 2 broches SS (slave select) pour la communication SPI. <br/>- 1 broche MOSI (master output slave input) pour la communication SPI. <br/>- 1 broche MISO (master input slave output) pour la communication SPI. <br/>- 2 broches SCK (serial clock) pour la communication SPI. <br/>- Branchements en cascade. <br/>- 8 x 8 pixels pour l'affichage. <br/>- Dimensions : 53.34mm x 40.64mm. <br/>- Entre-axes de fixations : 45.72mm x 33.02mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Contrôleur d'affichage MAX7219 (boîtier DIP-24) <br/>1x Afficheur à matrice TC15-11 (couleur de votre choix) <br/>1x Résistance 9.53kΩ métal 0.25W (tolérance 1%) <br/>1x Condensateur 100nF céramique (pas 5.08mm, tension >5V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >5V) <br/>1x Support DIP-24 300mil <br/>10x Broches mâles (pas 2.54mm)</quote> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectModulableM20.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectModulableM20"><back>Retour</back></a> <a href="projectMax7219Digit.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>L'automate programmable MODULABLE M20</title> <underline></underline> <text>Cet <bold>automate programmable</bold> associé à la bibliothèque MODULE (c'est-à-dire compatible en terme de fonctions et d'entrées/sorties avec MODULE), était utilisé dans mes précédents projets en électronique, il peut être équipé des microcontrôleurs <bold>ATmega48P</bold>, <bold>ATmega88P</bold>, <bold>ATmega168P</bold> ou <bold>ATmega328P</bold>.</text> <a href="photo/dsc02341.jpg"><img src="thumbnail/dsc02341.jpg"></img></a> <a href="photo/dsc01789.jpg"><img src="thumbnail/dsc01789.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/modulable_m20.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Selon si votre projet requiert plus ou moins de mémoire <bold>Flash</bold>, <bold>EEPROM</bold>, ou <bold>SRAM</bold>, 4 microcontrôleurs différents peuvent être implantés sur la carte MODULABLE M20 :</text> <caution><bold>Microcontrôleur ATmega48P :</bold> <br/>- Mémoire Flash = 4096 octets (4Kio) <br/>- Mémoire EEPROM = 256 octets (0.25Kio) <br/>- Mémoire SRAM = 512 octets (0.5Kio) <br/> <br/><bold>Microcontrôleur ATmega88P :</bold> <br/>- Mémoire Flash = 8192 octets (8Kio) <br/>- Mémoire EEPROM = 512 octets (0.5Kio) <br/>- Mémoire SRAM = 1024 octets (1Kio) <br/> <br/><bold>Microcontrôleur ATmega168P :</bold> <br/>- Mémoire Flash = 16384 octets (16Kio) <br/>- Mémoire EEPROM = 512 octets (0.5Kio) <br/>- Mémoire SRAM = 1024 octets (1Kio) <br/> <br/><bold>Microcontrôleur ATmega328P :</bold> <br/>- Mémoire Flash = 32768 octets (32Kio) <br/>- Mémoire EEPROM = 1024 octets (1Kio) <br/>- Mémoire SRAM = 2048 octets (2Kio)</caution> <text>L'antériorité de ce projet veux que j'ai débuté la programmation de MODULE avec le microcontrôleur <bold>ATmega328P</bold> et cet automate programmable MODULABLE M20. Mais depuis, j'ai conçu un automate programmable (le M32) plus intéressant sur bons nombres de points, c'est pourquoi je considère donc l'automate programmable présenté ici comme obsolète même si il n'a en soit pas de défauts.</text> <quote>Le M20 en comparaison au M32 garde néanmoins l'avantage d'être <bold>moins onéreux en terme de coût des composants</bold>, et de dimension (longueur seulement) légèrement plus petite.</quote> <a href="photo/dsc06376.jpg"><img src="thumbnail/dsc06376.jpg"></img></a> <a href="photo/dsc06385.jpg"><img src="thumbnail/dsc06385.jpg"></img></a> <caution>Cet automate programmable peut être alimenté de <bold>+6V</bold> jusqu'à <bold>+26V</bold>, ce qui est favorable à une batterie <bold>Lithium/Polymère de 2S à 6S</bold> standard (+8.4V à +25.2V), ou encore à des sources d'alimentation assez communes de <bold>+12V</bold> ou <bold>+24V</bold> en courant continu.</caution> <text>Néanmoins, selon le courant demandé (inférieur à 1A), le circuit de régulation de tension embarqué dans cet automate programmable pourra malgré tout délivrer une <bold>tension stable de +5V</bold> via une tension d'alimentation supérieure à +5V mais <bold>inférieure à +6V</bold>, ceci grâce aux faibles pertes (dropout) du régulateur LM2940.</text> <quote>Également, le microcontrôleur fonctionnera normalement (dans ses spécifications techniques) avec des <bold>tensions d'alimentation de seulement +5V</bold> en entrée (toujours sur le connecteur POWER), ce qui est intéressant en terme de sécurité notamment pour certains systèmes embarqués dont la tension d'alimentation est critique.</quote> <text><bold>Les caractéristiques de la carte :</bold> <br/>- Microcontrôleur ATmega48P, ATmega88P, ATmega168P ou ATmega328P. <br/>- Régulateur de tension LM2940 +5V 1A. <br/>- 1 port POWER (alimentation) de +6V à +26V. <br/>- 1 port ISP (programmation in-situ) pour la programmation du microcontrôleur. <br/>- 20 entrées/sorties GPIO (partie commande), avec 20 +5V et 20 GND (partie puissance). <br/>- Fréquence de fonctionnement : 16MHz. <br/>- Dimensions : 66.04mm x 40.64mm. <br/>- Entre-axes de fixations : 58.42mm x 33.02mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Microcontrôleur ATMEGA48P (boîtier DIP-28) <br/>ou 1x Microcontrôleur ATMEGA88P (boîtier DIP-28) <br/>ou 1x Microcontrôleur ATMEGA168P (boîtier DIP-28) <br/>ou 1x Microcontrôleur ATMEGA328P (boîtier DIP-28) <br/>1x Régulateur de tension LM2940 (version fixée +5V, boîtier TO-220) <br/>1x Résistance 220Ω carbone 0.25W (tolérance 5%) <br/>1x Résistance 10kΩ carbone 0.25W (tolérance 5%) <br/>2x Condensateurs 22pF céramiques (pas 5.08mm, tension >5V) <br/>3x Condensateurs 100nF céramiques (pas 5.08mm, tension >5V) <br/>1x Condensateur 100nF électrolytique tantale (pas 2.54mm, tension >5V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >26V) <br/>1x Condensateur 22μF électrolytique tantale (pas 2.54mm, tension >5V) <br/>1x Condensateur 100μF électrolytique aluminium (pas 2mm, tension >5V) <br/>1x Inductance 10μH self (boîtier axial) <br/>1x Diode Schottky 1N5819 <br/>1x Quartz 16MHz (pas 5.08mm) <br/>1x Del 3mm (pas 2.54mm, couleur de votre choix) <br/>1x Support DIP-28 300mil <br/>68x Broches mâles (pas 2.54mm) <br/>1x Dissipateur thermique (pour boîtier TO-220)</quote> <text><bold>Correspondances des ports (MODULE par rapport aux microcontrôleurs) :</bold></text> <caution>- Port 1 = PD0 <br/>- Port 2 = PD1 <br/>- Port 3 = PD2 <br/>- Port 4 = PD3 <br/>- Port 5 = PD4 <br/>- Port 6 = PD5 <br/>- Port 7 = PD6 <br/>- Port 8 = PD7 <br/>- Port 9 = PB0 <br/>- Port 10 = PB1 <br/>- Port 11 = PB2 <br/>- Port 12 = PB3 <br/>- Port 13 = PB4 <br/>- Port 14 = PB5 <br/>- Port 15 = PC0 <br/>- Port 16 = PC1 <br/>- Port 17 = PC2 <br/>- Port 18 = PC3 <br/>- Port 19 = PC4 <br/>- Port 20 = PC5</caution> <text>Quelques photos du prototype à l'époque ou je débutais la programmation de MODULE :</text> <a href="photo/dsc01673.jpg"><img src="thumbnail/dsc01673.jpg"></img></a> <a href="photo/dsc01667.jpg"><img src="thumbnail/dsc01667.jpg"></img></a> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectModulableM32.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectModulableM32"><back>Retour</back></a> <a href="projectModulableM20.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>L'automate programmable MODULABLE M32</title> <underline></underline> <text>Ce nouvel <bold>automate programmable</bold> associé à la bibliothèque MODULE (c'est-à-dire compatible en terme de fonctions et d'entrées/sorties avec MODULE), sera utilisé dans tous mes futurs projets en électronique, il peut être équipé des microcontrôleurs <bold>ATmega164P</bold>, <bold>ATmega324P</bold>, <bold>ATmega644P</bold> ou <bold>ATmega1284P</bold>.</text> <a href="photo/dsc07387.jpg"><img src="thumbnail/dsc07387.jpg"></img></a> <a href="photo/dsc07391.jpg"><img src="thumbnail/dsc07391.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/modulable_m32.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <text>Selon si votre projet requiert plus ou moins de mémoire <bold>Flash</bold>, <bold>EEPROM</bold>, ou <bold>SRAM</bold>, 4 microcontrôleurs différents peuvent être implantés sur la carte MODULABLE M32 :</text> <caution><bold>Microcontrôleur ATmega164P :</bold> <br/>- Mémoire Flash = 16384 octets (16Kio) <br/>- Mémoire EEPROM = 512 octets (0.5Kio) <br/>- Mémoire SRAM = 1024 octets (1Kio) <br/> <br/><bold>Microcontrôleur ATmega324P :</bold> <br/>- Mémoire Flash = 32768 octets (32Kio) <br/>- Mémoire EEPROM = 1024 octets (1Kio) <br/>- Mémoire SRAM = 2048 octets (2Kio) <br/> <br/><bold>Microcontrôleur ATmega644P :</bold> <br/>- Mémoire Flash = 65536 octets (64Kio) <br/>- Mémoire EEPROM = 2048 octets (2Kio) <br/>- Mémoire SRAM = 4096 octets (4Kio) <br/> <br/><bold>Microcontrôleur ATmega1284P :</bold> <br/>- Mémoire Flash = 131072 octets (128Kio) <br/>- Mémoire EEPROM = 4096 octets (4Kio) <br/>- Mémoire SRAM = 16384 octets (16Kio)</caution> <text>L'automate programmable MODULABLE M32 est le cœur de mes montages électroniques, il contient dans le microcontrôleur <bold>le programme binaire</bold> écrit à l'origine en langage C++ à l'aide de MODULE permettant de gérer toute la logique combinatoire et mathématique du montage.</text> <text>En comparaison à l'automate programmable MODULABLE M20, le M32 est bien plus intéressant sur bien des aspects. En effet, il dispose de <bold>32 entrées/sorties</bold> groupées par 4 (logique des ports respectivement B, D, C et A), et peut développer un courant jusqu'à <bold>8A</bold> à l'aide d'un régulateur de tension <bold>LM2940</bold> assisté par un transistor bipolaire <bold>MJE15033</bold>.</text> <caution>L'automate programmable MODULABLE M32 (tout comme le M20) peut être alimenté de <bold>+6V</bold> jusqu'à <bold>+26V</bold>, ce qui est favorable à une batterie <bold>Lithium/Polymère de 2S à 6S</bold> standard (+8.4V à +25.2V), ou encore à des sources d'alimentation assez communes de <bold>+12V</bold> ou <bold>+24V</bold> en courant continu.</caution> <text>Néanmoins, selon le courant demandé (inférieur à 1A), le circuit de régulation de tension embarqué dans cet automate programmable pourra malgré tout délivrer une <bold>tension stable de +5V</bold> via une tension d'alimentation supérieure à +5V mais <bold>inférieure à +6V</bold>, ceci grâce aux faibles pertes (dropout) du régulateur LM2940 couplé au transistor bipolaire MJE15033.</text> <quote>Également, le microcontrôleur fonctionnera normalement (dans ses spécifications techniques) avec des <bold>tensions d'alimentation de seulement +5V</bold> en entrée (toujours sur le connecteur POWER), ce qui est intéressant en terme de sécurité notamment pour certains systèmes embarqués dont la tension d'alimentation est critique.</quote> <text>Cette alimentation robuste ainsi que les caractéristiques inhérentes aux microcontrôleurs qui peuvent être embarqués sur cette carte, élargissent le domaine d'application de l'automate programmable MODULABLE M32, ce qui permet entre autre de réaliser des projets lourds et imposants en terme de ligne de programmation et de complexité mathématique et logique.</text> <a href="photo/dsc07320.jpg"><img src="thumbnail/dsc07320.jpg"></img></a> <a href="photo/dsc07397.jpg"><img src="thumbnail/dsc07397.jpg"></img></a> <text><bold>Les caractéristiques de la carte :</bold> <br/>- Microcontrôleur ATmega164P, Atmega324P, Atmega644P ou ATmega1284P. <br/>- Régulateur de tension LM2940 +5V 1A assisté par un transistor bipolaire MJE15033 8A. <br/>- 2 ports POWER (alimentation) de +6V à +26V (broches ou connecteurs à souder). <br/>- 1 port ISP (programmation in-situ) pour la programmation du microcontrôleur. <br/>- 32 entrées/sorties GPIO (partie commande), avec 32 +5V et 32 GND (partie puissance). <br/>- Fréquence de fonctionnement : 16MHz. <br/>- Dimensions : 88.9mm x 40.64mm. <br/>- Entre-axes de fixations : 81.28mm x 33.02mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <text><bold>Liste des composants :</bold></text> <quote>1x Microcontrôleur ATMEGA164P (boîtier DIP-40) <br/>ou 1x Microcontrôleur ATMEGA324P (boîtier DIP-40) <br/>ou 1x Microcontrôleur ATMEGA644P (boîtier DIP-40) <br/>ou 1x Microcontrôleur ATMEGA1284P (boîtier DIP-40) <br/>1x Régulateur de tension LM2940 (version fixée +5V, boîtier TO-220) <br/>1x Résistance 10Ω carbone 0.25W (tolérance 5%) <br/>1x Résistance 220Ω carbone 0.25W (tolérance 5%) <br/>1x Résistance 10kΩ carbone 0.25W (tolérance 5%) <br/>2x Condensateurs 22pF céramiques (pas 5.08mm, tension >5V) <br/>3x Condensateurs 100nF céramiques (pas 5.08mm, tension >5V) <br/>1x Condensateur 100nF électrolytique tantale (pas 2.54mm, tension >5V) <br/>1x Condensateur 10μF électrolytique aluminium (pas 2mm, tension >26V) <br/>1x Condensateur 22μF électrolytique tantale (pas 2.54mm, tension >5V) <br/>3x Condensateurs 100μF électrolytiques aluminium (pas 2mm, tension >5V) <br/>1x Condensateur 100μF électrolytique aluminium (pas 2.5mm, tension >26V) <br/>1x Inductance 10μH self (boîtier axial) <br/>1x Diode Schottky 1N5819 <br/>1x Transistor bipolaire MJE15033 (boîtier TO-220) <br/>1x Quartz 16MHz (pas 5.08mm, profil bas) <br/>1x Del 3mm (pas 2.54mm, couleur de votre choix) <br/>1x Support DIP-40 600mil <br/>98x Broches mâles (pas 2.54mm) <br/>1x Dissipateur thermique (pour boîtier TO-220)</quote> <text>À gauche les composants nécessaires, à droite le PCB nu :</text> <a href="photo/dsc07200.jpg"><img src="thumbnail/dsc07200.jpg"></img></a> <a href="photo/dsc07352.jpg"><img src="thumbnail/dsc07352.jpg"></img></a> <text><bold>Correspondances des ports (MODULE par rapport aux microcontrôleurs) :</bold></text> <caution>- Port 1 = PB0 <br/>- Port 2 = PB1 <br/>- Port 3 = PB2 <br/>- Port 4 = PB3 <br/>- Port 5 = PB4 <br/>- Port 6 = PB5 <br/>- Port 7 = PB6 <br/>- Port 8 = PB7 <br/>- Port 9 = PD0 <br/>- Port 10 = PD1 <br/>- Port 11 = PD2 <br/>- Port 12 = PD3 <br/>- Port 13 = PD4 <br/>- Port 14 = PD5 <br/>- Port 15 = PD6 <br/>- Port 16 = PD7 <br/>- Port 17 = PC0 <br/>- Port 18 = PC1 <br/>- Port 19 = PC2 <br/>- Port 20 = PC3 <br/>- Port 21 = PC4 <br/>- Port 22 = PC5 <br/>- Port 23 = PC6 <br/>- Port 24 = PC7 <br/>- Port 25 = PA7 <br/>- Port 26 = PA6 <br/>- Port 27 = PA5 <br/>- Port 28 = PA4 <br/>- Port 29 = PA3 <br/>- Port 30 = PA2 <br/>- Port 31 = PA1 <br/>- Port 32 = PA0</caution> <title>Précautions pour l'assemblage :</title> <underline></underline> <text>Il convient pour assembler cette carte électronique de respecter un ordre lors de la soudure de certains composants, notamment ceux <bold>implantés en dessous du microcontrôleur</bold> :</text> <a href="photo/dsc07205.jpg"><img src="thumbnail/dsc07205.jpg"></img></a> <a href="photo/dsc07214.jpg"><img src="thumbnail/dsc07214.jpg"></img></a> <text>Un pliage spécifique doit être effectué avec une pince adéquate afin que les condensateurs viennent se loger sans toucher le microcontrôleur et son support :</text> <a href="photo/dsc06995.jpg"><img src="thumbnail/dsc06995.jpg"></img></a> <a href="photo/dsc07221.jpg"><img src="thumbnail/dsc07221.jpg"></img></a> <text>Une fois cette opération réalisée l'assemblage se fait normalement.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectPinHeader.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectPinHeader"><back>Retour</back></a> <a href="projectRadioControl.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>La platine de distribution 24 broches</title> <underline></underline> <text>Cette carte de <bold>distribution</bold> peut s'avérer utile lorsque l'on souhaite <bold>mettre en commun un ou plusieurs ports</bold> d'un automate programmable (bus USART, SPI, TWI, etc...), ainsi que la distribution de la puissance <bold>+5V</bold>, <bold>+3.3V</bold> et la <bold>masse</bold> (GND) vers certains périphériques.</text> <a href="photo/dsc07416.jpg"><img src="thumbnail/dsc07416.jpg"></img></a> <a href="photo/dsc07083.jpg"><img src="thumbnail/dsc07083.jpg"></img></a> <text>Le plan de fabrication de cette carte est disponible au <bold>format Gerber</bold> ici :</text> <a href="download/pcb/pin_header.zip"><download>Télécharger le plan de fabrication du circuit imprimé</download></a> <caution>Cette carte peux véhiculer un <bold>courant supérieur à 1A</bold> par ligne.</caution> <text><bold>Les caractéristiques de la carte :</bold> <br/>- 3 lignes séparées x 8 broches communes pour la distribution. <br/>- Courant par ligne supérieur à 1A. <br/>- Dimensions : 35.56mm x 10.16mm. <br/>- Entre-axes de fixations : 27.94mm. <br/>- Fixations par vis M3 (perçages diamètre 3.2mm).</text> <a href="photo/dsc07100.jpg"><img src="thumbnail/dsc07100.jpg"></img></a> <text><bold>Liste des composants :</bold></text> <quote>24x Broches mâles (pas 2.54mm)</quote> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectQuadcopter.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectQuadcopter"><back>Retour</back></a> <a href="projectGeigerCounter.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Le quadri-hélicoptère</title> <underline></underline> <text>Le <bold>quadri-hélicoptère</bold> (et non pas drone) est un type d'hélicoptère propulsé par quatre moteurs. Ce projet a débuté en 2015, était fonctionnel en 2016 avec ma radiocommande de modélisme standard achetée dans le commerce (de marque FUTABA), et a été finalisé pour fonctionner en <bold>voltige 3D</bold> avec ma radiocommande de conception personnelle en 2017.</text> <text>Vidéo ci-dessous, un vol en cours de conception (filmé au début du projet en 2015) :</text> <video src="video/00003.mov" controls></video> <text><bold>Programmation de l'automate programmable MODULABLE M32 avec MODULE :</bold> <br/>Le programme en langage C++ fonctionnant avec MODULE est téléchargeable ici :</text> <a href="download/cpp/quadcopter.zip"><download>Télécharger le programme en langage C++</download></a> <text>Les paramètres (settings) sont à régler via la radiocommande, voici les valeurs que j'ai indiqué qui sont optimisées pour un hélicoptère comportant des caractéristiques précises (voir les caractéristiques de mon hélicoptère plus bas) :</text> <caution>- "FRES" = <bold>1000Hz</bold> (fréquence PWM des ESC). <br/>- "CUES" = <bold>187μs</bold> (coupure des ESC, moteur arrêté). <br/>- "MIEN" = <bold>190μs</bold> (gaz minimum des ESC en vol normal). <br/>- "MAEN" = <bold>250μs</bold> (gaz maximum des ESC en vol normal). <br/>- "MIEI" = <bold>185μs</bold> (gaz minimum des ESC en vol inversé). <br/>- "MAEI" = <bold>125μs</bold> (gaz maximum des ESC en vol inversé). <br/>- "SPPI" = <bold>360°/s</bold> (vitesse angulaire maximale sur l'axe de tangage). <br/>- "SPRO" = <bold>360°/s</bold> (vitesse angulaire maximale sur l'axe de roulis). <br/>- "SPYA" = <bold>360°/s</bold> (vitesse angulaire maximale sur l'axe de lacet). <br/>- "GAPI" = <bold>97%</bold> (gain du gyroscope sur l'axe de tangage). <br/>- "GARO" = <bold>94%</bold> (gain du gyroscope sur l'axe de roulis). <br/>- "GAYA" = <bold>97%</bold> (gain du gyroscope sur l'axe de lacet). <br/>- "TRAV" = <bold>40%</bold> (proportion des débattements de l'axe de tangage et de roulis par rapport au lacet). <br/>- "PROP" = <bold>90%</bold> (diminution des gains en fonction des gaz). <br/>- "LOCK" = <bold>60%</bold> (augmentation des gains lors des acrobaties). <br/>- "LIMI" = <bold>90%</bold> (limitation des gaz maximums).</caution> <text><bold>Connexions (automate programmable MODULABLE M32 sur les différents systèmes embarqués) :</bold></text> <caution>- Port 5 sur broche CSN (slave select) composant nRF24L01+. <br/>- Port 6 sur broche MOSI (master output slave input) composant nRF24L01+. <br/>- Port 7 sur broche MISO (master input slave output) composant nRF24L01+. <br/>- Port 8 sur broche SCK (serial clock) composant nRF24L01+. <br/>- Port 9 sur broche PWM ESC moteur 1 (avant gauche). <br/>- Port 10 sur broche PWM ESC moteur 2 (avant droit). <br/>- Port 11 sur broche PWM ESC moteur 3 (arrière gauche). <br/>- Port 12 sur broche PWM ESC moteur 4 (arrière droit). <br/>- Port 17 sur broche SCL (serial clock line) composant MPU6050. <br/>- Port 18 sur broche SDA (serial data line) composant MPU6050. <br/>- Port 25 sur broche WAVE (onde) buzzer de signalement. <br/>- Port 31 sur sortie pont diviseur de tension 10kΩ / 1kΩ (tension de la batterie).</caution> <title>Historique, faisabilité, et caractéristiques :</title> <underline></underline> <text>Cette idée que j'avais de faire se sustenter un objet semi-autonome en stationnaire au dessus du sol ne date pas d'hier, mais elle est devenue un peu plus réalité à l'époque ou j'ai commencé le pilotage des aéro-modèles, c'est-à-dire en 2003.</text> <a href="photo/dsc02038.jpg"><img src="thumbnail/dsc02038.jpg"></img></a> <a href="photo/dsc02027.jpg"><img src="thumbnail/dsc02027.jpg"></img></a> <text>À cette période, la propulsion électrique des modèles réduits d'aéronefs était à ses débuts, mais on voyait déjà apparaître sur les terrains d'aéromodélisme des mini-hélicoptères radio-commandés qui peinaient tout juste à se soulever de quelques centimètres, puis quelques mètres au dessus du sol.</text> <text>Depuis ce temps, la technologie a fait un bond, notamment au niveau des accumulateurs au <bold>Lithium/Polymère</bold> et des <bold>moteurs sans charbons</bold> (brushless), ce qui a permis des avancées jusqu'alors insoupçonnées en terme de durée de vol et de performances.</text> <quote>La miniaturisation de l'électronique, notamment des <bold>gyroscopes</bold> et des <bold>émetteurs/récepteurs radios</bold>, a progressé à tel point qu'aujourd'hui en terme de volume, toute l'électronique tient dans une petite boite !</quote> <text><bold>Contraintes de stabilisation en vol :</bold> <br/>Le vol basique d'un aéronef à 4 hélices a été avec MODULE solutionné sans difficulté. En effet avec MODULE, vous pouvez programmer et faire fonctionner très facilement des gyroscopes, accéléromètres, magnétomètres, baromètres, servo-moteurs et ESC électroniques (contrôleurs de moteurs sans charbons) sans passer des heures en programmation.</text> <text>En revanche, la ou <bold>l'algorithme de vol</bold> (prototype en ces temps), a montré ses premiers signes de faiblesse, s'est trouvé lors des premiers tests d'accélérations et d'acrobaties diverses (boucles, tonneaux). Ainsi, après de nombreux tests en vol (mises gaz au ralenti/pleins gaz et angles vifs à plat et sur le dos volontairement), je me suis aperçu qu'il fallait programmer bien plus qu'une simple stabilisation (plus évoluée qu'un pendule stabilisé par exemple).</text> <text>Pour se faire, j'ai dû suivre une logique différente de ma première approche, à savoir tenir compte de plusieurs paramètres, notamment la consigne que doit tenir l'aéronef face aux ordres angulaires demandés, la prise en compte du rendement des hélices (variable avec la vitesse de rotation), la sensibilité des corrections que l'algorithme doit effectuer, variables selon les ordres du pilote aux gaz et au cyclique, ainsi que cette sensibilité glissante au cours du temps afin de tenir compte des ordres très rapides aux commandes.</text> <text>Tous ces calculs assez subtils participent au verrouillage en vol de l'ensemble, et permettent des vols acrobatiques assez poussés (notamment pour le vol 3D).</text> <a href="photo/dsc02050.jpg"><img src="thumbnail/dsc02050.jpg"></img></a> <a href="photo/dsc02048.jpg"><img src="thumbnail/dsc02048.jpg"></img></a> <text><bold>Projet validé :</bold> <br/>L'expérience acquise lors de la conception de cet hélicoptère, de la logique de l'algorithme de vol, ainsi que le nombre de vols effectués, m'ont permis de constater la fiabilité de l'ensemble des cartes électroniques à bord du modèle ainsi que de la programmation.</text> <text><bold>Les caractéristiques du quadri-hélicoptère :</bold> <br/>- Automate programmable MODULABLE M32 équipé du microcontrôleur ATmega644P. <br/>- Émetteur/récepteur radio 2.4GHz (composant nRF24L01+). <br/>- Communication bidirectionnelle. <br/>- Antenne Trèfle omnidirectionnelle 4 branches (7dBm). <br/>- Communication par trames de 32 bits. <br/>- Gyroscope MPU6050. <br/>- Buzzer de signalement. <br/>- Système à tolérance de pannes (fail-safe) envoyé par la radiocommande sur 6 bits (0 à 63). <br/>- Contrôleurs de moteurs sans charbons KISS ESC 2-5S 24A Race Edition. <br/>- Moteurs sans charbons TIGER MOTORS MN2206 2000kV. <br/>- Hélices 3D Graupner 6" x 3". <br/>- Accumulateur Lithium/Polymère TURNIGY 4S 2200mAh (+14.8V). <br/>- Tension de la batterie envoyée à la radiocommande sur 10 bits (0 à 1023). <br/>- Allumage ou extinction du modèle ou de la radiocommande dans n'importe quel ordre. <br/>- Châssis en tubes d'aluminium 10mm x 12mm. <br/>- Entre-axes moteurs : 372mm x 372mm.</text> <text>Boite de transport sur-mesure en contre-plaqué 10mm :</text> <a href="photo/dsc01916.jpg"><img src="thumbnail/dsc01916.jpg"></img></a> <title>Les sécurités d'avant vol :</title> <underline></underline> <text>Afin de garantir le non-démarrage des moteurs à l'allumage du modèle, j'ai mis en place quelques sécurités (ou conditions à remplir) : <br/>- Vérification de <bold>l'arrivée de toutes les voies</bold> de la radiocommande. <br/>- Vérification que l'interrupteur moteurs coupés soit <bold>activé</bold>. <br/>- Vérification que le manche de gaz soit <bold>centré entre 45% à 55%</bold> de sa course totale (ralenti moteur en mode 3D) sans trim ni courbe de gaz. <br/>- Buzzer de signalement (code erreur sonore).</text> <text>Une fois ces conditions remplies, l'hélicoptère est prêt à être mis en vol, il est alors en attente du basculement de l'interrupteur de coupure moteurs pour une mise au ralenti de ces derniers.</text> <a href="photo/dsc01583.jpg"><img src="thumbnail/dsc01583.jpg"></img></a> <a href="photo/dsc01905.jpg"><img src="thumbnail/dsc01905.jpg"></img></a> <quote>Cet hélicoptère est également équipé d'un <bold>système à tolérance de pannes</bold> (fail-safe), ce qui permet d'arrêter les moteurs lorsque la radiocommande ne répond plus.</quote> <title>Possibilités d'évolution :</title> <underline></underline> <text>Il est possible d'utiliser le gyroscope/magnétomètre <bold>BNO055</bold> à l'aide de la classe dédiée <bold>Bno055.h</bold> si vous souhaitez voler avec un horizon artificiel (vol assisté conseillé pour les débutants), ainsi que le baromètre <bold>BMP180</bold> à l'aide de la classe <bold>Bmp180.h</bold> si vous souhaitez mesurer la pression atmosphérique et donc connaître l'altitude de votre hélicoptère.</text> <text>Exemple en vol de l'utilisation de <bold>l'horizon artificiel</bold> :</text> <video src="video/00004.mov" controls></video> <title>Responsabilité :</title> <underline></underline> <text>Vous pouvez utiliser la partie matérielle et logicielle que je propose, mais en matière de communication sans fil 2.4GHz et d'aéromodélisme, des précautions doivent être prises.</text> <caution>Je ne pourrais être tenu pour responsable si vous faites une mauvaise utilisation de mes systèmes !</caution> <text>Ce qui signifie que vous utilisez ma programmation en toute connaissance de cause et en règle avec la loi en vigueur dans votre pays (notamment en ce qui concerne les lieux de vols autorisés, les fréquences et puissances d'émissions des radio-émetteurs, etc...).</text> <caution>On ne rappellera jamais assez que <bold>les hélicoptères en aéromodélisme ne sont pas des jouets</bold>, surtout quand il s'agit d'hélices entraînées à 36000 tours / minute comme c'est le cas sur cet hélicoptère !</caution> <text>Vous devez prendre une extrême précaution lors des réglages d'un tel hélicoptère, il est vivement conseillé de démonter les hélices lors des réglages et de les remonter uniquement lorsque vous êtes certains de vos paramètres.</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectRadioControl.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectRadioControl"><back>Retour</back></a> <a href="projectQuadcopter.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>La radiocommande</title> <underline></underline> <text>Ce projet de <bold>radiocommande</bold> est la suite logique de mon intérêt et de mes convictions pour un modélisme aérien tel qu'il devrait être pratiqué, c'est-à-dire la conception et la fabrication de systèmes radio-pilotés en partant réellement de zéro.</text> <a href="photo/dsc07891.jpg"><img src="thumbnail/dsc07891.jpg"></img></a> <a href="photo/dsc07874.jpg"><img src="thumbnail/dsc07874.jpg"></img></a> <a href="photo/dsc06915.jpg"><img src="thumbnail/dsc06915.jpg"></img></a> <a href="photo/dsc06927.jpg"><img src="thumbnail/dsc06927.jpg"></img></a> <a href="photo/dsc07895.jpg"><img src="thumbnail/dsc07895.jpg"></img></a> <a href="photo/dsc07686.jpg"><img src="thumbnail/dsc07686.jpg"></img></a> <text>À partir des premières ébauches sur papier, études des possibilités et contraintes techniques, schémas des circuits électroniques, conception des programmes dans la radiocommande et les modèles associés, dessins du boîtier et définition des différentes pièces d'usinage (etc...), jusqu'à la finalisation du projet, il aura fallu plus d'une année de conception, fabrication, et tests de validation.</text> <text><bold>Les caractéristiques de la radiocommande :</bold> <br/>- Automate programmable MODULABLE M32 équipé du microcontrôleur ATmega1284P. <br/>- Émetteur/récepteur (tranceiver) radio 2.4GHz (composant nRF24L01+). <br/>- Antenne Trèfle omnidirectionnelle 3 branches (7dBm). <br/>- Communication multidirectionnelle vers (sol/air air/sol) et entre (air/air) plusieurs modèles. <br/>- Communication vers périphériques relais pour applications longues distances basse puissance. <br/>- Communication par trames de 32 bits. <br/>- Affichage digital avec afficheur à digits MAX7219. <br/>- Buzzer de signalement. <br/>- Système à tolérance de pannes (fail-safe) sur 6 bits (0 à 63). <br/>- Surveillance de l'activité du modèle (watchdog) sur 6 bits (0 à 63). <br/>- 1 menu principal + 1 menu des paramètres/réglages. <br/>- Aucune mémoire de modèles (la mémoire est située dans les modèles). <br/>- Possibilité de copier les réglages d'un modèle vers un autre très facilement. <br/>- 15 paramètres/réglages par défaut envoyés par le modèle. <br/>- Réglage des trims (autour des neutres) des manches de gaz/roulis et profondeur/lacet. <br/>- Réglage d'une alarme (visuelle et sonore) tension de batterie faible du modèle (de 0V à 100V). <br/>- Réglage d'une alarme (visuelle et sonore) temporisation/chronomètre (de 0s à 3600s). <br/>- Réglage de l'inversion des manches de gaz/roulis et profondeur/lacet. <br/>- Réglage de courbes des manches de gaz/roulis et profondeur/lacet. <br/>- Jusqu'à 16 paramètres/réglages personnalisés supplémentaires envoyés par le modèle. <br/>- 4 paramètres/réglages par défaut propres à la radiocommande. <br/>- Calibration des potentiomètres des manches (si remplacement/autre). <br/>- Verrouillage des menus (plus de réglages possibles, ni d'extinction de la radiocommande). <br/>- Affichage de la tension de la batterie de la radiocommande. <br/>- Affichage de la tension de la batterie du modèle. <br/>- Affichage d'une temporisation/chronomètre (temps d'utilisation du modèle/autre). <br/>- Affichage des trims (verrouillage et remise à 0 possible par le bouton de sélection). <br/>- Affichage d'une télémétrie personnalisée. <br/>- Affichage des paramètres/réglages par défaut et personnalisés. <br/>- Menu de mise à jour des paramètres/réglages du modèle. <br/>- Menu de sauvegarde des réglages propres à la radiocommande. <br/>- Allumage ou extinction de la radiocommande ou du modèle dans n'importe quel ordre. <br/>- Accumulateur NIMH (+1.2V par élément) 8S 600mAh (+9.6V). <br/>- Prise de charge de la batterie (XT30). <br/>- Prise de programmation du microcontrôleur (mini XLR). <br/>- Boîtier fermé en aluminium, acier inoxydable, bois (contreplaqué 5mm), et ertalon. <br/>- Dimensions : 214mm x 204mm x 117mm.</text> <a href="photo/dsc07865.jpg"><img src="thumbnail/dsc07865.jpg"></img></a> <a href="photo/dsc07867.jpg"><img src="thumbnail/dsc07867.jpg"></img></a> <text><bold>L'interface électromécanique entre l'homme et la machine :</bold> <br/>- 2 manches analogiques (1 gaz/roulis + 1 tangage/lacet) sur 10 bits chacun (0 à 1023). <br/>- 4 interrupteurs de trims (3 positions) sur 2 bits chacun (0 à 2). <br/>- 1 interrupteur de coupure moteur/autre (2 positions) sur 1 bit (0 à 1). <br/>- 3 interrupteurs auxiliaires (3 positions) sur 2 bits chacun (0 à 2). <br/>- 1 bouton rotatif auxiliaire sur 10 bits (0 à 1023). <br/>- 1 bouton rotatif de sélection/menus sur 10 bits (0 à 1023). <br/>- 1 bouton poussoir de sélection/menus (2 positions, dont 1 momentanée) sur 1 bit (0 à 1). <br/>- 1 interrupteur d'alimentation maintenue on/off (2 positions).</text> <text><bold>Programmation de l'automate programmable MODULABLE M32 avec MODULE :</bold> <br/>Le programme en langage C++ fonctionnant avec MODULE est téléchargeable ici :</text> <a href="download/cpp/radio_control.zip"><download>Télécharger le programme en langage C++</download></a> <text><bold>Connexions (automate programmable MODULABLE M32 sur les différents systèmes embarqués) :</bold></text> <caution>- Port 1 sur broche STATE (état) interrupteur d'alimentation maintenue. <br/>- Port 2 sur broche HOLD (auto-maintien) interrupteur d'alimentation maintenue. <br/>- Port 3 sur broche SS (slave select) afficheur à digits. <br/>- Port 4 sur broche WAVE (onde) buzzer de signalement. <br/>- Port 5 sur broche CSN (slave select) composant nRF24L01+. <br/>- Port 6 sur broche MOSI (master output slave input) afficheur à digits et composant nRF24L01+. <br/>- Port 7 sur broche MISO (master input slave output) composant nRF24L01+. <br/>- Port 8 sur broche SCK (serial clock) afficheur à digits et composant nRF24L01+. <br/>- Port 9 sur bouton poussoir de sélection/menus. <br/>- Port 10 sur interrupteur de coupure moteur/autre. <br/>- Port 11 sur interrupteur auxiliaire A (position 1). <br/>- Port 12 sur interrupteur auxiliaire A (position 3). <br/>- Port 13 sur interrupteur auxiliaire B (position 1). <br/>- Port 14 sur interrupteur auxiliaire B (position 3). <br/>- Port 15 sur interrupteur auxiliaire C (position 1). <br/>- Port 16 sur interrupteur auxiliaire C (position 3). <br/>- Port 17 sur interrupteur trim de gaz (position 1). <br/>- Port 18 sur interrupteur trim de gaz (position 3). <br/>- Port 19 sur interrupteur trim de tangage (position 1). <br/>- Port 20 sur interrupteur trim de tangage (position 3). <br/>- Port 21 sur interrupteur trim de roulis (position 1). <br/>- Port 22 sur interrupteur trim de roulis (position 3). <br/>- Port 23 sur interrupteur trim de lacet (position 1). <br/>- Port 24 sur interrupteur trim de lacet (position 3). <br/>- Port 25 sur curseur bouton rotatif de sélection/menus. <br/>- Port 26 sur curseur manche analogique des gaz. <br/>- Port 27 sur curseur manche analogique de tangage. <br/>- Port 28 sur curseur manche analogique de roulis. <br/>- Port 29 sur curseur manche analogique de lacet. <br/>- Port 30 sur curseur bouton rotatif auxiliaire. <br/>- Port 31 sur broche VOLT (tension) interrupteur d'alimentation maintenue.</caution> <title>Le concept de cette radiocommande :</title> <underline></underline> <text>Depuis les premiers temps ou je pilote des modèles radiocommandés dans des associations d'aéromodélisme jusqu'à aujourd'hui, je me suis souvent demandé et au vu de l'avancée précédente et actuelle en matière d'électronique embarquée :</text> <caution><bold>Mais pourquoi donc les radiocommandes du commerce ont'elles des mémoires de modèles ?</bold> Les mémoires de modèles permettent en effet de retenir les réglages relatifs à un modèle, dans la mémoire de la radiocommande.</caution> <text>À ce propos je ne citerais que l'exemple d'un ami au terrain de modélisme sans le nommer, qui par mégarde se trompe assez régulièrement de mémoire de modèles (il vol avec beaucoup de choses). En conséquence cela lui arrive souvent d'écraser ses réglages, ou d'écraser son modèle tout simplement au sens physique du terme !</text> <text>En fait, cette "lacune" des mémoires de modèles dans les radiocommandes modernes trouve historiquement ses racines dans la conception même des premiers radio-émetteurs/récepteurs. En effet, <bold>les premières radiocommandes se contentaient uniquement d'être émetteur d'information</bold>, et le modèle étant lui simplement un récepteur. Dans cette situation (unidirectionnelle), il est facile de comprendre que le modèle reste toujours muet.</text> <text>Plus tard, les concepteurs et divers industriels se sont décidés (au vue de la demande qui augmentait) à ajouter une communication du modèle vers la radiocommande, sur un circuit électronique bien distinct et avec une antenne radio supplémentaire sur le modèle et la radiocommande. C'est un retour air/sol qui a été appelé <bold>télémétrie</bold> (en rapport avec la télémétrie à l'époque des débuts de la conquête spatiale jusqu'à nos jours).</text> <quote>L'avancée en matière de miniaturisation des composants permet aujourd'hui d'avoir <bold>dans une même puce un émetteur et un récepteur</bold>, qui se sert de la même antenne radio pour communiquer, ces systèmes sont appelés <bold>tranceivers</bold> (émetteurs/récepteurs).</quote> <caution>Le concept que je développe ici permet de vous expliquer l'idée même de ma radiocommande, <bold>celle-ci n'a en effet aucune mémoire de modèles</bold>, ayant souhaité aller au bout de ma logique, <bold>c'est le modèle qui contient la mémoire !</bold></caution> <text>Cette idée simple permet beaucoup de choses, notamment le fait que <bold>c'est le modèle qui envoi des paramètres et réglages personnalisés à la radiocommande</bold>, qui à l'origine dispose d'un menu des paramètres et réglages vide. La radiocommande se voit alors garnie de paramètres personnalisés relatifs au modèle qui est actuellement en communication avec elle. Ces paramètres peuvent être de n'importe quel type et agir sur n'importe quelle fonction du modèle. Ce retour radio air/sol permet également à la radiocommande de disposer de <bold>l'affichage de la tension de la batterie du modèle en temps réel</bold>, et d'une <bold>télémétrie personnalisée</bold> en fonction du modèle.</text> <quote>Une fois cette notion comprise, tout est alors possible.</quote> <text>Pour régler votre modèle réduit, ma radiocommande dispose alors de <bold>15 paramètres par défaut</bold> qui en général sont assez communs aux modèles réduits (trims, alarmes, inversion des voies, courbes de gaz, etc...), et d'un maximum de <bold>16 paramètres personnalisés par le modèle</bold> (dont le type de paramètre n'est pas défini par défaut).</text> <text>Ceci est largement suffisant parce que par définition même, ces paramètres sont spécifiques au modèle considéré. Terminé les réglages et menus à n'en plus finir (souvent la plupart du temps inutilisés) dans les radiocommandes du commerce !</text> <quote>Dans ce que je propose ici, vous disposez des <bold>réglages uniquement nécessaires au modèle mis en œuvre</bold>, ce qui facilite grandement son utilisation sur le terrain de modélisme !</quote> <title>Système multidirectionnel (multiceiver) :</title> <underline></underline> <text>Le système de radiocommande 2.4GHz que je propose ici permet la <bold>communication multidirectionnelle entre la radiocommande et un ou plusieurs modèles</bold>, autorise le <bold>dialogue entre les modèles</bold> eux-mêmes (réseau d'émetteurs/récepteurs, ou multiceivers), et rend possible l'ajout de plusieurs émetteurs/récepteurs (tranceivers) embarqués dans un même véhicule (pour les gros modèles notamment).</text> <a href="photo/dsc07145.jpg"><img src="thumbnail/dsc07145.jpg"></img></a> <a href="photo/dsc07153.jpg"><img src="thumbnail/dsc07153.jpg"></img></a> <text>Tout projet est alors possible, sans même évoquer le modélisme piloté dont il est question ici :</text> <quote>Par exemple des applications robotiques mettant en œuvre des réseaux de robots qui communiquent entre-eux, et bien d'autres projets encore. Libre à vous d'imaginer vos propres applications en fonction de vos besoins !</quote> <text>Ce principe d'émetteur/récepteur intégré donne également la possibilité à l'utilisateur d'effectuer des communications longues distances en basse puissance d'émission (inférieure à 100mW), ceci par <bold>transmission de données de la radiocommande vers des périphériques relais</bold> qui se chargent non pas de traiter l'information et de l'utiliser, mais plutôt de la relayer vers d'autres périphériques afin d'atteindre la portée radio vers le modèle.</text> <caution>Cette propriété de pouvoir recevoir et émettre avec de multiples périphériques ainsi que de relayer l'information, est effectuée de manière <bold>complètement transparente pour l'utilisateur ou le programmeur</bold> via l'utilisation de ma classe Nrf24l01p.h.</caution> <text>Il est envisageable d'imaginer un robot d'exploration de décombres hors de portée radio directe avec le poste de pilotage (à cause des bardages métalliques des bâtiments par exemple), mais étant à portée radio de plusieurs relais qui se chargent seulement de transmettre (relayer) les informations aux téléopérateurs.</text> <quote>Toutes ces propriétés multidirectionnelles (multiceivers) sont à définir non pas dans la radiocommande, mais <bold>uniquement à la conception des programmes à bord de vos modèles, robots, et autres systèmes embarqués</bold> (libre à chacun de créer une logique en rapport avec le type de système piloté).</quote> <text>À noter que les paragraphes qui suivent font état d'une utilisation avec un seul modèle, car c'est mon application principale (l'aéromodélisme). Néanmoins tout ce qui est expliqué ci-dessous (utilisation des menus, fonctionnalités, etc...) fonctionne avec plusieurs modèles (suivant la logique que vous avez programmé dans leurs microcontrôleurs respectifs bien entendu).</text> <title>Démarrage de la radiocommande :</title> <underline></underline> <text>À l'allumage de la radiocommande, se propose à vous le choix de démarrer celle-ci en <bold>mode "ON AIR"</bold> (à l'antenne) ou en <bold>mode "OFF AIR"</bold> (hors antenne) en faisant pivoter le bouton rotatif de sélection. Si vous choisissez "ON AIR" (à l'antenne), le circuit radio d'émission/réception est démarré, la radiocommande se met alors à envoyer et recevoir des données, et cherche si un modèle est présent.</text> <quote><bold>Si un modèle est présent et répond à la radiocommande</bold>, cette dernière récupère alors tous les paramètres nécessaires (trims, paramètres par défaut, paramètres personnalisés, etc...) <bold>lors de ce démarrage uniquement</bold>, et vous emmène directement au menu principal pour une utilisation normale.</quote> <text><bold>Si au contraire, aucun modèle ne se présente à la radiocommande</bold>, l'affichage indiquera "BINDING" (liaison), et vous aurez le choix d'attendre ou de quitter (en appuyant sur le bouton de sélection) <bold>sans récupérer les paramètres du modèle</bold>, ce qui en conséquence vous donnera l'impossibilité de régler ses paramètres, car <bold>le menu des paramètres sera vide</bold>.</text> <caution>Attention, la radiocommande émet et reçoit des données (le circuit radio d'émission/réception est démarré) <bold>même en ayant quitté la tentative de liaison</bold> ("BINDING") avec le modèle, vous pourrez alors tout de même le piloter (sans pouvoir en changer les paramètres).</caution> <text>En résulte que les trims, alarmes, inversions des voies, et courbes (qui doivent normalement êtres récupérés du modèle, et qui sont mixés non pas dans le modèle, mais dans la radiocommande) seront alors à leur <bold>valeur par défaut</bold> ("OFF" pour les trims/alarmes/courbes, et "NOR" pour l'inversion des voies), il convient alors d'être prudent suivant le modèle piloté, et une telle configuration n'est en soit pas idéale, mais est possible.</text> <quote>Si vous démarrez la radiocommande en <bold>mode "OFF AIR"</bold> (hors antenne), cette dernière reste <bold>muette</bold> (circuit d'émission/réception éteint).</quote> <text>Dans ce cas, le menu des paramètres ("SETTINGS") vous permettra non pas de régler les paramètres du modèle (voir plus bas : "Réglages et enregistrement des paramètres"), mais plutôt de modifier <bold>certains réglages propres à la radiocommande</bold>, et enregistrés dans celle-ci (comme par exemple la calibration des manches, voir plus bas : "Calibration des potentiomètres des manches").</text> <text>Ne pas démarrer le circuit radio d'émission/réception permet également de se familiariser avec l'interface de cette radiocommande, ou bien encore de contrôler la tension de la batterie interne avant de se rendre sur votre terrain de modélisme favoris.</text> <title>Allumage de la radiocommande et du modèle :</title> <underline></underline> <text>Il n'existe aucune contrainte au niveau de l'ordre d'allumage ou de la mise hors tension de la radiocommande ou du modèle, tout deux attendent une réponse de l'autre :</text> <caution><bold>Vous pouvez allumer la radiocommande ou le modèle dans n'importe quel ordre</bold>, éteindre votre modèle ou la radiocommande quand vous le souhaitez, et rallumer l'une ou l'autre en cours d'utilisation !</caution> <a href="photo/dsc07875.jpg"><img src="thumbnail/dsc07875.jpg"></img></a> <a href="photo/dsc02048.jpg"><img src="thumbnail/dsc02048.jpg"></img></a> <text>Lorsque le modèle s'aperçoit que plus aucune radiocommande ne répond, il active alors son <bold>système à tolérance de pannes</bold> (fail-safe), et envoi en boucle les paramètres dont la radiocommande a besoin jusqu'à temps que celle-ci réponde, <bold>tout en laissant actif et parfaitement opérationnel son algorithme de vol</bold> si besoin (à définir dans la programmation du modèle lui-même).</text> <quote>Si la radiocommande a besoin de paramètres à son allumage, <bold>elle ira les chercher si un modèle est sous tension et répond</bold>, de même si le modèle a besoin de paramètres et qu'aucune radiocommande n'est allumée, <bold>il ira les chercher au moment où elle sera activée en communication</bold> (via le menu de démarrage "ON AIR").</quote> <title>Différents menus :</title> <underline></underline> <text>Ma radiocommande dispose d'un <bold>menu principal</bold> :</text> <quote>- Verrouillage de la radiocommande ("LOCK/-LOCKED-", voir plus bas : "Le verrouillage de la radiocommande"). <br/>- Visualisation de la tension de la batterie de la radiocommande et alarme ("CTRL", voir plus bas : "Alarmes"). <br/>- Visualisation de la tension de la batterie du modèle et alarme ("MODL", voir plus bas : "Alarmes"). <br/>- Visualisation d'une temporisation/chronomètre et alarme ("TIME", voir plus bas : "Alarmes"). <br/>- Visualisation et modification des trims ("THRO", "PITC", "ROLL", "YAW"). <br/>- Visualisation d'une télémétrie personnalisée ("TLMT"). <br/>- Accès au menu des paramètres ("SETTINGS").</quote> <text>À partir du menu principal et par la pression du bouton de sélection sur la section "SETTINGS" (paramètres) en <bold>mode "ON AIR"</bold> (à l'antenne), vous entrez dans le menu des paramètres/réglages dans lequel on trouve <bold>11 paramètres par défaut</bold>, ainsi qu'un maximum de <bold>16 paramètres personnalisés</bold> agrémentés par le modèle si besoin :</text> <quote><bold>Paramètres par défaut :</bold> <br/>- Réglage d'une alarme tension de batterie faible du modèle ("BMDL", voir plus bas : "Alarmes"). <br/>- Réglage de la limite d'une temporisation/chronomètre avec alarme ("TMED", voir plus bas : "Alarmes"). <br/>- Réglage de la manière dont la temporisation/chronomètre se déclenche ("TMTR", voir plus bas : "Alarmes"). <br/>- Réglage de l'inversion des manches de gaz/roulis et profondeur/lacet ("DRTH", "DRPI", "DRRO", "DRYA"). <br/>- Réglage de courbes des manches de gaz/roulis et profondeur/lacet ("CUTH", "CUPI", "CURO", "CUYA"). <br/> <br/><bold>Paramètres personnalisés :</bold> <br/>- Paramètres dont le type n'est pas défini par défaut (nom affiché dans le menu, valeur initiale, valeurs minimales et maximales possibles, etc...). <br/> <br/><bold>Autres sections :</bold> <br/>- Retour au menu principal sans enregistrer les paramètres dans le modèle ni conserver les dernières modifications effectuées ("EXIT"). <br/>- Retour au menu principal et mise à jour des paramètres dans le modèle ("UPDATE", si la radiocommande n'est pas verrouillée).</quote> <text>Lorsque la radiocommande est démarrée en <bold>mode "OFF AIR"</bold> (hors antenne, c'est-à-dire circuit d'émission/réception éteint), à partir du menu principal et par la pression du bouton de sélection sur la section "SETTINGS" (paramètres), vous entrez dans le menu dans lequel vous pouvez modifier <bold>certains réglages propres à la radiocommande</bold>, paramètres qui sont enregistrés dans sa mémoire :</text> <quote><bold>Réglages :</bold> <br/>- Calibration des potentiomètres des manches ("CLTH", "CLPI", "CLRO", "CLYA", voir plus bas : "Calibration des potentiomètres des manches"). <br/> <br/><bold>Autres sections :</bold> <br/>- Retour au menu principal sans enregistrer les paramètres dans la radiocommande ni conserver les dernières modifications effectuées ("EXIT"). <br/>- Retour au menu principal et enregistrement des paramètres dans la radiocommande ("SAVE", si la radiocommande n'est pas verrouillée).</quote> <title>Alarmes :</title> <underline></underline> <text>Ma radiocommande est équipée d'une alarme niveau de batterie faible de la radiocommande et du modèle, et d'une alarme qui s'active via une temporisation/chronomètre (lorsque le temps paramétré est dépassé).</text> <quote>Ma radiocommande est équipée d'une temporisation (chronomètre) dont la durée limite est paramétrable, et la manière dont elle se déclenche : <br/>- Avec l'interrupteur de coupure moteur/autre. <br/>- En dépassant une certaine position (réglable) au manche de gaz.</quote> <text>Au pilotage, vous avez donc le choix de déceler la fin de votre session lors du dépassement d'une certaine tension de la batterie du modèle <bold>réglable de 0V à 100V</bold> (par pas de 0.1V), et/ou du dépassement d'une temporisation/chronomètre <bold>réglable de 0s à 3600s</bold> (par pas de 1s), soit 1h au total.</text> <text>Le dépassement du temps (réglé préalablement) de la temporisation/chronomètre est indiqué de façon <bold>visuelle et sonore</bold> (alarme sonore de quelques secondes mais affichage permanent), ce chronomètre est désactivable et peut être remis à 0 à tout moment (en cours d'utilisation ou à l'arrêt). Le dépassement de la tension limite de la batterie du modèle (réglée par l'utilisateur) provoque également un affichage visuel et sonore (alarme sonore de quelques secondes mais affichage permanent).</text> <caution>Cette alarme visuelle du <bold>niveau de batterie faible du modèle</bold>, n'est qu'en à elle désactivable uniquement lorsque le niveau de la batterie dépasse à nouveau (augmente positivement) le seuil minimum que vous avez réglé en paramètre (ceci peut se produire lors du changement de la batterie de votre modèle par exemple).</caution> <text>Une alarme de niveau de batterie faible de la radiocommande existe à l'instar de celle du modèle, mais la valeur limite n'est pas réglable et est <bold>fixée à +6V</bold>, ce qui correspond à la tension minimum d'alimentation de l'automate programmable MODULABLE M32.</text> <quote>Cette alarme de niveau de batterie faible de la radiocommande intervient de manière visuelle et sonore lorsque le <bold>seuil de +6V minimum</bold> est dépassé.</quote> <text>Dans cette situation, même si la tension de la batterie de la radiocommande (pour une raison x ou y) remonte au dessus de +6V, <bold>l'alarme perdurera</bold>, seul la partie sonore une fois active pourra être désactivée (par une pression sur le bouton de sélection dans la partie relative à ce paramètre dans le menu principal), l'alarme visuelle restera qu'en à elle présente dans tous les cas.</text> <caution>Si cette alarme de niveau de batterie faible vient à s'activer (que ce soit celle de la radiocommande ou du modèle), et que votre modèle est en vol, il est alors <bold>vivement conseillé de le poser dans les plus brefs délais !</bold></caution> <text>Si aucune intervention de l'utilisateur pour désactiver ou réinitialiser l'une (ou l'ensemble) des 3 alarmes n'est effectuée, <bold>un bip se fait entendre toutes les 30 secondes</bold>, ce qui signifie qu'une alarme visuelle <bold>est toujours active</bold>. Rendez-vous alors dans le menu principal pour les désactiver (si possible).</text> <title>Inversions des voies et courbes :</title> <underline></underline> <text>En paramètres par défaut, il vous est également possible de définir <bold>le sens des voies de gaz, de tangage, de roulis, et de lacet</bold> envoyés au modèle par la radiocommande (de 0 à 1023 en mode normal, ou de 1023 à 0 en mode inversé), et de définir des valeurs de courbes, soit "OFF" pour linéaire, jusqu'à 100 qui est l'équivalent de beaucoup d'exponentiel.</text> <caution>Tout comme les trims, l'inversion des voies et les courbes sont <bold>mixés dans la radiocommande</bold>, et envoyés au modèle en l'état.</caution> <text>Si vous souhaitez inverser une ou plusieurs voies, rendez-vous dans le menu des paramètres via le menu principal en cliquant sur la section "SETTINGS" (paramètres) tout en étant en <bold>mode "ON AIR"</bold> (à l'antenne), cherchez les paramètres <bold>"DRTH"</bold>, <bold>"DRPI"</bold>, <bold>"DRRO"</bold>, ou <bold>"DRYA"</bold> (qui correspondent respectivement aux gaz, tangage, roulis, et lacet).</text> <text>Les paramètres ayant en suffixe <bold>"NOR"</bold> (normal) indiquent que la voie concernée n'est pas inversée, et ceux mentionnés <bold>"REV"</bold> (inversé) sont inversées. Pour les modifier, il vous suffit de cliquer dessus avec le bouton de sélection, ou d'utiliser les interrupteurs de trims pour en changer les valeurs. Ensuite, rendez-vous dans la section <bold>"UPDATE"</bold> (mettre à jour) pour mettre à jour les modifications dans le modèle et les prendre en compte dans la radiocommande (car ces paramètres sont mixés dans la radiocommande, et non pas le modèle).</text> <quote>En plus des trims et de l'inversion des voies, vous disposez de la possibilité de modifier les <bold>courbes de gaz, de tangage, de roulis, et de lacet</bold>. Celles-ci sont linéaires ("OFF") par défaut, et leurs actions s'appliquent de part et d'autre du neutre des manches (gaz y compris).</quote> <text>De même que pour le réglage des autres paramètres, dans le menu "SETTINGS" (paramètres), cherchez les mots <bold>"CUTH"</bold>, <bold>"CUPI"</bold>, <bold>"CURO"</bold>, ou <bold>"CUYA"</bold> (qui correspondent respectivement aux gaz, tangage, roulis, et lacet).</text> <text>Si il est indiqué <bold>"OFF"</bold>, les courbes sont <bold>linéaires</bold> (pas de courbe). Vous pouvez modifier cela via les interrupteurs de trims, ou plus rapidement à l'aide du bouton rotatif auxiliaire tout en restant appuyé sur le bouton de sélection (comme expliqué ci-dessous : "Réglages et enregistrement des paramètres").</text> <caution>Plus les valeurs des courbes seront hautes (proches de 100), plus <bold>le pilotage sera doux autour du neutre des manches</bold> et moins sensible. Le pilotage d'un modèle à forts débattements sera donc plus aisé en augmentant les valeurs des courbes.</caution> <text>À noter qu'une courbe sur l'axe des gaz peut être utile au pilotage des hélicoptères de voltige (dont le neutre, et donc le centre du manche correspond au pas 0 sur le modèle), même si pour ma part je préfère piloter sans courbe de gaz/pas (linéaire).</text> <title>Réglages et enregistrement des paramètres :</title> <underline></underline> <text>Ma radiocommande dispose de l'affichage des trims dans le menu principal, parce que leurs réglage s'effectue à tout moment via les 4 interrupteurs 3 positions prévus à cet effet (c'est pourquoi dans le menu des paramètres/réglages vous ne trouvez que 11 paramètres par défaut sur les 15 au total, soit les 4 trims en moins). <bold>Les trims sont eux aussi enregistrés dans le modèle</bold> (et non la radiocommande). Ils peuvent être remis à 0 individuellement par la simple pression du bouton poussoir de sélection, et verrouillés ("OFF") si besoin.</text> <quote>Sur un modèle radiocommandé à propulsion électrique disposant de son propre algorithme de vol, il est souvent rare d'avoir besoin d'un trim sur le manche de gaz, ou même sur les autres axes de vol, d'ou cette possibilité de verrouillage d'un ou plusieurs trims avec la radiocommande que j'ai développé.</quote> <text>Le menu des paramètres et réglages en <bold>mode "ON AIR"</bold> (à l'antenne) est <bold>accessible en cliquant sur "SETTINGS"</bold> (paramètres) dans le menu principal, et dispose d'une section "EXIT" (sortie) et "UPDATE" (mettre à jour). Lorsque vous avez effectué vos réglages (trims, paramètres par défaut, paramètres personnalisés, etc...), <bold>vous devez mettre à jour la mémoire du modèle</bold> en cliquant sur "UPDATE" (mettre à jour) afin que le modèle enregistre tous les paramètres dans sa mémoire et mette à jour son algorithme de vol (si il en dispose, vous pouvez très bien piloter un bateau sans algorithme de contrôle de la navigation par exemple, mais disposant tout de même de réglages et de paramètres).</text> <quote>Si vous avez modifié des paramètres (trims, paramètres par défaut, paramètres personnalisés, etc...) et qu'une mise à jour du modèle est nécessaire, <bold>la section "UPDATE"</bold> (mettre à jour) <bold>se changera en "-UPDATE-"</bold> (-mettre à jour-), les tirets de part et d'autre du mot faisant office d'indication.</quote> <text>Si aucun modèle ne répond à la radiocommande lorsque vous souhaitez mettre à jour les paramètres dans celui-ci après avoir cliqué sur "UPDATE" (mettre à jour) dans le menu des paramètres, dans ce cas <bold>l'affichage indiquera "BINDING"</bold> (liaison), et vous aurez le choix d'attendre ou de quitter (en appuyant sur le bouton de sélection) <bold>sans mettre à jour les paramètres dans le modèle</bold>.</text> <text>Quitter la mise à jour n'aura pas le même effet que de sortir du menu avec "EXIT" (sortie), <bold>vos paramètres dernièrement modifiés le resteront tant que la radiocommande sera allumée</bold>, et vous devrez alors retourner ultérieurement dans le menu pour mettre à jour vos paramètres dans le modèle (si vous le souhaitez).</text> <caution>Si vous ne souhaitez pas enregistrer les paramètres dans le modèle <bold>ni conserver les dernières modifications effectuées</bold> dans le menu des paramètres ("SETTINGS"), <bold>vous pouvez sortir du menu en cliquant sur "EXIT"</bold> (sortie).</caution> <text>Les réglages des trims sont actifs en permanence, car ils sont <bold>mixés avec les manches directement dans la radiocommande</bold>, mais ils ne s'enregistrent pas dans celle-ci. Cette possibilité donne l'avantage bien entendu d'avoir des trims distincts par modèle, mais aussi de pouvoir trimer votre modèle sur le terrain sans avoir forcément envie de les enregistrer à l'extinction de la radiocommande comme c'est le cas avec les radiocommandes du commerce (si par exemple vous avez trimé votre modèle alors qu'il y avait du vent, ce qui fausse votre perception des bons réglages).</text> <quote>À noter que ce sont les interrupteurs de trims qui servent à régler les valeurs dans le menu des paramètres et réglages en mode "ON AIR" (à l'antenne), <bold>sauf lorsque la radiocommande est verrouillée</bold> (voir plus bas : "Le verrouillage de la radiocommande"), auquel cas les trims agissent toujours comme tel.</quote> <text>Il existe une méthode rapide pour régler des paramètres aux valeurs minimales et maximales trop larges (par exemple 0 à 3600 par pas de 1 comme c'est le cas pour le chronomètre intégré). Pour ce faire il suffit de <bold>rester appuyé sur un trim</bold> (ce qui fera défiler les valeurs plus rapidement).</text> <text>L'autre méthode de réglage rapide consiste à <bold>presser continuellement le bouton de sélection</bold>, ce qui vous permettra de régler la plupart des valeurs directement avec <bold>le bouton rotatif auxiliaire</bold> (pour la majorité des paramètres), ou en ce qui concerne le paramètre de déclenchement de la temporisation/chronomètre, ce sera <bold>le manche de gaz</bold> (si le potentiomètre de ce manche est calibré, voir ci-dessous : "Calibration des potentiomètres des manches").</text> <caution>Si vous décidez de régler la valeur de déclenchement de la temporisation/chronomètre à l'aide du manche de gaz, il convient que <bold>l'interrupteur de coupure moteur doit être actif</bold>, ou que que le modèle soit mis <bold>hors tension !</bold></caution> <text>À noter qu'il est tout à fait possible de régler les paramètres de votre modèle (sans parler des trims bien entendu) alors que celui-ci est <bold>en cours de pilotage</bold>, et que la radiocommande <bold>n'est pas verrouillée</bold> (voir plus bas : "Le verrouillage de la radiocommande").</text> <text>Bien évidement, même qu'il s'agisse d'une voiture, ou d'un bateau (ou de tout autre modèle ne pouvant se crasher quand il n'y a plus d'intervention du pilote), je ne peux que vous conseiller de <bold>régler votre modèle que lorsque il est à l'arrêt et en sécurité</bold> (et je ne ferais à ce propos pas de commentaires en ce qui concerne un modèle aérien !).</text> <title>Calibration des potentiomètres des manches :</title> <underline></underline> <text>De part la conception même des manches de la radiocommande, <bold>la plupart des potentiomètres de ceux-ci ne tournent pas mécaniquement sur leur plage de résistance complète minimale et maximale</bold>, ne produisant pas une plage de valeurs sur 10 bits (converties d'analogique à numérique) de 0 à 1023.</text> <quote>Cette contrainte technique conduit donc l'utilisateur de cette radiocommande à devoir calibrer les potentiomètres pour que cette dernière sache les <bold>plages de valeurs minimales et maximales des gaz, de l'axe de tangage, de roulis, et de lacet</bold>.</quote> <a href="photo/dsc07663.jpg"><img src="thumbnail/dsc07663.jpg"></img></a> <a href="photo/dsc07683.jpg"><img src="thumbnail/dsc07683.jpg"></img></a> <caution>Cette opération doit être effectuée <bold>à la première utilisation de la radiocommande</bold>, et lorsque que vous souhaitez <bold>remplacer les manches ou les potentiomètres</bold> de celle-ci.</caution> <text>Pour ce faire, vous devez démarrer la radiocommande en <bold>mode "OFF AIR"</bold> (hors antenne), puis vous rendre dans le menu des paramètres ("SETTINGS") dans lequel vous trouverez la calibration des potentiomètres des manches de la radiocommande.</text> <text>4 sections respectivement utiles pour calibrer le potentiomètre de <bold>gaz</bold> ("CLTH"), de <bold>tangage</bold> ("CLPI"), de <bold>roulis</bold> ("CLRO"), ou de <bold>lacet</bold> ("CLYA"), permettent de calibrer les potentiomètres concernés par ces axes.</text> <quote>Pour effectuer le calibrage, positionnez vous dans la section voulue (l'une des 4 mentionnées), puis <bold>pressez de façon continue le bouton de sélection</bold>, et <bold>pivotez le manche concerné aux positions minimales et maximales</bold>. La valeur par défaut de 0 <bold>augmentera alors jusqu'à atteindre un maximum</bold>, ce qui signifiera que le potentiomètre est calibré (c'est-à-dire que la radiocommande a trouvée les valeurs minimales et maximales de celui-ci).</quote> <text>Si par exemple le potentiomètre de tangage à une plage de résistance telle qu'il retourne en numérique une valeur pouvant varier de <bold>104</bold> à <bold>985</bold>, une fois correctement calibrée cela signifie que la valeur qui s'affichera à vous dans la section correspondante à cet axe sera de <bold>881</bold> (car 985 - 104 = 881).</text> <caution>La valeur de calibration qui s'affiche à vous est une <bold>soustraction entre la valeur maximale et la valeur minimale</bold> (convertie d'analogique à numérique sur 10 bits) que produit le potentiomètre.</caution> <text>Le menu dispose d'une section "EXIT" (sortie) et "SAVE" (enregistrer). Lorsque vous avez effectué vos réglages, <bold>vous devez les sauvegarder dans la radiocommande</bold> en cliquant sur "SAVE" (enregistrer) afin que celle-ci prenne en compte ces nouveaux réglages.</text> <quote>Si vous avez modifié des paramètres (calibration des potentiomètres des manches) et qu'un enregistrement dans la radiocommande est nécessaire, <bold>la section "SAVE"</bold> (enregistrer) <bold>se changera en "-SAVE-"</bold> (-enregistrer-), les tirets de part et d'autre du mot faisant office d'indication.</quote> <title>Le verrouillage de la radiocommande :</title> <underline></underline> <text>Il est possible avec cette radiocommande <bold>d'empêcher l'extinction de celle-ci via l'interrupteur d'alimentation on/off</bold>, et d'éviter de pouvoir modifier les paramètres dans les menus (sauf les trims qui doivent servir même lorsque la radiocommande est verrouillée). Ceci s'effectue en <bold>restant appuyé 1 seconde sur le bouton de sélection</bold> sur la section "LOCK" (verrouillage) dans le menu principal. Le mot "LOCK" (verrouillage) se change alors en "-LOCKED-" (-verrouillé-).</text> <caution>À noter que vous ne pouvez pas éteindre la radiocommande tout en vous trouvant dans la section "LOCK/-LOCKED-" du menu principal (c'est une sécurité supplémentaire).</caution> <text>Pour déverrouiller à nouveau la radiocommande, répétez l'opération (pression de 1 seconde sur le bouton de sélection dans cette partie du menu).</text> <quote>Ce sont les interrupteurs de trims qui servent à régler les valeurs dans le menu des paramètres et réglages en mode "ON AIR" (à l'antenne), <bold>sauf lorsque la radiocommande est verrouillée</bold>, auquel cas les trims agissent toujours comme tel.</quote> <text>Les trims <bold>ne peuvent pas êtres réinitialisés</bold> à leur valeur par défaut ("OFF") en pressant le bouton de sélection dans le menu principal dans la section concernée lorsque la radiocommande est verrouillée.</text> <text>Lorsque la radiocommande est verrouillée, vous pouvez visualiser et modifier les réglages dans le menu des paramètres, mais vous ne pouvez pas les mettre à jour dans le modèle (en mode "ON AIR") ou les enregistrer dans la radiocommande (en mode "OFF AIR"), car respectivement <bold>les sections "UPDATE" (mettre à jour) et "SAVE" (enregistrer) sont absents du menu</bold>.</text> <title>La copie des paramètres d'un modèle :</title> <underline></underline> <text>Avec ma radiocommande il est très simple de copier les paramètres (trims, paramètres par défaut, paramètres personnalisés) d'un modèle vers un autre <bold>sans jamais pouvoir se tromper</bold>, voici la procédure :</text> <quote><bold>1</bold> - Allumez la radiocommande et le modèle à copier. <br/><bold>2</bold> - Activez la transmission radio dans le menu qui vous est proposé au démarrage de la radiocommande ("ON AIR"). <br/><bold>3</bold> - Au signal sonore, les paramètres du modèle viennent d'être copiés dans la radiocommande, vous pouvez éteindre le modèle à copier, et allumer l'autre modèle dans lesquels vous souhaitez écraser les paramètres. <br/><bold>4</bold> - Rendez-vous dans le menu des paramètres en cliquant sur la section "SETTINGS" (paramètres), puis cliquez sur "UPDATE" (mettre à jour). Vous entendez alors les signaux sonores de la radiocommande et du modèle vous indiquant que les paramètres ont bien été copiés dans ce dernier.</quote> <text>Si vous avez plusieurs modèles devant recevoir les mêmes paramètres, répétez la procédure de l'opération <bold>3</bold> à <bold>4</bold>.</text> <caution>Il est très important de comprendre que cette opération de copie n'a de sens que si les paramètres du modèle à copier vers ceux du modèle à écraser sont <bold>identiques</bold> non pas en terme de valeurs, mais bien <bold>en terme de nature et de caractéristiques</bold> (valeurs minimales et maximales, emplacements dans le menu des paramètres, etc...), et que les modèles à copier se situent tous dans la même logique (axes de manœuvrabilité, types de pilotage, etc...).</caution> <text>Dans le cas contraire, cela peut être un choix délibéré de votre part de copier les paramètres vers un système complètement différent du modèle à copier, je pense par exemple à la copie vers un automate programmable nu afin de <bold>sauvegarder vos paramètres préférés</bold> (sans qu'il soit question de modèle à proprement parlé).</text> <title>La sécurité de la communication :</title> <underline></underline> <text>La communication s'effectue de manière encodée avec une <bold>clé 32 bits unique</bold> paramétrable dans le programme de la radiocommande et des modèles (voir dans la section "Exemples simples à l'aide de MODULE" en page d'accueil mon exemple avec ma classe Nrf24l01p.h), ce qui permet de rendre ce système de communication radio très fiable et sécurisé.</text> <text>Lors d'une communication, un <bold>accusé de réception</bold> valide est demandé, et un <bold>code de correction d'erreurs</bold> (sur 16 bits) très performant permet de contrôler la validité des informations reçues.</text> <quote>Le modèle dispose également d'un <bold>système à tolérance de pannes</bold> (fail-safe) qui permet d'effectuer certaines opérations spécifiques <bold>lorsque la radiocommande ne répond plus</bold> (mise au neutre des servo-moteurs, coupure de la motorisation, etc...). Tout ceci est à définir à la conception du programme de vol à bord du modèle (libre à chacun de créer une logique en rapport avec le type de modèle piloté).</quote> <title>La vitesse de communication :</title> <underline></underline> <text>La communication s'effectue sur 32 bits (sans compter la clé unique, ainsi que les vérifications d'usage) et demande un accusé de réception à chaque fois. Néanmoins cette communication <bold>ne peut pas prendre un temps supérieur à 500 microsecondes</bold> parce que c'est ce que j'ai configuré au niveau des registres du composant nRF24L01+ avec la classe Nrf24l01p.h que j'ai conçu.</text> <a href="photo/dsc07869.jpg"><img src="thumbnail/dsc07869.jpg"></img></a> <a href="photo/dsc07870.jpg"><img src="thumbnail/dsc07870.jpg"></img></a> <text>C'est donc le temps au bout duquel le composant nRF24L01+ décide que la communication a échouée si aucune réponse n'est reçue. Dans la plupart des cas cette communication <bold>ne dure que 250 microsecondes maximum par trames de 32 bits</bold> (32 bits du point de vue abstrait des variables envoyées via l'utilisation de ma classe Nrf24l01p.h).</text> <text>Toutes les valeurs de l'interface électromécanique entre l'homme et la machine de ma radiocommande sont envoyées sur <bold>2 x 32 bits</bold>, ce qui comprends :</text> <quote>- Gaz sur 10 bits (0 à 1023). <br/>- Axe de roulis sur 10 bits (0 à 1023). <br/>- Axe de tangage sur 10 bits (0 à 1023). <br/>- Axe de lacet sur 10 bits (0 à 1023). <br/>- Interrupteur de coupure moteur/autre sur 1 bit (0 à 1). <br/>- Interrupteur auxiliaire A sur 2 bits (0 à 2). <br/>- Interrupteur auxiliaire B sur 2 bits (0 à 2). <br/>- Interrupteur auxiliaire C sur 2 bits (0 à 2). <br/>- Bouton rotatif auxiliaire D sur 10 bits (0 à 1023). <br/>- Système à tolérance de pannes (fail-safe) sur 6 bits (0 à 63). <br/>- Ordre de mise à jour sur 1 bit (0 à 1).</quote> <text>Ce qui donne un <bold>total de 64 bits</bold> soit 2 trames de communication. On peut donc estimer la latence très faible de ce principe. En effet, j'encode les données en binaire toutes ensembles sur 2 x 32 bits à l'émission et je les décode à la réception, ce qui prend le minimum de place possible (évite de perdre des bits dans des variables aux tailles fixes de 8, 16, ou 32 bits).</text> <title>Responsabilité :</title> <underline></underline> <text>Vous pouvez utiliser la partie matérielle et logicielle que je propose, mais en matière de communication sans fil 2.4GHz et d'aéromodélisme, des précautions doivent être prises.</text> <caution>Je ne pourrais être tenu pour responsable si vous faites une mauvaise utilisation de mes systèmes !</caution> <text>Ce qui signifie que vous utilisez ma programmation en toute connaissance de cause et en règle avec la loi en vigueur dans votre pays (notamment en ce qui concerne les lieux de vols autorisés, les fréquences et puissances d'émissions des radio-émetteurs, etc...).</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier projectUselessMachine.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#projectUselessMachine"><back>Retour</back></a> <a href="projectSite.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Les machines inutiles</title> <underline></underline> <text>Les machines <bold>inutiles</bold> sont les créations personnelles d'un inventeur raté (moi), mais elles ont tout de même un intérêt pédagogique certain !</text> <text><bold>La roue perpétuellement inutile :</bold> <br/>Cette roue est l'incarnation de la déchéance ultime en matière de physique et notamment de thermodynamique, généralement laissée au stade d'idée dans des boites crâniennes aux cerveaux ravagés (et encore il faut chercher tellement c'est vide la dedans), j'ai pour ma part souhaité en réaliser une pour en avoir le cœur net !</text> <a href="photo/dsc06361.jpg"><img src="thumbnail/dsc06361.jpg"></img></a> <a href="photo/dsc06357.jpg"><img src="thumbnail/dsc06357.jpg"></img></a> <text>Le principe est simple : <bold>PAS DE PRINCIPE !</bold> Bien entendu cette roue reste statique, comme les molécules à 0 degrés Kelvin (ou Kevin ?) qui composent les ramifications nerveuses de son créateur...</text> <a href="photo/dsc06359.jpg"><img src="thumbnail/dsc06359.jpg"></img></a> <a href="photo/dsc06358.jpg"><img src="thumbnail/dsc06358.jpg"></img></a> <text>Les masselottes (sur le cercle extérieur) circulants à droite de la roue sont plus excentrées (plus loin de l'axe de rotation) que les masselottes circulants à gauche, de sorte qu'un déséquilibre est créé. Mais les masses permettant cet excentrique (dissymétrie) abaissent le centre de gravité du système dans son ensemble, ce qui a pour conséquence de ramener <bold>la somme des moments</bold> (forces) à <bold>0</bold>.</text> <text>Au mieux cela peut servir de tourniquet ou de moulin à prière... dam oui !</text> <title>L'additionneuse de poche 8 bits :</title> <underline></underline> <text>La machine à calculer 8 bits est comme son nom ne l'indique pas, <bold>compacte et légère</bold>, vous pouvez l'emmener partout dès que vous avez un problème pour additionner des nombres de <bold>0</bold> à <bold>255</bold> dont la somme (résultat) ne dépasse pas 255 !</text> <a href="photo/dsc01493.jpg"><img src="thumbnail/dsc01493.jpg"></img></a> <a href="photo/dsc01556.jpg"><img src="thumbnail/dsc01556.jpg"></img></a> <text>Pour s'en servir, rien de plus simple, il suffit de savoir jouer aux billes ! Et cela dit en passant de comprendre et lire le <bold>binaire</bold>, donc la logique combinatoire un petit peu...</text> <text>Cette machine dispose de 8 bascules (registre), qui représentent à l'état repos 8 zéros, c'est-à-dire <bold>1 octet</bold> de poids faible (00000000). Quand vous souhaitez additionner 2 nombres, il vous faut insérer les <bold>bits</bold> (ou billes) par le dessus, de droite à gauche (logique de la programmation). Les bascules selon leurs états (0 ou 1) changent d'état quand un bit est inséré dans le mécanisme. Ceci est le premier nombre à additionner avec un second.</text> <text>Le second nombre s'insère dans la machine de la même manière. Le résultat du calcul étant la position finale des bascules.</text> <a href="photo/dsc01508.jpg"><img src="thumbnail/dsc01508.jpg"></img></a> <a href="photo/dsc01541.jpg"><img src="thumbnail/dsc01541.jpg"></img></a> <text><bold>Exemple :</bold> <br/>- J'insère l'octect 00001010 dans la machine (10 en décimal). <br/>- J'insère un nouvel octet 00000111 dans la machine (7 en décimal). <br/>- Le registre indique en binaire 00010001, soit 17 en décimal, c'est le résultat du calcul.</text> <quote>Quand le résultat du calcul est supérieur à 255, la machine se trouve dans une situation de dépassement de la taille du registre (overflow). Un bit (une bille) est alors éjecté à gauche dans la 9ème case disponible, si il existait plusieurs machines en cascade, ce bit viendrait alors changer l'état d'un 9ème transistor (bascule) d'un second registre de 8 bits.</quote> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier toolBmpToMod.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#toolBmpToMod"><back>Retour</back></a> <a href="download.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Conversion d'images .bmp vers .mod</title> <underline></underline> <text>Avec cette routine de conversion d'images (pour le système d'exploitation Linux Ubuntu que j'utilise), vous allez pouvoir <bold>importer des logos</bold> (et autres graphismes) dans vos dessins KiCad en vue PCB <bold>sur le calque de sérigraphie</bold> de la face avant (F.SilkS).</text> <quote>Il existe un outil par défaut dans cette suite KiCad nommé <bold>Bitmap2Component</bold> qui est censé remplir cette fonction, mais notamment dépendant de la résolution (hauteur/largeur) de l'image d'origine, il ne permet pas le redimensionnement, est basé sur un principe de conversion vectorielle qui détruit l'information, et au final fait apparaître pour certains dessins de petites tailles des lignes courbes là où il y a des droites parfaites, et plus une bouillie de pixels qu'une sérigraphie de qualité...</quote> <text>Ainsi cet outil proposé par défaut est pour moi inutilisable lorsque l'on souhaite un rendu exact par rapport à notre image noir et blanc initiale.</text> <text>À l'instar de Bitmap2Component, ma routine d'automatisation prend en entrée une image qui doit être initialement en noir et blanc (monochrome) afin que les pixels blancs soient utilisés dans le traitement :</text> <caution>Ce que je vous propose ici permettra <bold>qu'un pixel blanc dans votre image d'origine sera très exactement un carré de sérigraphie</bold> (de la taille souhaitée) dans votre dessin en vue PCB.</caution> <text>Cette routine (.sh) contient le programme suivant :</text> <code>#!/bin/bash mkdir tmp for file in *.bmp do echo $file echo -e "\nPixel size ?" read sizeRaw size=$(echo $sizeRaw*"10" | bc) convert $file tmp/tmp.txt grep "white" tmp/tmp.txt > tmp/tmp grep -o ".*:" tmp/tmp > tmp/tmpxy grep -o ".*," tmp/tmpxy > tmp/x sed -i tmp/x -e "s/,//" grep -o ",.*:" tmp/tmpxy > tmp/y sed -i tmp/y -e "s/,//" -e "s/://" nCount=0 while read x do xList[nCount]=$(echo $x*$size | bc) ((nCount++)) done < tmp/x nCount=0 while read y do yList[nCount]=$(echo $y*$size | bc) ((nCount++)) done < tmp/y echo "PCBNEW-LibModule-V1" > ${file%%.*}.mod echo "\$INDEX" >> ${file%%.*}.mod echo ${file%%.*} >> ${file%%.*}.mod echo "\$EndINDEX" >> ${file%%.*}.mod echo "\$MODULE "${file%%.*} >> ${file%%.*}.mod echo "Li "${file%%.*} >> ${file%%.*}.mod for ((n=0; n<nCount; n++)) do echo "DP 0 0 0 0 4 0 200" >> ${file%%.*}.mod echo "Dl "${xList[n]}" "${yList[n]} >> ${file%%.*}.mod echo "Dl "$(echo ${xList[n]}+$size | bc)" "${yList[n]} >> ${file%%.*}.mod echo "Dl "$(echo ${xList[n]}+$size | bc)" "$(echo ${yList[n]}+$size | bc) >> ${file%%.*}.mod echo "Dl "${xList[n]}" "$(echo ${yList[n]}+$size | bc) >> ${file%%.*}.mod done echo "\$EndMODULE "${file%%.*} >> ${file%%.*}.mod echo "\$EndLIBRARY" >> ${file%%.*}.mod clear done rm tmp -r exit 0</code> <caution>La routine présentée ci-dessus utilise le programme <bold>ImageMagick</bold> pour extraire les valeurs matricielles des images traitées.</caution> <text>Il vous faut donc l'installer à l'aide de la ligne de commande suivante (à écrire dans le terminal de Linux Ubuntu) :</text> <code>sudo apt-get install imagemagick</code> <text>Une fois cette installation effectuée, lorsque vous exécutez la routine (.sh) toutes les images ayant l'extension <bold>.bmp</bold> sont converties successivement en fichiers <bold>.mod</bold> (footprint) que vous pouvez ajouter à vos projets KiCad par l'intermédiaire du menu d'ajout de bibliothèques (Preferences > Library) en vue PCB.</text> <text>Pour chaque image à convertir se propose à vous une question "Pixel size ?", il vous faut alors renseigner la taille souhaitée que fera un pixel dans votre dessin KiCad (cohérent lorsque les unités de mesures sont indiquées en pouces et non pas en millimètres) :</text> <quote>Par exemple si vous indiquez en taille de pixel le nombre <bold>25</bold>, avec une grille dans votre dessin KiCad réglée sur <bold>25</bold> (et des unités de mesures en pouces) vous verrez que <bold>le pas des pixels de votre graphisme en vue PCB fera très exactement le même pas que la grille</bold>.</quote> <text>À noter que vous pouvez indiquer une taille de pixel en <bold>nombre entier ou décimal</bold> indifféremment, les valeurs seront traitées correctement lors des calculs de conversion.</text> <caution>Si vous apercevez le crénelage des pixels de votre graphisme sérigraphié une fois votre circuit réalisé, je vous conseille d'utiliser une image bitmap (.bmp) initiale de <bold>plus grande résolution</bold>, et d'indiquer une taille de pixel (lors de la conversion avec la routine) d'autant <bold>plus faible</bold>, par exemple <bold>2.5</bold> (attention cependant, les temps de traitements peuvent s'avérer assez longs avec des résolutions d'images trop grandes).</caution> <text>Libre à vous de faire une utilisation de ce petit programme de conversion d'image, qui vous permettra aisément d'apposer vos logos et divers graphismes sur vos circuits imprimés avec une <bold>parfaite exactitude de conversion</bold> (1 pixel bitmap vers 1 pixel sérigraphié).</text> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html> Fichier understandWhatIsModule.html : <html> <head> <title>sylvainmahe.site</title> <link rel="stylesheet" type="text/css" href="style.css"> <link rel="icon" type="image/png" href="image/icon.png"> </head> <body> <a href="index.html#understandWhatIsModule"><back>Retour</back></a> <a href="howToInstallModule.html"><next>Suite</next></a> <header> <a href="index.html"><logo><img src="image/logo.png"></img></logo></a> <title>sylvainmahe.site</title> <dualine></dualine> <subtitle>LE SITE</subtitle> <text>de Sylvain Mahé</text> <contact>contact@sylvainmahe.site</contact> <sublogo><img src="image/sublogo.png"></img></sublogo> </header> <page> <author>Article : Sylvain Mahé</author> <contact>contact@sylvainmahe.site</contact> <title>Comprendre ce qu'est MODULE</title> <underline></underline> <text>MODULE est un système embarqué d'automates programmables, c'est-à-dire une partie logicielle (programmation) et une partie matérielle (électronique) permettant de réaliser des tâches d'automatisation.</text> <text>Partie logicielle, MODULE est une suite de classes écrites en <bold>C++</bold> pur (sans bibliothèque additionnelle) dédiées à la programmation des microcontrôleurs <bold>ATmega48P</bold>, <bold>ATmega88P</bold>, <bold>ATmega168P</bold>, <bold>ATmega328P</bold>, <bold>ATmega164P</bold>, <bold>ATmega324P</bold>, <bold>ATmega644P</bold> et <bold>ATmega1284P</bold> qui équipent mes automates programmables.</text> <text>Partie matérielle, je vous propose les plans de mise en production (par vos soins ou par une usine de fabrication) de quelques cartes électroniques partie commande avec microcontrôleurs (ce sont les automates programmables associés à la bibliothèque MODULE), mais également de l'électronique de puissance.</text> <text>Photo de gauche, l'automate programmable <bold>MODULABLE M20</bold> accompagné des afficheurs à digits et matrice, photo de droite, l'automate programmable <bold>MODULABLE M32</bold> avec à ses cotés également diverses cartes, toutes sont proposées en téléchargement :</text> <a href="photo/dsc02499.jpg"><img src="thumbnail/dsc02499.jpg"></img></a> <a href="photo/dsc07357.jpg"><img src="thumbnail/dsc07357.jpg"></img></a> <quote>Les plans de fabrication de mes cartes électroniques sont disponibles dans les sections "Téléchargements" et "Fabrications et diverses réalisations" en page d'accueil.</quote> <text><bold>Historique du projet MODULE :</bold> <br/>Le projet MODULE et les circuits électroniques qui y sont associés a débuté en Août 2014 et aura demandé plus de 3 années pour aboutir au produit actuel.</text> <text>Depuis longtemps je me suis intéressé à l'électricité, mais l'électronique (embarquée) avant ce projet m'est toujours apparue comme obscure et difficile à appréhender. En Août 2014, j'ai donc décidé d'apprendre avec la meilleure volonté l'électronique, parce que c'était un domaine que je ne connaissais (sans même encore parler de maîtriser ou de pratiquer) absolument pas.</text> <text>Sans formation dans le domaine, il aura fallut acharnement pour ainsi progresser en lisant pendant des mois les documentations techniques des composants, des articles sur internet (dans lesquels il convient souvent de trier et de recouper l'information), mais aussi et surtout à force de pratique et d'expériences personnelles.</text> <a href="photo/dsc02345.jpg"><img src="thumbnail/dsc02345.jpg"></img></a> <a href="photo/dsc02821.jpg"><img src="thumbnail/dsc02821.jpg"></img></a> <text><bold>La philosophie de MODULE :</bold> <br/>MODULE n'est pas programmé en surcouche d'une autre bibliothèque comme l'est la plupart des bibliothèques dont fait partie Arduino™, de fait le code source C++ est dédié et optimisé pour le microcontrôleur ATmega48P, ATmega88P, ATmega168P, ATmega328P, ATmega164P, ATmega324P, ATmega644P ou ATmega1284P afin d'obtenir le meilleur compromis en C++ en terme de rapidité et d'espace mémoire.</text> <quote>MODULE est une bonne alternative à Arduino™ pour programmer plus efficacement l'ATmega48P, l'ATmega88P, l'ATmega168P, l'ATmega328P, l'ATmega164P, l'ATmega324P, l'ATmega644P ou l'ATmega1284P.</quote> <text>L'idée de MODULE veut qu'aucun code C++ n'ait été recopié d'un livre ou d'internet, tout est une création personnelle unique, ceci dans le seul but de comprendre le fonctionnement des choses, d'optimiser, et de partager une création personnelle tout simplement.</text> <text>Aucune bibliothèque même couramment admise (par la communauté des programmeurs) comme faisant partie du standard du langage C++ n'a été utilisée pour programmer MODULE, comme par exemple stdlib.h, stdio.h, ou encore math.h, toujours dans un soucis de compréhension du fonctionnement. Cela m'a permis par exemple de faire un peu de mathématiques (sans math.h) et de comprendre comment construire des fonctions comme sinus, cosinus, ou encore arc tangente que l'on retrouve souvent dans les calculatrices modernes sans en connaître et en imaginer réellement le fonctionnement interne.</text> <caution>Ne pas être lié à d'autres programmes permet à MODULE d'être indépendant, et en outre de ne pas subir les aléas, évolutions, bogues, ou encore obsolescences de fichiers concurrents.</caution> <text>MODULE qui a débuté avec l'ATmega328P (ce fut le point de départ), c'est aussi redonner tout l'intérêt pour ce petit microcontrôleur 8 bits de plus en plus délaissé au profit de microcontrôleurs 32 bits aux fréquences de fonctionnement plus élevées du fait que les bibliothèques concurrentes demandent plus de cycles pour faire les mêmes opérations que MODULE.</text> <text><bold>La normalisation de la structure interne et syntaxique de MODULE :</bold> <br/>MODULE a été programmé avec rigueur et normalisation du code source (comme tous les programmes que je vous propose en téléchargement ou en exemple).</text> <text>Une ligne de conduite concernant la logique, la structure, la syntaxe, le nommage des variables, des fonctions et des classes, ou même simplement l'aspect visuel (indentation, espaces, etc...), a été respectée afin d'obtenir le code source le plus lisible, fonctionnel et propre possible.</text> <quote>Ceci n'est pas plus une réponse à tout ce que je peux constater dans la communauté des programmeurs actuellement, mais plus une volonté personnelle de bonnes pratiques en terme d'écriture des programmes.</quote> <text><bold>Simplicité de programmation avec MODULE :</bold> <br/>En interne, MODULE s'occupe de réaliser les taches les plus laborieuses, ardues et complexes que requiert la programmation brute d'un microcontrôleur. Ceci permet au développeur de réaliser des projets élaborés en un minimum de lignes de programmation, sans pour autant pâtir sur les performances ou brider le nombre de possibilités.</text> <text>MODULE se veut accessible au débutants, tout en permettant la réalisation d'applications professionnelles.</text> <text><bold>Que peut-on faire avec MODULE ?</bold> <br/>MODULE est comme son nom l'indique modulaire, il n'a en soit pas de limite, la seule est notre imagination. Sachez qu'à l'époque de la conquête spatiale, des ingénieurs et techniciens ont envoyés des fusées dans l'espace avec bien moins comme calculateur qu'un ATmega328P !</text> <text>Avec MODULE vous pouvez faire fonctionner des gyroscopes, magnétomètres, baromètres, émetteurs/récepteurs 2.4GHz, générer du PWM et donc entre autre faire fonctionner des servos-moteurs et des ESC, lire des PWM, créer une interface entre l'utilisateur et l'automate programmable via des boutons, des potentiomètres, des afficheurs, et des buzzers. Il est possible de temporiser les actions et les événements à effectuer, de réaliser des calculs et diverses courbes et fonctions mathématiques, de générer de l'aléatoire à partir de bruit analogique, de filtrer des valeurs en temps réel, de créer des états multiples avec hystérésis, de gérer la veille du microcontrôleur, d'effectuer des communications entre plusieurs automates programmables, de sauvegarder des données dans sa mémoire EEPROM interne une fois celui-ci coupé de son alimentation électrique, et bien d'autres choses encore...</text> <quote>Libre à vous de programmer d'autres fonctions dans MODULE si vous le souhaitez !</quote> <text>Photo ci-dessous, un exemple de projet réalisé avec MODULE et l'automate programmable MODULABLE M20 équipé de l'ATmega328P :</text> <a href="photo/dsc01905.jpg"><img src="thumbnail/dsc01905.jpg"></img></a> <text><bold>L'électronique associé à MODULE :</bold> <br/>Toute l'électronique que je vous propose en téléchargement (dans les sections "Téléchargements" et "Fabrications et diverses réalisations" en page d'accueil) est réalisée avec les mêmes contraintes et critères de normalisation que la programmation, c'est-à-dire avec la plus grande rigueur et dans le soucis de prise en compte de ce qui pourrait être considéré comme des détails.</text> <text>Je réalise les plans de mes circuits imprimés à l'aide du <bold>logiciel KiCad</bold> avec le système d'exploitation Linux Ubuntu, les fichiers originaux de mes projets KiCad ne sont pas disponibles en téléchargement (disponibles cependant sur demande), mais sachez que mes dessins sont réalisés à l'aide de <bold>ma propre bibliothèque de composants en vue schématique et PCB</bold>, bibliothèque construite de façon normée à partir des documentations techniques officielles des composants et également de mon expérience personnelle concernant leurs implantations (ergonomie de positionnement et de brasure, etc...).</text> <text>Le reste de la conception n'est pas laissée au hasard (diamètres des perçages pour le passage des broches des composants, calculs des dimensions des pistes en fonction du courant, prise en compte des parasites, plans de masse, distances entre les composants, distances au bord des PCB, normalisation de la sérigraphie et du nommage, épaisseur des lettres, des tracés, positions et orientations des mots, etc...).</text> <a href="photo/dsc07352.jpg"><img src="thumbnail/dsc07352.jpg"></img></a> <a href="photo/dsc07209.jpg"><img src="thumbnail/dsc07209.jpg"></img></a> <text>Les plans de fabrication de mes circuits imprimés sont tous disponibles au <bold>format de fichier Gerber</bold>, car c'est un fichier normalisé utilisé par toute l'industrie de l'électronique pour la transmission de plans de production entre les différentes manufactures.</text> <quote>Le format de fichier Gerber est le standard directement pris en charge par toutes les usines de fabrication.</quote> <line></line> <footer>Programmation et graphismes du site : Sylvain Mahé</footer> </page> </body> </html>