IMA4 2018/2019 EC4
Sommaire
Présentation du projet
Contexte
L'élève continue son semestre S8 à l'école.
Objectif
L'objectif est de terminer la conception d'une mini-manette de jeu à base d'ATMega16u2 pour des travaux pratiques d'IMA4. Il est aussi demandé de programmer le micro-contrôleur.
Description du projet
Concernant la partie matérielle, il vous est demandé de :
- partir du circuit Media:Circuit_16u2_v7.zip (remplacez l'extension par
.fzz
) ; - remplacer le quartz par un quartz plus compact de type FA238 ;
- d'ajouter un joystick sur la partie gauche et un circuit d'acquisition analogique pour l'exploiter.
Le circuit d'acquisition peut être un MCP3008 qui présente la bonne propriété de pouvoir être connecté à l'ATMega16u2 par le bus SPI.
Pour pouvoir faire tenir le MCP3008 et le joystick sur le circuit vous pouvez sacrifier une LED et agrandir modérément le PCB.
Concernant la partie logicielle, programmez le micro-contrôleur en utilisant la bibliothèque LUFA pour que la manette apparaisse comme une manette USB classique, c'est à dire comme un périphérique USB de la classe HID. La manette doit pouvoir être utilisée directement par un jeu contrôlable par manette. Comme base vous utiliserez la démonstration Joystick
de la LUFA (code bas niveau).
Matériel nécessaire
Description | Fabricant | Référence Fabricant | Fournisseur | Quantité | Lien fournisseur |
---|
Planning prévisionnel
Travail effectué
La première partie de mon travail est de concevoir le PCB de la manette. En suivi l'énoncé, j'ai changé le quartz pae un quartz plus compact de type FA238 et ajouté un Joystick sur la partie gauche. J'avais dû mettre un circuit d'acquisition analogique (MCP3008). Par contre, monsieur Boé m'a proposé d'utiliser un ATmega16u4 à la place d'un ATmega16u2 pour simplifier la lecture d'une valeur analogique. Donc, avec un ATmega16u4, je n'ai plus besoin un MCP3008.
Le schématic de mon PCB :
Une fois le schématic est fait, le travail suivant est le routage du PCB.
Après avoir vérifié tout le routage de mon PCB , la carte est envoyé à fabriquer. ET voici, la carte reçue :
Cependant, il y a un problème grave avec ma carte. J'ai pris un ATmega16u4 en boitier QFN, qui a un métal en bas. C'est à dire si je mets des vias sous l'ATmega16u4, il va avoir des court-circuits et la carte ne va pas bien fonctionner comme elle faut. Donc, je suis obligé de gratter les deux vias qui sont connectés à UCAP et à PB6(ADC13).
L'étape suivante est de souder la première parts de composants.
Ensuite, monsieur REDON essayait de brancher la carte sur un PC et tester avec l'instruction 'lsusb'. La carte ne peut pas d'être détectée. Après avoir testé avec un multimètre, on a trouvé que j'ai oublié de connecté AVCC et C6 à 5V. Pour corriger cette erreur, j'ai mis deux fils à externe.
Malheureusement, le périphérique ne peut toujours pas être détecté. Donc, la seule possibilité qui reste est la connection UCAP, qui a était gratté pour éviter le court-circuit. J'ajoutais un fil pour la connection de UCAP et la carte est enfin détectée. On a testé le fonctionnement des composants soudés avec un Arduino Leonardo, en conséquence, il n'y a qu'une seule LED s'allume parmi les trois mais les autres composants fonctionnent correctement. Je soudais du coup la deuxième parts de composants, c'est à dire le Joystick et les boutons.
Enfin, je passe à la deuxième partie de mon épreuve complémentaire, la programmation pour la manette. J'ai réalisé cette partie par 3 étape :
1) Allumer la LED en appuyant sur un bouton
2) Allumer la LED en jouant sur le Joystick
3) Assembler ces deux derniers et tester le fonctionnement de la manette
Allumer la LED en appuyant sur un bouton
En appliquant le fichier IO.c et IO.h, je suis permet de paramètrer les INPUTs (les boutons) et les OUTPUTs (les LEDs). J'utilise PB7 comme INPUT, c'est à dire le bouton "Haut". J'initialise avec le code :
inputs_init(0b10000000, 0x00,0x00,0x00,0x00,0x00);
J'utilise PF5 comme OUTPUT, c'est la LED qui fonctionne. J'initialise avec le code :
outputs_init(0x00,0x00,0b11100000);
Donc, dans une boucle infinie, après avoir récupéré l'état du bouton, j'ai mis un if(). Si le bouton est appuyé, le LED s'allume, sinon la LED s'étteint. Voici le code :
for (;;){ inputs_get(&portb, &portc, &portd); if((portb&0b10000000) != 0x00){outputs_set(0x00,0x00,0xe0);} else{outputs_set(0x00,0x00,0x00);} }
Et la LED fonctionne comme elle faut.
Allumer la LED en jouant sur le Joystick
Pour pouvoir utiliser un Joystick, il faut appliquer le module ADC, parce que les variables envoyées par le joystick sont en analogique.
void initializeADC(unsigned char channel){ ADCSRA = (1 << ADEN) | (0b111 << ADPS0); ADCSRB = (1 << MUX5); ADMUX = (0b11 << REFS0) | channel;}
int readAnalogADCValue(void){ ADCSRA |= (1<<ADSC); while (ADCSRA & (1 << ADSC)); return ADC;}
Avec la fonction 'initializeADC()', je pourrais choisir la variable que je veux récupérer (il y a deux variables : V et H). 'V' est connecté à la PIN ADC8 et 'H' est connecté à ADC11.
Premièrement, je récupère la valeur de 'V' et la mettre dans un variable 'analog1' : `
initializeADC(0b000000); analog1=readAnalogADCValue();
Je fait la même chose pour 'H' :
initializeADC(0b000011); analog2=readAnalogADCValue();
Avec l'ATmega32u4, la valeur analogique est sauvegarder en 10 bits, de 0 à 1024. Et je veux l'exprimer de -100 à 100. Donc, avec le code suivant, je peux réaliser la transformation de valeur :
calc1=(analog1*200)>>10; calc2=(analog2*200)>>10; ReportData->Y = calc1-100; ReportData->X = calc2-100;
Dans une boucle infinie, si ReportData->Y est égale à -100 ou 100, j'allume la LED. Pour l'axe X, je fait la même chose.
Assembler ces deux derniers et tester le fonctionnement de la manette
Maintenant, il faut rassembler les deux dernières parties ensemble.