<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
		<id>http://wikigeii.iut-troyes.univ-reims.fr//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cleusb</id>
		<title>troyesGEII - Contributions de l’utilisateur [fr]</title>
		<link rel="self" type="application/atom+xml" href="http://wikigeii.iut-troyes.univ-reims.fr//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cleusb"/>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Sp%C3%A9cial:Contributions/Cleusb"/>
		<updated>2026-05-04T20:58:24Z</updated>
		<subtitle>Contributions de l’utilisateur</subtitle>
		<generator>MediaWiki 1.30.1</generator>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7877</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7877"/>
				<updated>2016-04-23T16:36:44Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception de la deuxième carte}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (vias plus espacés), et d'inclure un anneau pour fixer un porte clé. Nous avons également modifié le composant du connecteur USB afin d'ajouter une surface métallique au dos du connecteur pour souder une plaque de clinquant.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB3-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB. Ce boitier a été réalisé par impression 3D.&amp;lt;br/&amp;gt;&lt;br /&gt;
Voici les dimensions des deux éléments du boitier ainsi qu'un aperçu du résultat :&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB-boitier.jpg|vignette|center|upright=1.5|Boitier imprimés]] ||[[Image:Clé_USB_HARENDARZ.jpg|vignette|center|upright=1.5|3&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; clé et boitier]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clés (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7876</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7876"/>
				<updated>2016-04-23T16:35:08Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception de la deuxième carte}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (vias plus espacés), et d'inclure un anneau pour fixer un porte clé. Nous avons également modifié le composant du connecteur USB afin d'ajouter une surface métallique au dos du connecteur pour souder une plaque de clinquant.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB3-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB. Ce boitier a été réalisé par impression 3D.&amp;lt;br/&amp;gt;&lt;br /&gt;
Voici les dimensions des deux éléments du boitier ainsi qu'un aperçu du résultat :&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB-boitier.jpg|vignette|center|upright=1.5|Boitier imprimés]] ||[[Image:Clé_USB_HARENDARZ.jpg|vignette|center|upright=1.5|3&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; clé et boitier]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clés (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7875</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7875"/>
				<updated>2016-04-23T16:34:38Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception de la troisième carte}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (vias plus espacés), et d'inclure un anneau pour fixer un porte clé. Nous avons également modifié le composant du connecteur USB afin d'ajouter une surface métallique au dos du connecteur pour souder une plaque de clinquant.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB3-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB. Ce boitier a été réalisé par impression 3D.&amp;lt;br/&amp;gt;&lt;br /&gt;
Voici les dimensions des deux éléments du boitier ainsi qu'un aperçu du résultat :&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB-boitier.jpg|vignette|center|upright=1.5|Boitier imprimés]] ||[[Image:Clé_USB_HARENDARZ.jpg|vignette|center|upright=1.5|3&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; clé et boitier]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clés (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3-photo.jpg&amp;diff=7874</id>
		<title>Fichier:USB3-photo.jpg</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3-photo.jpg&amp;diff=7874"/>
				<updated>2016-04-23T16:33:50Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7873</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7873"/>
				<updated>2016-04-23T16:31:24Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception d'un boitier pour la clé}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (vias plus espacés), et d'inclure un anneau pour fixer un porte clé. Nous avons également modifié le composant du connecteur USB afin d'ajouter une surface métallique au dos du connecteur pour souder une plaque de clinquant.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB. Ce boitier a été réalisé par impression 3D.&amp;lt;br/&amp;gt;&lt;br /&gt;
Voici les dimensions des deux éléments du boitier ainsi qu'un aperçu du résultat :&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB-boitier.jpg|vignette|center|upright=1.5|Boitier imprimés]] ||[[Image:Clé_USB_HARENDARZ.jpg|vignette|center|upright=1.5|3&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; clé et boitier]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clés (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7872</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7872"/>
				<updated>2016-04-23T16:29:13Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Correction}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (vias plus espacés), et d'inclure un anneau pour fixer un porte clé. Nous avons également modifié le composant du connecteur USB afin d'ajouter une surface métallique au dos du connecteur pour souder une plaque de clinquant.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB. Ce boitier a été réalisé par impression 3D.&amp;lt;br/&amp;gt;&lt;br /&gt;
Voici les dimensions des deux éléments du boitier ainsi qu'un aperçu du résultat :&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB-boitier.jpg|vignette|center|upright=1.5|Boitier imprimés]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clés (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7871</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7871"/>
				<updated>2016-04-23T16:28:15Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception d'un boitier pour la clé}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (vias plus espacés), et d'inclure un anneau pour fixer un porte clé. Nous avons également modifié le composant du connecteur USB afin d'ajouter une surface métallique au dos du connecteur pour souder une plaque de clinquant.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB. Ce boitier a été réalisé par impression 3D.&amp;lt;br/&amp;gt;&lt;br /&gt;
Voici les dimensions des deux éléments du boitier ainsi qu'un aperçu du résultat :&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB-boitier.jpg|vignette|center|upright=1.5|Boitier imprimés]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB-boitier.jpg&amp;diff=7870</id>
		<title>Fichier:USB-boitier.jpg</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB-boitier.jpg&amp;diff=7870"/>
				<updated>2016-04-23T16:25:42Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7869</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7869"/>
				<updated>2016-04-23T16:20:46Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Troisième clé USB}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (vias plus espacés), et d'inclure un anneau pour fixer un porte clé. Nous avons également modifié le composant du connecteur USB afin d'ajouter une surface métallique au dos du connecteur pour souder une plaque de clinquant.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7868</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7868"/>
				<updated>2016-04-23T16:17:01Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception de la deuxième carte}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté des morceaux de clinquant sur les connecteurs USB affin de corriger une erreur de dimensionnement de celle-ci et d'augmenter l'épaisseur du connecteur. En effet, le PCB est trop fin donc dans certain ports USB trop larges, il n'y a pas de contact entre les connecteur mâle et femelle.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7867</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7867"/>
				<updated>2016-04-23T16:08:36Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Interface graphique}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]||&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7866</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7866"/>
				<updated>2016-04-23T15:54:34Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Interface graphique}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
[[Image:GUI-etape1.png|vignette|left|upright=1.5|1&amp;lt;sup&amp;gt;ère&amp;lt;/sup&amp;gt; étape: choix de l'identifiant à modifier]]&lt;br /&gt;
[[Image:GUI-etape2.png|vignette|left|upright=1.5|2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; étape: modification du mot de passe et de l'identifiant]]&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7865</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7865"/>
				<updated>2016-04-23T09:53:44Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Deuxième clé USB}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous avons également réalisé une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprime donc le connecteur utilisé dans la précédente clé. Le connecteur ISP est également supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour certaines résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:USB2-photo.jpg|vignette|upright=3|left|Schéma]]&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Gestion de mot de passe}}=&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Protocole de communication}}==&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Fonctionnement du microcontrôleur}}==&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensibles lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Interface graphique}}==&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlP5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
[[Image:GUI-etape1.png|vignette]]&lt;br /&gt;
[[Image:GUI-etape2.png|vignette]]&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mots de passes&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décalage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de la sélection d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //après 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //après 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:GUI-etape2.png&amp;diff=7864</id>
		<title>Fichier:GUI-etape2.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:GUI-etape2.png&amp;diff=7864"/>
				<updated>2016-04-23T09:50:34Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:GUI-etape1.png&amp;diff=7863</id>
		<title>Fichier:GUI-etape1.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:GUI-etape1.png&amp;diff=7863"/>
				<updated>2016-04-23T09:48:54Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB2-photo.jpg&amp;diff=7862</id>
		<title>Fichier:USB2-photo.jpg</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB2-photo.jpg&amp;diff=7862"/>
				<updated>2016-04-23T09:37:44Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7861</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7861"/>
				<updated>2016-04-23T09:33:23Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Réglage du volume}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de Remote_ au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7860</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7860"/>
				<updated>2016-04-23T09:28:48Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Bootloader}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous avons installé un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation ZIF et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé le boitier d'adaptation à notre disposition, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous avons donc créé une nouvelle carte d'adaptation sur laquelle souder le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7859</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7859"/>
				<updated>2016-04-23T09:23:55Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Conception de la première clé}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dans cette première version, nous avons conservé par sécurité un connecteur ISP pour la programmation, mais l'objectif est de se passer de l'ISP et de programmer la carte par USB.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7858</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7858"/>
				<updated>2016-04-23T09:20:30Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Conception de la première clé}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous avons ajouté 4 boutons et 4 LEDs sur le port D maintenant inutilisé.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7857</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7857"/>
				<updated>2016-04-23T09:17:53Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Conception de la première clé}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7856</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7856"/>
				<updated>2016-04-23T09:12:12Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser, dans un premier temps, une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra également permettre stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
USB1-photo.jpg&lt;br /&gt;
[[Image:Schéma USB1-photo.jpg|vignette|left|upright=1.5]]&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB1-photo.jpg&amp;diff=7855</id>
		<title>Fichier:USB1-photo.jpg</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB1-photo.jpg&amp;diff=7855"/>
				<updated>2016-04-23T09:10:57Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7854</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7854"/>
				<updated>2016-04-23T09:04:08Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir stocker et saisir des mots de passes. Pour cela nous avons réalisé successivement plusieurs clés, la première servant uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Etant donné que nous devons utiliser le port USB comme liaison série et comme clavier virtuel, nous avons basé notre projet sur un microcontrôleur ATMEGA32U4 car les deux fonction sont intégrées dans celui-ci. Nous avons donc repris le schéma de l'ARDUINO LEONARDO qui utilise un ATMEGA32U4, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation externe et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des signaux et des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7812</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7812"/>
				<updated>2016-03-28T13:35:22Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici les fichiers utiles pour la réalisation des clé (typons, routage, programmes):&lt;br /&gt;
*[[Media:Fichiers_utiles.zip]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Fichiers_utiles.zip&amp;diff=7811</id>
		<title>Fichier:Fichiers utiles.zip</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Fichiers_utiles.zip&amp;diff=7811"/>
				<updated>2016-03-28T13:31:20Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7810</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7810"/>
				<updated>2016-03-28T13:18:43Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Vert|Fonctionnement du microcontrôleur}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible lors de la première utilisation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7809</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7809"/>
				<updated>2016-03-28T13:15:45Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Gestion de mot de passe}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 16 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction initialisation() est appelée dans le setup() la première fois que le programme est utilisé.&lt;br /&gt;
Cette fonction initialise chaque emplacement pour mots de passe et identifiants avec le mot &amp;quot;nouveau&amp;quot;.&lt;br /&gt;
pour savoir si le programme est exécuté pour la première fois, nous utilisons la valeur stockée dans le premier emplacement de l'EEPROM, si cet emplacement vaut 1, l'initialisation a déjà été effectuée lors d'une utilisation précédente.&lt;br /&gt;
Cette initialisation permet à l'utilisateur de l'interface graphique de voir apparaître &amp;quot;nouveau&amp;quot; plutôt qu'une chaîne de caractères incompréhensible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
/*lecture des informations transmises par l'interface graphique sur le port série*/&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
    }&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
/*lecture boutons*/&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7808</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7808"/>
				<updated>2016-03-28T12:52:11Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&amp;lt;br /&amp;gt;&lt;br /&gt;
(Il n'est pas possible d'utiliser d'utiliser une version pré-modifiée de ces fichiers, car les programmes HID.cpp et USBAPI.h peuvent varier en fonction du système d'exploitation utilisé ou de la version d'ARDUINO. Pour éviter les problèmes de compatibilité, il est préférable d'apporter les modifications suivantes aux fichiers fournis avec le logiciel) &lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7807</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7807"/>
				<updated>2016-03-28T12:38:26Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Clé_USB_HARENDARZ.jpg|vignette|center]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Cl%C3%A9_USB_HARENDARZ.jpg&amp;diff=7806</id>
		<title>Fichier:Clé USB HARENDARZ.jpg</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Cl%C3%A9_USB_HARENDARZ.jpg&amp;diff=7806"/>
				<updated>2016-03-28T12:35:41Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : Cleusb a téléversé une nouvelle version de Fichier:Clé USB HARENDARZ.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Cl%C3%A9_USB_HARENDARZ.jpg&amp;diff=7805</id>
		<title>Fichier:Clé USB HARENDARZ.jpg</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Cl%C3%A9_USB_HARENDARZ.jpg&amp;diff=7805"/>
				<updated>2016-03-28T12:32:51Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7804</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7804"/>
				<updated>2016-03-26T02:41:21Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Troisième clé USB}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=1.5|Board]] || [[Image:USB3_percage.png|vignette|upright=1.5|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=1.5|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=1.5|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=1.5|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=1.5|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=1.5|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7803</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7803"/>
				<updated>2016-03-26T02:39:21Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Problèmes rencontrés}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=1.5]] || [[Image:Board adaptation USB.png|vignette|upright=1.5]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=2|Board]] || [[Image:USB3_percage.png|vignette|upright=2|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=2|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=2|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=2|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=2|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7802</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7802"/>
				<updated>2016-03-26T02:38:35Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Conception de la première clé}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=1.5|Routage]] || [[Image:Percage_USB1.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=1.5|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=1.5|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=2]] || [[Image:Board adaptation USB.png|vignette|upright=2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=2|Board]] || [[Image:USB3_percage.png|vignette|upright=2|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=2|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=2|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=2|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=2|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7801</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7801"/>
				<updated>2016-03-26T02:37:56Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception de la deuxième carte}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=2|Routage]] || [[Image:Percage_USB1.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=2|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=2|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=2]] || [[Image:Board adaptation USB.png|vignette|upright=2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=1.5|Board]] || [[Image:Perçage_USB2.png|vignette|upright=1.5|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=1.5|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=1.5|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=2|Board]] || [[Image:USB3_percage.png|vignette|upright=2|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=2|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=2|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=2|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=2|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7800</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7800"/>
				<updated>2016-03-26T02:35:50Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Bleu|Conception d'un boitier pour la clé}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=2|Routage]] || [[Image:Percage_USB1.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=2|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=2|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=2]] || [[Image:Board adaptation USB.png|vignette|upright=2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=2|Board]] || [[Image:Perçage_USB2.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=2|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=2|Board]] || [[Image:USB3_percage.png|vignette|upright=2|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=2|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|center|upright=2|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|center|upright=2|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|center|upright=2|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|center|upright=2|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|center|upright=2|aperçu]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Correction}}==&lt;br /&gt;
Nous n'avions pas pris en compte le boitier lors de la réalisation de la clé. Avec l’épaisseur de celui ci, il n'est plus possible de relier le connecteur USB à un connecteur USB femelle. Pour utiliser le boitier il est donc nécessaire d'allonger le connecteur USB.&lt;br /&gt;
[[Image:USB3_board_final.png|vignette|center|upright=2|aperçu]]&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3_board_final.png&amp;diff=7799</id>
		<title>Fichier:USB3 board final.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3_board_final.png&amp;diff=7799"/>
				<updated>2016-03-26T02:34:31Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7798</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7798"/>
				<updated>2016-03-26T02:05:50Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Troisième clé USB}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=2|Routage]] || [[Image:Percage_USB1.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=2|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=2|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=2]] || [[Image:Board adaptation USB.png|vignette|upright=2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=2|Board]] || [[Image:Perçage_USB2.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=2|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=2|Board]] || [[Image:USB3_percage.png|vignette|upright=2|Perçage et détourrage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=2|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;br /&gt;
{|&lt;br /&gt;
! Boitier inférieur !! Boitier supérieur&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_dessus.png|vignette|upright=2|vue dessus]] || [[Image:Supérieur_vue_dessus.png|vignette|upright=2|vue dessus]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Inférieur_vue_face.png|vignette|upright=2|vue coté connecteur USB]] || [[Image:Supérieur_vue_face.png|vignette|upright=2|vue coté connecteur USB]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Aperçu_boitier_inférieur.png|vignette|upright=2|aperçu]] || [[Image:Aperçu_boitier_supérieur.png|vignette|upright=2|aperçu]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Aper%C3%A7u_boitier_inf%C3%A9rieur.png&amp;diff=7797</id>
		<title>Fichier:Aperçu boitier inférieur.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Aper%C3%A7u_boitier_inf%C3%A9rieur.png&amp;diff=7797"/>
				<updated>2016-03-26T02:01:20Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : Cleusb a téléversé une nouvelle version de Fichier:Aperçu boitier inférieur.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Aper%C3%A7u_boitier_sup%C3%A9rieur.png&amp;diff=7796</id>
		<title>Fichier:Aperçu boitier supérieur.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Aper%C3%A7u_boitier_sup%C3%A9rieur.png&amp;diff=7796"/>
				<updated>2016-03-26T01:59:21Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Aper%C3%A7u_boitier_inf%C3%A9rieur.png&amp;diff=7795</id>
		<title>Fichier:Aperçu boitier inférieur.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Aper%C3%A7u_boitier_inf%C3%A9rieur.png&amp;diff=7795"/>
				<updated>2016-03-26T01:46:54Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Sup%C3%A9rieur_vue_face.png&amp;diff=7794</id>
		<title>Fichier:Supérieur vue face.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Sup%C3%A9rieur_vue_face.png&amp;diff=7794"/>
				<updated>2016-03-26T01:44:26Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Inf%C3%A9rieur_vue_face.png&amp;diff=7793</id>
		<title>Fichier:Inférieur vue face.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Inf%C3%A9rieur_vue_face.png&amp;diff=7793"/>
				<updated>2016-03-26T01:43:38Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Sup%C3%A9rieur_vue_dessus.png&amp;diff=7792</id>
		<title>Fichier:Supérieur vue dessus.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Sup%C3%A9rieur_vue_dessus.png&amp;diff=7792"/>
				<updated>2016-03-26T01:42:51Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Inf%C3%A9rieur_vue_dessus.png&amp;diff=7791</id>
		<title>Fichier:Inférieur vue dessus.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:Inf%C3%A9rieur_vue_dessus.png&amp;diff=7791"/>
				<updated>2016-03-26T01:42:01Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7790</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7790"/>
				<updated>2016-03-25T20:18:26Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : /* {{Rouge|Troisième clé USB}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=2|Routage]] || [[Image:Percage_USB1.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=2|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=2|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=2]] || [[Image:Board adaptation USB.png|vignette|upright=2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=2|Board]] || [[Image:Perçage_USB2.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=2|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=2|Board]] || [[Image:USB3_percage.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=2|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;br /&gt;
&lt;br /&gt;
Nous avons conçu un boitier pour cette dernière version de la clé USB.&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7789</id>
		<title>CleUSB</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=CleUSB&amp;diff=7789"/>
				<updated>2016-03-25T17:44:47Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Catégorie:projets]]&lt;br /&gt;
&lt;br /&gt;
L'objectif de ce projet est de réaliser une clé USB capable de régler le volume de l'ordinateur sur lequel elle est branchée. Dans un deuxième temps, la clé devra pouvoir servir de télécommande ou stocker et saisir des mots de passes. Pour cela nous allons réaliser successivement plusieurs clés, la première servira uniquement à envoyer des informations à l'ordinateur afin d'ajuster le volume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Conception de la première clé}}=&lt;br /&gt;
&lt;br /&gt;
Notre projet est basé sur un ATMEGA32U4, nous avons donc repris le schéma de l'ARDUINO LEONARDO, en ne conservant que la partie utile à notre clé USB. Ainsi nous pouvons supprimer les entrées et sorties ARDUINO. La carte sera toujours alimentée par USB donc la borne de connexion pour alimentation  et le système de régulation de tension peuvent être supprimés. L'objectif étant de miniaturiser au maximum la carte, nous avons décidé de supprimer également les inductances et condensateurs destinés à l'amélioration de la qualité des mesures. &amp;lt;br/&amp;gt;&lt;br /&gt;
Nous allons ajouter sur le port D maintenant inutilisé 4 boutons et 4 LEDs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici la première version de la clé USB:&lt;br /&gt;
&lt;br /&gt;
[[Image:Schéma USB1.png|vignette|left|upright=4]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board_USB1.png|vignette|upright=2|Routage]] || [[Image:Percage_USB1.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants top USB1.png|vignette|upright=2|placement composants top]] || [[Image:Composants bottom USB1.png|vignette|upright=2|Placement composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1M || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ISP) || MA03-2&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.sch]]&lt;br /&gt;
*[[Media:HARENDARZ_DISSISSA_USB1.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Bootloader}}=&lt;br /&gt;
&lt;br /&gt;
Afin de téléverser les programmes sans utiliser le connecteur ISP et d’exécuter le programme à la mise sous tension du microcontrôleur, nous allons installer un bootloader sur l'ATMEGA32U4.&lt;br /&gt;
Pour cela, avant de le souder sur la carte, nous plaçons le microcontrôleur dans un boitier d'adaptation et utilisons l'outil &amp;quot;graver la séquence d'initialisation&amp;quot; du logiciel ARDUINO.&lt;br /&gt;
Dans la première version de la carte nous avons conservé l'ISP comme sécurité si le bootloader ne fonctionne pas. &lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Problèmes rencontrés}}==&lt;br /&gt;
Le connecteur ISP de la carte sur laquelle est soudé ce boitier d'adaptation, ne sont pas reliées aux bonnes broches du microcontrôleur. Nous allons donc créer une nouvelle carte d'adaptation sur laquelle nous souderons le boitier. Les broches à connecter sont:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Nom !! Broche ATMEGA32U4&lt;br /&gt;
|-&lt;br /&gt;
| MISO || 11&lt;br /&gt;
|-&lt;br /&gt;
| MOSI || 10&lt;br /&gt;
|-&lt;br /&gt;
| SCLK || 9&lt;br /&gt;
|-&lt;br /&gt;
| /RESET || 13&lt;br /&gt;
|-&lt;br /&gt;
| VCC || 14,34&lt;br /&gt;
|-&lt;br /&gt;
| GND || 15,23,35,43&lt;br /&gt;
|-&lt;br /&gt;
| Quartz || 16,17&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le boitier n'étant pas au format standard, il faut recréer le composant sur Eagle.&lt;br /&gt;
*[[Media:Adaptation_ATMEGA32U4.lbr]]&lt;br /&gt;
&lt;br /&gt;
voici la carte d'adaptation que nous avons réalisé.&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Schéma adaptation USB.png|vignette|upright=2]] || [[Image:Board adaptation USB.png|vignette|upright=2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
|1||(ISP)||MA03-2&lt;br /&gt;
|-&lt;br /&gt;
|1||1MR||R1206&lt;br /&gt;
|-&lt;br /&gt;
|1||(quartz 16MHz)||&lt;br /&gt;
|-&lt;br /&gt;
|1||(adaptateur ATMEGA32U4)||&lt;br /&gt;
|}&lt;br /&gt;
*[[Media:Carte_adaptation.sch]]&lt;br /&gt;
*[[Media:Carte_adaptation.brd]]&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Réglage du volume}}=&lt;br /&gt;
=={{Bleu|Modification des programmes ARDUINO}}==&lt;br /&gt;
Pour ajuster le volume d'un ordinateur, il existe 3 caractères spéciaux nommés XF86volume_up, XF86volume_down et XF86volume_mute.&lt;br /&gt;
Pour pouvoir envoyer ces caractères, il faut modifier les fichiers ARDUINO HID.cpp et USBAPI.h qui gèrent la partie &amp;quot;périphérique USB&amp;quot; de l'ARDUINO LEONARDO.&lt;br /&gt;
Voici un exemple de modification que nous avons trouvé qui ajoute à l'interface homme-machine la classe Remote permettant l'usage de fonctions de base d'une télécommande.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=USBAPI.h}}&lt;br /&gt;
| On déclare la classe Remote_ après les classes Keyboard_ et Mouse_ :&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote &lt;br /&gt;
 &lt;br /&gt;
#define REMOTE_CLEAR 0&lt;br /&gt;
#define VOLUME_UP 1&lt;br /&gt;
#define VOLUME_DOWN 2&lt;br /&gt;
#define VOLUME_MUTE 4&lt;br /&gt;
#define REMOTE_PLAY 8&lt;br /&gt;
#define REMOTE_PAUSE 16&lt;br /&gt;
#define REMOTE_STOP 32&lt;br /&gt;
#define REMOTE_NEXT 64&lt;br /&gt;
#define REMOTE_PREVIOUS 128&lt;br /&gt;
#define REMOTE_FAST_FORWARD 256&lt;br /&gt;
#define REMOTE_REWIND 512&lt;br /&gt;
 &lt;br /&gt;
class Remote_&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
public:&lt;br /&gt;
	Remote_(void);&lt;br /&gt;
	void begin(void);&lt;br /&gt;
	void end(void);&lt;br /&gt;
 &lt;br /&gt;
	// Volume&lt;br /&gt;
	void increase(void);&lt;br /&gt;
	void decrease(void);&lt;br /&gt;
	void mute(void);&lt;br /&gt;
 &lt;br /&gt;
	// Playback&lt;br /&gt;
	void play(void);&lt;br /&gt;
	void pause(void);&lt;br /&gt;
	void stop(void);&lt;br /&gt;
 &lt;br /&gt;
	// Track Controls&lt;br /&gt;
	void next(void);&lt;br /&gt;
	void previous(void);&lt;br /&gt;
	void forward(void);&lt;br /&gt;
	void rewind(void);&lt;br /&gt;
 &lt;br /&gt;
	// Send an empty report to prevent repeated actions&lt;br /&gt;
	void clear(void);&lt;br /&gt;
};&lt;br /&gt;
extern Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=HID.cpp}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| On déclare Remote l'instance de _Remote au début du programme:  &lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
Remote_ Remote;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| On place l'impémentation de Remote à la fin du fichier,&lt;br /&gt;
après l'implémentation de Mouse et Keyboard, et avant les #endif finaux:&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Remote&lt;br /&gt;
 &lt;br /&gt;
Remote_::Remote_(void)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::increase(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_UP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::decrease(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_DOWN;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::mute(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = VOLUME_MUTE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::play(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PLAY;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::pause(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PAUSE;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::stop(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_STOP;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::next(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_NEXT;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::previous(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = REMOTE_PREVIOUS;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::forward(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_FAST_FORWARD &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::rewind(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = REMOTE_REWIND &amp;gt;&amp;gt; 8;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Remote_::clear(void)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[2];&lt;br /&gt;
	m[0] = 0;&lt;br /&gt;
	m[1] = 0;&lt;br /&gt;
	HID_SendReport(4,m,2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|On place la description HID des élément de Remote après &amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#if RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt; (ligne 130 environ)&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
//-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
    /* Cross-platform support for controls found on IR Remotes */&lt;br /&gt;
&lt;br /&gt;
    0x05, 0x0c,                    //	Usage Page (Consumer Devices)&lt;br /&gt;
    0x09, 0x01,                    //	Usage (Consumer Control)&lt;br /&gt;
    0xa1, 0x01,                    //	Collection (Application)&lt;br /&gt;
    0x85, 0x04,                    //	REPORT_ID (4)&lt;br /&gt;
    0x15, 0x00,                    //	Logical Minimum (0)&lt;br /&gt;
    0x25, 0x01,                    //	Logical Maximum (1)&lt;br /&gt;
    0x09, 0xe9,                    //	Usage (Volume Up)&lt;br /&gt;
    0x09, 0xea,                    //	Usage (Volume Down)&lt;br /&gt;
    0x75, 0x01,                    //	Report Size (1)&lt;br /&gt;
    0x95, 0x02,                    //	Report Count (2)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xe2,                    //	Usage (Mute)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb0,                    //	Usage (Play)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb1,                    //	Usage (Pause)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb7,                    //	Usage (Stop)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb5,                    //	Usage (Next)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb6,                    //	Usage (Previous)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb3,                    //	Usage (Fast Forward)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x09, 0xb4,                    //	Usage (Rewind)&lt;br /&gt;
    0x95, 0x01,                    //	Report Count (1)&lt;br /&gt;
    0x81, 0x06,                    //	Input (Data, Variable, Relative)&lt;br /&gt;
&lt;br /&gt;
    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte&lt;br /&gt;
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) &lt;br /&gt;
    0xc0                           //	End Collection&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
|}{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici le fichier USBAPI.h modifié(les fichiers .cpp ne peuvent pas etre importé sur le wiki):&lt;br /&gt;
*[[Media:USBAPI.h]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Programme de réglage du volume}}==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x0f;&lt;br /&gt;
  PORTD=0xff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PD3);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD5))==0){&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=1;&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b0110;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Deuxième clé USB}}=&lt;br /&gt;
&lt;br /&gt;
Nous devons créer un nouvelle version de la clé USB plus compacte, qui permettrait l'usage de deux programme : le programme de gestion du volume ou un programme permettant le stockage et la saisie d'identifiant et de mots de passes. Pour ce dernier, nous allons également réaliser une interface graphique pour permettre à l'utilisateur de saisir les mots de passes à mémoriser.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la deuxième carte}}==&lt;br /&gt;
&lt;br /&gt;
Dans cette version de notre clé, le PCB fera office de connecteur USB mâle, on supprimera donc le connecteur utilisé dans la précédente clé. Le connecteur ISP sera aussi supprimé.&lt;br /&gt;
Dans le but de miniaturiser la carte, nous avons choisi d'utiliser un format de boitier plus petit pour les résistances, et la résistance associée au quartz a été supprimée. Le quartz ne peut cependant pas être supprimé, il est nécessaire pour les fonctions d'interface homme-machine que nous voulons utiliser. Les ports des entrées et sorties sont modifiés afin d'optimiser le routage.&lt;br /&gt;
&lt;br /&gt;
[[Image:Schema_USB2.png|vignette|upright=3|left|Schéma]]&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Board USB2.png|vignette|upright=2|Board]] || [[Image:Perçage_USB2.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Composants_top_USB2.png|vignette|upright=2|Composants top]] || [[Image:Composants_bottom_USB2.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Nomenclature&lt;br /&gt;
|-&lt;br /&gt;
! quantité !! valeur !! package&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (led) || PLCC2&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 330R || R0805&lt;br /&gt;
|-&lt;br /&gt;
| 4 || (bouton poussoir) || SWITCH-6*6.5&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 100nF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 22R || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1MR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 10kR || R1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1uF || C1206&lt;br /&gt;
|-&lt;br /&gt;
| 1 || (ATMEGA32U4) || TQFP44-PAD&lt;br /&gt;
|-&lt;br /&gt;
| 1 || quartz 16MHz || &lt;br /&gt;
|-&lt;br /&gt;
| 1 || (USB mâle A) || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*[[Media:USB2.sch]]&lt;br /&gt;
*[[Media:USB2.brd]]&lt;br /&gt;
composant utilisé pour le connecteur USB:&lt;br /&gt;
*[[Media:USB male.lbr]]&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Contrôle du volume}}==&lt;br /&gt;
&lt;br /&gt;
Ce programme est le même que dans la partie précédente, il est juste nécessaire de changer les broches des entrées et sorties.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
void setup(){&lt;br /&gt;
  DDRD=0x00;&lt;br /&gt;
  DDRF=0xf0;&lt;br /&gt;
  PORTD=0xf0;&lt;br /&gt;
  PORTF=0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop(){&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD6))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
    Remote.increase();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF7);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD4))==0){&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
    Remote.decrease();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=(1&amp;lt;&amp;lt;PF4);&lt;br /&gt;
  }&lt;br /&gt;
  if((PIND&amp;amp;(1&amp;lt;&amp;lt;PD7))==0){&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
    Remote.mute();&lt;br /&gt;
    Remote.clear();&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    PORTD^=0b01100000;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Gestion de mot de passe}}==&lt;br /&gt;
&lt;br /&gt;
Pour faciliter l'utilisation de la clé, nous avons choisi de ne stocker que 4 couples identifiants/mots de passe, ainsi, chaque bouton de la clé permet de l'envoie d'un mot de passe.&lt;br /&gt;
Pour la communication entre l'interface graphique et la clé, nous avons mis en place un protocole de communication.&lt;br /&gt;
Pour le moment, les chaines de caractères stockés doivent contenir 10 caractères ou moins, cette valeur pourra être augmenté en changeant l'adressage utilisé pour le stockage dans l'EEPROM.&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Protocole de communication}}===&lt;br /&gt;
chaque élément est séparé par le caractère '\n' (retour à la ligne).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| demande de la liste des identifiants/mots de passe &lt;br /&gt;
| 1 &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| commande de changement d'un couple&lt;br /&gt;
| 2 || n° du couple || identifiant || mot de passe &lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| envoie de la liste des couples&lt;br /&gt;
| 3 || n° du 1&amp;lt;sup&amp;gt;er&amp;lt;/sup&amp;gt; couple || identifiant n°1 || mot de passe n°1 || n° du 2&amp;lt;sup&amp;gt;ème&amp;lt;/sup&amp;gt; couple  || identifiant n°2 || ... &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Fonctionnement du microcontrôleur}}===&lt;br /&gt;
{{boîte déroulante/début|titre=Programme arduino}}&lt;br /&gt;
&amp;lt;small&amp;gt; &amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
#include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char bp[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PD5, 1 &amp;lt;&amp;lt; PD4, 1 &amp;lt;&amp;lt; PD7, 1 &amp;lt;&amp;lt; PD6&lt;br /&gt;
};&lt;br /&gt;
char led[4] = {&lt;br /&gt;
  1 &amp;lt;&amp;lt; PF4, 1 &amp;lt;&amp;lt; PF5, 1 &amp;lt;&amp;lt; PF6, 1 &amp;lt;&amp;lt; PF7&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
char inBuffer[255];    //Packet à envoyer&lt;br /&gt;
char s[4][15];         //s[0]=num consigne; s[1]=num ID; s[2]=ID; s[3]=MP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
La fonction change() modifie un couple identifiant mot de passe lorsqu'on reçoit une consigne de changement venant de l'interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour réduire l'usure de l'EEPROM, on change le caractère stocké seulement si il est différent du précédent.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void change() {&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  char adresse = 0x10 + s[1][0] * 0x20;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[2][i]) EEPROM.write( i + adresse, s[2][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[2][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
  i = 0;&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    if (EEPROM.read(i + adresse) != s[3][i]) EEPROM.write( i + adresse, s[3][i]);&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (s[3][i] != 0);&lt;br /&gt;
  if (EEPROM.read(i + adresse) != 0) EEPROM.write( i + adresse, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction liste retourne à l'interface graphique la liste des couples identifiant/mot de passe stockés&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
void liste() {&lt;br /&gt;
  String env = &amp;quot;&amp;quot;; //chaine de stockage des caracteres à envoyer&lt;br /&gt;
  env += '3';&lt;br /&gt;
  env += '\n';&lt;br /&gt;
&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int n = 0; n &amp;lt; 4; n++) {&lt;br /&gt;
    env += n;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    char i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
    i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char c = EEPROM.read(adresse + i);&lt;br /&gt;
      env += c;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while ((EEPROM.read(adresse + i) != 0) &amp;amp;&amp;amp; (i &amp;lt; 0x10));&lt;br /&gt;
    adresse += 0x10;&lt;br /&gt;
    env += '\n';&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(env);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**************&lt;br /&gt;
 * partie HID *&lt;br /&gt;
 **************/&lt;br /&gt;
&amp;lt;/source&amp;gt; &amp;lt;/small&amp;gt;&lt;br /&gt;
Partie du programme gérant les couples identifiants/mots de passe.&lt;br /&gt;
Le texte envoyé par l'ARDUINO LEONARDO est basé sur un clavier &amp;quot;qwerty&amp;quot; et le signal envoyé correspond à la position de la touche sur le clavier.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction translate permet de remplacer le caractère demandé par l'emplacement de ce caractère sur un clavier &amp;quot;qwerty&amp;quot;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Il est également possible de modifier la classe Keyboard d'ARDUINO afin qu'elle utilise un clavier &amp;quot;azerty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
char translate(char c) {&lt;br /&gt;
  switch (c) {&lt;br /&gt;
  case '1':&lt;br /&gt;
    c = '!';&lt;br /&gt;
    break;&lt;br /&gt;
  case '2':&lt;br /&gt;
    c = '@';&lt;br /&gt;
    break;&lt;br /&gt;
  case '3':&lt;br /&gt;
    c = '#';&lt;br /&gt;
    break;&lt;br /&gt;
  case '4':&lt;br /&gt;
    c = '$';&lt;br /&gt;
    break;&lt;br /&gt;
  case '5':&lt;br /&gt;
    c = '%';&lt;br /&gt;
    break;&lt;br /&gt;
  case '6':&lt;br /&gt;
    c = '^';&lt;br /&gt;
    break;&lt;br /&gt;
  case '7':&lt;br /&gt;
    c = '&amp;amp;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '8':&lt;br /&gt;
    c = '*';&lt;br /&gt;
    break;&lt;br /&gt;
  case '9':&lt;br /&gt;
    c = '(';&lt;br /&gt;
    break;&lt;br /&gt;
  case '0':&lt;br /&gt;
    c = ')';&lt;br /&gt;
    break;&lt;br /&gt;
  case '°':&lt;br /&gt;
    c = '_';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;amp;':&lt;br /&gt;
    c = '1';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'é':&lt;br /&gt;
    c = '2';&lt;br /&gt;
    break;&lt;br /&gt;
  case '&amp;quot;':&lt;br /&gt;
    c = '3';&lt;br /&gt;
    break;&lt;br /&gt;
  case '(':&lt;br /&gt;
    c = '5';&lt;br /&gt;
    break;&lt;br /&gt;
  case '-':&lt;br /&gt;
    c = '6';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'è':&lt;br /&gt;
    c = '7';&lt;br /&gt;
    break;&lt;br /&gt;
  case '_':&lt;br /&gt;
    c = '8';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'ç':&lt;br /&gt;
    c = '9';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'à':&lt;br /&gt;
    c = '0';&lt;br /&gt;
    break;&lt;br /&gt;
  case ')':&lt;br /&gt;
    c = '-';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'a':&lt;br /&gt;
    c = 'q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'A':&lt;br /&gt;
    c = 'Q';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'z':&lt;br /&gt;
    c = 'w';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Z':&lt;br /&gt;
    c = 'W';&lt;br /&gt;
    break;&lt;br /&gt;
  case '^':&lt;br /&gt;
    c = '[';&lt;br /&gt;
    break;&lt;br /&gt;
  case '$':&lt;br /&gt;
    c = ']';&lt;br /&gt;
    break;&lt;br /&gt;
  case '£':&lt;br /&gt;
    c = '}';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'q':&lt;br /&gt;
    c = 'a';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'Q':&lt;br /&gt;
    c = 'A';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'm':&lt;br /&gt;
    c = ';';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'M':&lt;br /&gt;
    c = ':';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'µ':&lt;br /&gt;
    c = '|';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'w':&lt;br /&gt;
    c = 'z';&lt;br /&gt;
    break;&lt;br /&gt;
  case 'W':&lt;br /&gt;
    c = 'Z';&lt;br /&gt;
    break;&lt;br /&gt;
  case ',':&lt;br /&gt;
    c = 'm';&lt;br /&gt;
    break;&lt;br /&gt;
  case '?':&lt;br /&gt;
    c = 'M';&lt;br /&gt;
    break;&lt;br /&gt;
  case ';':&lt;br /&gt;
    c = ',';&lt;br /&gt;
    break;&lt;br /&gt;
  case '.':&lt;br /&gt;
    c = '&amp;lt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case ':':&lt;br /&gt;
    c = '.';&lt;br /&gt;
    break;&lt;br /&gt;
  case '/':&lt;br /&gt;
    c = '&amp;gt;';&lt;br /&gt;
    break;&lt;br /&gt;
  case '!':&lt;br /&gt;
    c = '/';&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
  return c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction login saisie le couple identifiant/mot de passe correspondant au nombre sélectionné en paramètre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void login(char num) {&lt;br /&gt;
  Keyboard.begin();&lt;br /&gt;
  char adresse = 0x10 + 0x20 * num;&lt;br /&gt;
  char i = 0;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.write(KEY_TAB);&lt;br /&gt;
  i = 0;&lt;br /&gt;
  delay(100);&lt;br /&gt;
  adresse += 0x10;&lt;br /&gt;
  do {&lt;br /&gt;
    char c = EEPROM.read(adresse + i);&lt;br /&gt;
    Keyboard.print(translate(c));&lt;br /&gt;
    i++;&lt;br /&gt;
  }&lt;br /&gt;
  while (EEPROM.read(adresse + i) != 0);&lt;br /&gt;
  Keyboard.println(&amp;quot;&amp;quot;);//==write(KEY_RETURN)&lt;br /&gt;
  Keyboard.end();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*********************&lt;br /&gt;
 * partie principale *&lt;br /&gt;
 *********************/&lt;br /&gt;
void initialisation() {&lt;br /&gt;
  char val[] = {&lt;br /&gt;
    'n', 'o', 'u', 'v', 'e', 'a', 'u'&lt;br /&gt;
  };&lt;br /&gt;
  char adresse = 0x10;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    for (int j = 0; j &amp;lt; 7; j++) {&lt;br /&gt;
      EEPROM.write(adresse + i * 0x10 + j, val[j]);&lt;br /&gt;
    }&lt;br /&gt;
    EEPROM.write(adresse + i * 0x10 + 7, 0);&lt;br /&gt;
  }&lt;br /&gt;
  EEPROM.write(0, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  if (EEPROM.read(0) != 1) initialisation();&lt;br /&gt;
&lt;br /&gt;
  DDRD = 0;&lt;br /&gt;
  PORTD = 0xf0;&lt;br /&gt;
  DDRF = 0xf0;&lt;br /&gt;
  PORTF = 0xf0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (Serial.available()) {&lt;br /&gt;
&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    do {&lt;br /&gt;
      char inChar = (char)Serial.read();&lt;br /&gt;
      inBuffer[i] = inChar;&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    while (Serial.available());&lt;br /&gt;
    inBuffer[i] = 0;&lt;br /&gt;
&lt;br /&gt;
    int j = 0;&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    for (int k = 0; k &amp;lt; 4; k++) {&lt;br /&gt;
      do {&lt;br /&gt;
        s[k][j - a] = inBuffer[j];&lt;br /&gt;
        j++;&lt;br /&gt;
      }&lt;br /&gt;
      while ((inBuffer[j] != '\n') &amp;amp;&amp;amp; (j &amp;lt; 16 + a));&lt;br /&gt;
      s[k][j - a] = 0;&lt;br /&gt;
      j++;&lt;br /&gt;
      a = j;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (s[0][0] == '1') liste();&lt;br /&gt;
    else if (s[0][0] == '2') change();&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  static char ePresent[4], ePasse[4];&lt;br /&gt;
&lt;br /&gt;
  for (char i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    ePasse[i] = ePresent[i];&lt;br /&gt;
    ePresent[i] = PIND &amp;amp; bp[i];&lt;br /&gt;
    if ((ePresent[i] == 0) &amp;amp;&amp;amp; (ePasse[i] != 0)) {&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
      login(i);&lt;br /&gt;
      PORTF ^= led[i];&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==={{Vert|Interface graphique}}===&lt;br /&gt;
Nous avons choisi de réaliser notre interface graphique avec Processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous avons crée une interface qui contient une liste d'identifiants, un bouton de modification qui fait apparaître des fenêtres de saisie pour les modifications.&amp;lt;br /&amp;gt;&lt;br /&gt;
Pour utiliser notre programme, il est nécessaire d'installer la librairie controlP5 disponible dans la liste des librairie processing.&amp;lt;br /&amp;gt;&lt;br /&gt;
La librairie controlp5 fournit des outils graphiques (boutons, fenêtre de saisie, menu déroulant...) facilitant l'édition d'une interface graphique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsqu'un bouton ou un menu déroulant est créé, une fonction d’interruption portant le même nom que l'objet est disponible, cette fonction est activée par un clic sur le bouton ou un élément du menu.&lt;br /&gt;
&lt;br /&gt;
{{boîte déroulante/début|titre=Programme processing}}&lt;br /&gt;
Normalement, le premier port série disponible devrait être la clé donc on peut initialiser la communication série sur le port Serial.list()[0].&amp;lt;br /&amp;gt;&lt;br /&gt;
Nous pourront par la suite ajouter un élément d'interface graphique affichant la liste des ports série pour une sélection par l'utilisateur.&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
&amp;lt;source lang=cpp&amp;gt;&lt;br /&gt;
import processing.serial.*;&lt;br /&gt;
import controlP5.*;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
Serial myPort;                         // Objet pour la liaison série&lt;br /&gt;
byte[] inBuffer = new byte[255];&lt;br /&gt;
String id[]=new String[4];             // Tableau d'identifiants&lt;br /&gt;
String mp[]=new String[4];             // Tableau de mot de passe&lt;br /&gt;
//parfois, un caractère apparaît au début de la chaîne de caractères transmis, la variable suivante permet d'adapter la lecture à cette erreur par un décallage&lt;br /&gt;
char dec=2;                            //si &amp;gt;=2 erreur, sinon indique le décalage nécessaire pour la lecture&lt;br /&gt;
int num;                               // Numéro du couple identifiant mot de passe&lt;br /&gt;
&lt;br /&gt;
ControlP5 cp5;                         // Objet permettant l'ajout d'outils pour interfaces graphiques&lt;br /&gt;
boolean modif;                         // Drapeau indiquant la modification&lt;br /&gt;
boolean init;                          //attente de réception de données pour affichage&lt;br /&gt;
boolean finInit;                       // Drapeau pour vérifier la fin d'initialisation&lt;br /&gt;
int suppr=4;                           //compteur de tour pour suppression des cadres&lt;br /&gt;
PFont font = createFont(&amp;quot;arial&amp;quot;, 20);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  modif=false;&lt;br /&gt;
  size(600, 600);&lt;br /&gt;
  cp5 = new ControlP5(this);&lt;br /&gt;
  myPort=new Serial(this, Serial.list()[0], 9600);&lt;br /&gt;
  &lt;br /&gt;
  init=true;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  demande();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/********************&lt;br /&gt;
 * partie affichage *&lt;br /&gt;
 ********************/&lt;br /&gt;
&lt;br /&gt;
void draw() {&lt;br /&gt;
  lecture();&lt;br /&gt;
  decor();&lt;br /&gt;
  if (finInit==true) afficher();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LA LISTE DES IDENTIFIANTS ET LE BOUTON MODIFIER*/&lt;br /&gt;
void afficher() {&lt;br /&gt;
  init=false;&lt;br /&gt;
  finInit=false;&lt;br /&gt;
  cp5.addScrollableList(&amp;quot;Identifiants&amp;quot;)                 //création de la liste des identifiants&lt;br /&gt;
    .setPosition(220, 100)&lt;br /&gt;
      .setSize(200, 200)&lt;br /&gt;
        .setBarHeight(30)&lt;br /&gt;
          .setItemHeight(25)&lt;br /&gt;
            .addItems(id)&lt;br /&gt;
              .setColorBackground(color(155, 75, 80));&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Modifier&amp;quot;)                             //création du bouton bouton modifier&lt;br /&gt;
    .setPosition(440, 100)&lt;br /&gt;
      .setSize(100, 30)&lt;br /&gt;
        .setColorBackground(color(155, 75, 80));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*FONCTION POUR AFFICHER LE FOND*/&lt;br /&gt;
void decor() {&lt;br /&gt;
  background(100);&lt;br /&gt;
  fill(255);&lt;br /&gt;
  textSize(25);&lt;br /&gt;
  text(&amp;quot;Réglage de la clé USB&amp;quot;, 160, 60);&lt;br /&gt;
  textSize(15);&lt;br /&gt;
  text(&amp;quot;Choix de l'identifiant :&amp;quot;, 50, 120);&lt;br /&gt;
  if (modif==true) {                            //S'affiche quand la modification est activée&lt;br /&gt;
    text(&amp;quot;Identifiant :&amp;quot;, 100, 270);&lt;br /&gt;
    text(&amp;quot;Mot de passe :&amp;quot;, 100, 320);&lt;br /&gt;
    text(&amp;quot;Confirmation :&amp;quot;, 100, 370);&lt;br /&gt;
  } else if (suppr&amp;lt;4) {&lt;br /&gt;
    /*un délai est nécessaire entre deux suppressions donc on supprime un cadre par image affichée*/&lt;br /&gt;
    switch(suppr) {&lt;br /&gt;
    case 0:&lt;br /&gt;
      cp5.remove(&amp;quot;id&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 1:&lt;br /&gt;
      cp5.remove(&amp;quot;mp&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 2:&lt;br /&gt;
      cp5.remove(&amp;quot;cf&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case 3:&lt;br /&gt;
      cp5.remove(&amp;quot;Valider&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
    suppr++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de la séléction d'un élément de la liste */&lt;br /&gt;
void Identifiants(int n) {&lt;br /&gt;
  num=n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interruption déclenchée lors de l'appui sur le bouton modifier */&lt;br /&gt;
void Modifier() {&lt;br /&gt;
  modif=true;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;id&amp;quot;)                           //création de la fenêtre de saisie pour identifiant&lt;br /&gt;
    .setPosition(220, 250)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;mp&amp;quot;)                         //création de la fenêtre de saisie pour mot de passe&lt;br /&gt;
    .setPosition(220, 300)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)           //mode mot de passe (affichage d’étoile à la place des caractères)&lt;br /&gt;
                  ;  &lt;br /&gt;
&lt;br /&gt;
  cp5.addTextfield(&amp;quot;cf&amp;quot;)                         //création de la fenêtre de saisie pour confirmation du mot de passe&lt;br /&gt;
    .setPosition(220, 350)&lt;br /&gt;
      .setSize(200, 30)&lt;br /&gt;
        .setFont(font)&lt;br /&gt;
          .setFocus(true)&lt;br /&gt;
            .setAutoClear(false)&lt;br /&gt;
              .setColor(color(255))&lt;br /&gt;
                .setPasswordMode(true)&lt;br /&gt;
                  ;&lt;br /&gt;
&lt;br /&gt;
  cp5.addButton(&amp;quot;Valider&amp;quot;)                       //création du bouton valider&lt;br /&gt;
    .setPosition(220, 400)&lt;br /&gt;
      .setSize(200, 25)&lt;br /&gt;
        ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Interuption declenchée lors de l'appui sur le boutton valider */&lt;br /&gt;
public void Valider() {&lt;br /&gt;
  /*Pour valider, il faut qu'il ait au moins un caractère de saisie dans les partie identifiant et mot de passe*/&lt;br /&gt;
  if ((cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue() != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue() != &amp;quot;&amp;quot;)) {&lt;br /&gt;
    println(cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue()+'\n'+cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue());&lt;br /&gt;
&lt;br /&gt;
    /*Test pour vérifier qu'on à la même chaîne de caractère dans les fenêtre mot de passe et confirmation */&lt;br /&gt;
    if (cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue().equals(cp5.get(Textfield.class, &amp;quot;cf&amp;quot;).getStringValue()) == true ) {&lt;br /&gt;
      println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
      id[num]=cp5.get(Textfield.class, &amp;quot;id&amp;quot;).getStringValue();&lt;br /&gt;
      mp[num]=cp5.get(Textfield.class, &amp;quot;mp&amp;quot;).getStringValue();&lt;br /&gt;
      cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id);&lt;br /&gt;
      suppr=0;&lt;br /&gt;
      modif=false;&lt;br /&gt;
&lt;br /&gt;
      changer(num);&lt;br /&gt;
      demande();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/************************&lt;br /&gt;
 * partie communication *&lt;br /&gt;
 ************************/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//demande mp&lt;br /&gt;
void demande() {&lt;br /&gt;
  myPort.write(&amp;quot;1&amp;quot;+'\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//envoie nouveau mp&lt;br /&gt;
void changer(int num) {&lt;br /&gt;
  myPort.write(&amp;quot;2&amp;quot;+'\n'+num+'\n'+id[num]+'\n'+mp[num]+'\n');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void lecture() {&lt;br /&gt;
  char I[]=new char[16];           //chaîne de caractères reçus pour l’identifiant, sera converti en String après traitement&lt;br /&gt;
  char M[]=new char[16];           //chêne de caractères reçus pour le mot de passe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (dec&amp;lt;2) {&lt;br /&gt;
    int i=dec+2;                   //apres 3\n&lt;br /&gt;
&lt;br /&gt;
    for (int j=0; j&amp;lt;4; j++) {&lt;br /&gt;
      int k=0;&lt;br /&gt;
      i+=2;                        //apres 3 \n num \n&lt;br /&gt;
      //lecture de l'identifiant i&lt;br /&gt;
      do {&lt;br /&gt;
        I[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      id[j]=new String(I);&lt;br /&gt;
      i++;&lt;br /&gt;
      k=0;&lt;br /&gt;
&lt;br /&gt;
      //lecture du mot de passe i&lt;br /&gt;
      do {&lt;br /&gt;
        M[k]=char(inBuffer[i]);&lt;br /&gt;
        i++;&lt;br /&gt;
        k++;&lt;br /&gt;
      }&lt;br /&gt;
      while ( (inBuffer[i]!='\n')&amp;amp;&amp;amp;(k&amp;lt;15));&lt;br /&gt;
      mp[j]=new String(M);&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    if(init==false) cp5.get(ScrollableList.class, &amp;quot;Identifiants&amp;quot;).setItems(id); //si la liste d'identifiant existe on la met à jour&lt;br /&gt;
    else finInit=true;                                                          //sinon on autorise la création de la liste&lt;br /&gt;
    dec=2;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void serialEvent(Serial myPort) {&lt;br /&gt;
  println(&amp;quot;reçu&amp;quot;);&lt;br /&gt;
  myPort.readBytesUntil(0x0d, inBuffer);&lt;br /&gt;
&lt;br /&gt;
  if (inBuffer != null) {&lt;br /&gt;
    if (inBuffer[0]=='3') {&lt;br /&gt;
      dec=0;&lt;br /&gt;
    } else if (inBuffer[1] == '3') {  //si le début du signal est décalé d'un octet&lt;br /&gt;
      dec=1;&lt;br /&gt;
    } else dec =2;  &lt;br /&gt;
 /*si le décalage est plus grand, on considère que c'est une erreur car il y a de forte chance que le&lt;br /&gt;
 signal ne corresponde pas à celui attendu et que la présence de la consigne 3 ne soit qu'une coïncidence*/&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/small&amp;gt;&lt;br /&gt;
{{boîte déroulante/fin}}&lt;br /&gt;
&lt;br /&gt;
={{Rouge|Troisième clé USB}}=&lt;br /&gt;
La carte suivante est une version améliorée de la clé précédente. Le schéma reste le même, mais le routage a été amélioré afin de faciliter la fabrication (via plus espacés), et d'inclure un anneau pour fixer un porte clé.&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception de la troisième carte}}==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_board.png|vignette|upright=2|Board]] || [[Image:USB3_percage.png|vignette|upright=2|Perçage]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:USB3_composants_top.png|vignette|upright=2|Composants top]] || [[Image:USB3_composants_bottom.png|vignette|upright=2|Composants bottom]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=={{Bleu|Conception d'un boitier pour la clé}}==&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3_composants_bottom.png&amp;diff=7788</id>
		<title>Fichier:USB3 composants bottom.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3_composants_bottom.png&amp;diff=7788"/>
				<updated>2016-03-25T17:44:29Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	<entry>
		<id>http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3_composants_top.png&amp;diff=7787</id>
		<title>Fichier:USB3 composants top.png</title>
		<link rel="alternate" type="text/html" href="http://wikigeii.iut-troyes.univ-reims.fr//index.php?title=Fichier:USB3_composants_top.png&amp;diff=7787"/>
				<updated>2016-03-25T17:44:07Z</updated>
		
		<summary type="html">&lt;p&gt;Cleusb : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cleusb</name></author>	</entry>

	</feed>