SE3 PSE Binome2023-5

De projets-se.plil.fr
Aller à la navigation Aller à la recherche

Projet système embarqué de Rémi BOURSAULT et Antoine LECOMTE

L'objectif de ce module est de modéliser une manette, puis de la rendre fonctionnelle, pour jouer au jeu Space Invaders qui est codé dans le même module.

Les professeurs avaient préalablement fourni un dossier contenant un modèle de PCB incomplet et différents fichiers ".c" et ".h" pour nous aider à démarrer.

Création de Manette

La création de la manette commence par la création sur kicad d'un PCB. Nous avons pris celui fourni sur le wiki du projet qui possède tous les composants mais non routés.



Modélisation PCB

A partir du fichier KiCad fourni, nous avons modélisé un PCB déstiné à être utilisé comme manette. Nous avons donc ajouté des boutons, replacé ces derniers. Grâce au schéma nous avons sélectionné des PIN pour connecter les boutons, ainsi que des LEDs et des résistances que nous avons aussi ajouté.

Voyant que nous avions encore de l'espace de libre sur notre carte, étant un peu ambitieux et voyant que le procédé n'est pas bien compliqué, nous décidons alors de rajouter quelque boutons et quelques LEDs en plus pour que notre manette soit un peu plus crédibles.

Il nous a alors fallu rajouté les dit composants sur notre schéma pour que ceux-ci soient rajoutés automatiquement sur le PCB lors de l'utilisation de la fonction "Update PCB with changes made to schematic"



Ajout du plan de masse et des via


Une fois le routage effectué, nous avons ajouté un plan de masse et ajouté une grande quantité de via à différent endroits de la carte pour que la masse soit bien connectée et éviter les fuites thermiques de certains composants.

Ensuite le fichier a été envoyé pour impression en Chine, grâce au fichier Gerber généré par KiCad que vous pouvez retrouvez sur notre GIT:


Rendu 3D final de la carte

Programmateur AVR

En attendant de recevoir les cartes, nous nous sommes initiés à la programmation d'un périphérique USB, nous avons utilisé les bibliothèques LUFA et LibUSB pour utilisé un programmateur AVR. Il nous a fallu également modifier des fichiers Descripteurs, en ".c" et ".h" qui permettent, une fois téléversés dans le programmateur, d'être détecter par le PC et que celui-ci reconnaisse les fonctionnalités du périphérique (InPoint et EndPoint).


Soudure de la carte

Une fois la carte reçu, nous avons pris tous nos composants et avons commencé à les souder. N'ayant que très peu d'expérience dans ce domaine ce n'était pas quelque chose de facile au début. Il nous a fallu un peu d'aide et pas mal de flux pour comprendre comment faire des soudures propres. Une fois le coup de main pris, la fin du montage de la carte était assez rapide. Nous avons donc pu passer à la programmation pour la reconnaissance par l'ordinateur de notre carte.

Carte vierge
Carte avec tous les composants soudés


Une fois la carte soudée il a fallu pouvoir la configurer pour par la suite pouvoir la programmer. Pour se faire il faut lui injecter un bootloader via son programmateur ISP. Ce qui passe la manette en mode DFU et elle est alors reconnu par l'ordinateur.

Manette reconnu en mode DFU

LUFA de la manette

Après avoir reçu les cartes et terminé de souder les composants nous avons pu attaquer la programmation du microcontrôleur pour pouvoir utiliser la manette. Nous avons procédés étape par étape, en commençant par allumé les LEDs puis réceptionner les signaux des boutons pour finir par fusionner les deux pour avoir une manette fonctionnelle.

LEDs

Pour éviter un décalage sur le portF il faut désactiver le JTAG en copiant deux fois cette ligne au niveau de la déclaration des pins : MCUCR |= (1<<JTD);cela permet d'accéder aux LEDs sur les pins PF4 et PF5.

Une fois la configuration terminé, nous avons testé nos LEDs avec la fonction suivante :

void blink_leds(void){
  PORTF |= 0b00110011;
  _delay_ms(200);
  PORTF &= ~0b00110011;
  _delay_ms(200);
  PORTF |= 0b00110011;
  _delay_ms(200);
  PORTF &= ~0b00110011;
}

Ce qui nous donne ce résultat



Nous avons également fais la fonction EtatLED dans le fichier USBFinal.c (fichier servant à détecter et communiquer avec la manette par le port USB) qui se trouve dans le dossier libUSB, qui sert à allumer ou éteindre la LED de son choix.

void EtatLED(int etat, int numLED, libusb_device *manette, libusb_device_handle *handle, struct libusb_config_descriptor *configdesc)
{
    int indint=0;/* e.g. première interface */
    int indalt=0; /* e.g. première alternative */
    int interface=1; //;configdesc->interface[indint].altsetting[indalt].bInterfaceNumber;
    int status=libusb_claim_interface(handle,interface);

    if(status!=0)
    {
            printf("bij\n");
        perror("libusb_claim_interface");
        exit(-1);
    }

    printf("Interface %d claimed\n",interface);

    unsigned char data = 0;
    if(etat){
       switch (numLED){
        case 1:
            data = 0x01;
            break;
        case 2:
            data = 0x02;
            break;
        case 3:
            data = 0x03;
            break;
        case 4:
            data = 0x04;
            break;
        default:
            printf("Selectionnez un chiffre entre 1 et 4");
        }
    }else{
        switch (numLED){
        case 1:
            data = 0x11;
            break;
        case 2:
            data = 0x12;
            break;
        case 3:
            data = 0x13;
            break;
        case 4:
            data = 0x14;
            break;
        default:
            printf("Selectionnez un chiffre entre 1 et 4");
        }
    }

Exemple d'appel dans le main EtatLED(0,1, manette, handle, configdesc);. La fonction va éteindre la LED 1.

Boutons

Les LEDs étant configuré il est temps de passer à l'utilisation des boutons. Le principe reste globalement le même, on modifie les fichiers descriptors et minimal selon nos besoins. Pour nous faciliter un peu la tâche nous avons pris les fichiers déjà existant pour des joysticks. Nous allons considérer que si un de nos boutons est appuyé cela reviendra au même que si un joystick est dirigée au maximum dans une direction donnée.


La modification majeure à faire pour que nos boutons soit détecté était sur la fonction

bool GetNextReport(USB_JoystickReport_Data_t* const ReportData)
{
  static uint8_t PrevJoyStatus    = 0;
  static uint8_t PrevButtonStatus = 0;
  bool           InputChanged     = false;

  /* Clear the report contents */
  memset(ReportData, 0, sizeof(USB_JoystickReport_Data_t));

  if(~(PIND>>PD4) & 1){
    ReportData->X = -100;
  }
  if(~(PIND>>PD7) & 1){
    ReportData->X =  100;
  }
  if(~(PIND>>PD6) & 1){
    ReportData->Y = -100;
  }
  if(~(PINB>>PB4) & 1){
    ReportData->Y =  100;
  }
  if(~(PINF>>PF7) & 1){
    ReportData->Button |= (1 << 0);
  }
  if(~(PINF>>PF6) & 1){
    ReportData->Button |= (1 << 1);
  }
  /* Return whether the new report is different to the previous report or not */
  return InputChanged;
}

Cela nous permet de dire que si un bouton que nous avons configuré est enfoncé, on met la direction X ou Y à plus ou moins 100. Nous les avons tester avec jstest-gtk qui permet de visualiser les directions et appuis d'un joystick, tous nos boutons sont reconnus et configurés comme nous le souhaitons.

Regroupement des deux

Pour avoir une manette fonctionnelle à 100% la dernière étape est de fusionner les différents fichiers pour les LEDs et pour les boutons pour que tout soit utilisable en même temps. Pour cela il a fallu modifié le fichier Descritpors.c, dans la fonction

const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptoril faut indiquer le nombre d'interface à deux, puis rajouter une interface. Dans notre cas étant parti du fichier des boutons nous avons rajouté celle des LEDs. Une fois ceci fais, il ne restait plus qu'à rajouter les fonctions de chaque partie dans un même fichier minimal.c et nous avons fini la configuration et la programmation de notre manette.

Implémentation dans le Space Invaders

Makefile
Fonction de gestion des LEDs
Titre
Titre
Titre

GIT

Vous pouvez consulter le dépôt Git des projet. Celui-ci contient le fichier gerber de la manette crée sur KiCad. Les fichiers utilisé pour le programmateur AVR sont dans le dossier projet-info-manette/ProgrammateurAVR. Et les fichiers utilisé pour la manette sont eux dans le dossier projet-info-manette/fichier_lufa_libusb.