« SE3Trinome2022-8 » : différence entre les versions

De projets-se.plil.fr
Aller à la navigation Aller à la recherche
(modif et correction)
 
(15 versions intermédiaires par le même utilisateur non affichées)
Ligne 2 : Ligne 2 :
CAZIN Némo, CEGARRA Antoine, PALIFERRO Adrien
CAZIN Némo, CEGARRA Antoine, PALIFERRO Adrien


== Objectifs fixés : ==
'''Lien du git :''' ''https://archives.plil.fr/ncazin/SE3_GROUPE_8.git''
L'objectif principal de ce projet était de réaliser la commande d'une voiture au format 1:43 capable d'avancer et reculer à l'aie d'un programme informatique. Avant de commencer le projet, nous nous sommes fixé plusieurs petits objectif afin de mener au mieux le projet.


La voiture devait tout d'abord avancer, reculer, tourner à gauche et à droite. Des LEDs devait être allumées lorsque la voiture effectue un déplacement.
==Objectifs fixés :==
L'objectif principal de ce projet était de '''réaliser la commande d'une voiture au format 1:43''' capable d'avancer et de reculer à l'aide d'un programme informatique. Avant de commencer le projet, nous nous sommes fixé plusieurs petits objectifs afin de mener au mieux le projet.


Pour la commande de la voiture, nous voulions qu'elle soit commandée grâce à une commande Bluetooth et pilotée depuis un smartphone. Une application devait alors être faites pour gérer les déplacements. MIT App Inventor permet de gérer des communications Bluetooth et est simple d'utilisation.
La voiture devait tout d'abord avancer, reculer, tourner à gauche et à droite. Des LEDs devaient être allumées lorsque la voiture effectue un déplacement.
 
Pour la commande de la voiture, nous voulions qu'elle soit commandée grâce à une commande Bluetooth et pilotée depuis un smartphone. Une application devait alors être faite pour gérer les déplacements. MIT App Inventor permet de gérer des communications Bluetooth et est simple d'utilisation.


Afin de pouvoir implémenter toutes ses fonctionnalités, nous devions réaliser une carte électronique gérée par un microcontrôleur ATMega16u2. D'autres module devaient être ajoutés pour la bonne réalisation de nos objectifs fixés.
Afin de pouvoir implémenter toutes ses fonctionnalités, nous devions réaliser une carte électronique gérée par un microcontrôleur ATMega16u2. D'autres module devaient être ajoutés pour la bonne réalisation de nos objectifs fixés.


== La carte électronique : ==
==La carte électronique :==
[[Fichier:Voiture CCP.zip|vignette|Voiture fichiers de routage et schéma PCB]]
 
La réalisation de la carte électronique a débutée par la création du schéma électrique sur KICAD. Nous avons implémenté ce que nous aviosn déjà prévu (Chargeur, moteurs, microcontrolleur...), cependant, pour certaines fonctionnalités, des composants n'étaient pas disponibles dans les librairies Sparkfun disponibles.  
La réalisation de la carte électronique a débuté par la création du schéma électrique sur KICAD. Nous avons implémenté ce que nous avions déjà prévu (Chargeur, moteurs, microcontrôleur...), cependant, pour certaines fonctionnalités, des composants n'étaient pas disponibles dans les librairies Sparkfun disponibles.  


Nous avons donc créé les schémas de ces composants, c'est-à-dire le module Bluetooth FP-BM70BLE01FC2 ainsi que le driver du moteur DRV8210DRL grâce aux informations de leurs datasheet disponible sur internet :   
Nous avons donc créé les schémas de ces composants, c'est-à-dire le module Bluetooth '''FP-BM70BLE01FC2''' ainsi que le driver du moteur '''DRV8210DRL''' grâce aux informations de leurs datasheet disponible sur Internet :   


- https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/BM70_71-Bluetooth-Low-Energy-BLE-Module-DS60001372L.pdf  
- Datasheet du module Bluetooth : ''https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/BM70_71-Bluetooth-Low-Energy-BLE-Module-DS60001372L.pdf''


-  
- Datasheet du driver du moteur : ''https://www.ti.com/lit/ds/slvsfy8b/slvsfy8b.pdf?ts=1683016270840&ref_url=https%253A%252F%252Fwww.google.com%252F''


Au final, nous obtenons au final ce schéma correspondant :   
Au final, nous obtenons au final ce schéma correspondant :   
[[Fichier:Schématic voiture.jpg|alt=Schéma de la voiture|centré|vignette|Schéma de la voiture]]
Après avoir fait le schéma de la voiture, nous avons dû faire le routage de la carte électronique. La première chose a faire à été de prendre les côtes de la voiture afin que la carte électronique se mette bien en place dessus. De plus, nous avons dû prendre les mesures des côtes du moteur continu, celui-ci va être soudé au centre de la carte et est imposant, il fallait donc prévoir la place nécessaire que le composant prendrait. 
Ensuite, nous avons dû réaliser les empreintes du module Bluetooth ainsi que du driver du moteur. Les mesures figurant sur leurs datasheet respectives, nous avons réussi simplement à les reproduire. Le plus compliqué a été de repérer les pâtes des composants que nous devions utiliser. Par exemple, sur le module Bluetooth, certaines entrées n'ont pas été utilisées. Nous avons aussi utilisé et adapter les empreintes des moteurs continus et pas à pas fournis par notre professeur M.Redon. 


ZIP :
Après cela, nous avons commencé le routage. Nous avons commencer par router la carte le plus possible sur une seule face jusqu'à ce que ne l'on puisse plus. Sinon nous utilisions des vias afin de router sur l'autre face. Cependant, nous avons dû recommencer une seconde fois le routage, car le premier ne nous convenait pas. Nous avons aussi demandé de l'aide au professeur M.Boé afin de réaliser les plans de masse. 


== Application Bluetooth : ==
Voici une image du routage final notre carte électronique : 
Nous nous étions fixé comme objectif que la voiture devait être contrôlée grâce à une application Bluetooth. Nous avons alors décidé de réaliser cette application grâce au site MIT App Inventor, ce site est simple d'utilisation et permet de gérer des communications Bluetooth facilement. De plus, le temps a était investi surtout dans la carte électronique donc apprendre et programmer par nous même dans un langage de programmation nouveau aurait été compliqué pour nous.
[[Fichier:Routage voiture.jpg|alt=Routage de la carte électronique|centré|vignette|Routage de la carte électronique]]
Voici aussi une représentation 3D de notre carte électronique :   
[[Fichier:Pcb 3D.jpg|alt=Représentation 3D de notre carte électronique|centré|vignette|Représentation 3D de notre carte électronique]]
Le routage fini, nous avons passé commande afin de recevoir notre carte électronique et voici celle-ci avec aucune soudure :   


Nous avons décider que les informations envoyées par communication Bluetooth serait sous forme hexadécimale. Le programme informatique du côté de l'ATMega16u2 recevra et traitera alors les informations reçues.  
Enfin, la carte étant vierge, nous devions commencer la soudure des composants. Cette partie a été très compliquée à mettre en oeuvre, car dans le groupe, aucun de nous n'avait fait de soudure dans sa vie. Nous avons donc dû apprendre à ce moment comment faire, d'les premières soudures un peu compliquées.


L'application devait avoir un aspect simple d'utilisation et sobre afin de faciliter l'expérience de l'utilisateur. L'application amènerait l'utilisateur sur une page permettant de choisir à quelle appareil Bluetooth se connecter. Un statut indiquant si le smartphone est connecté ou non à l'appareil est aussi présent. L'élément le plus important de la page est le bloc de déplacement, composé de 4 boutons représentant des flèches directionnelles afin de piloter la voiture.
Nous avons eu un problème de reconnaissance du microprocesseur lors de la commande "''lsusb"'', le matériel n'était pas détecté. Nous avons donc dû modifier le circuit qui comportait quelques erreurs, ainsi que remplacer les résistances et condensateurs afin de s'assurer de leur valeur. Finalement, nous avons dû changer le microprocesseur qui avec les précédents branchements avait surchauffé et était défectueux. Après avoir remplacé tous les composants, nous avons réussi à faire reconnaître le microprocesseur grâce à la commande "''lsusb''". Après cela, nous avons pu souder les derniers composants restants.


Lorsque nous avions terminé l'application pour piloter grâce à des flèches directionnelles, nous nous sommes rendu compte que nous pourrions réaliser aussi un pilotage par gyroscope. En effet, les informations transmises pour les déplacements reste les mêmes donc du côté du programme informatique, rien ne change. Nous avons deux moyens de piloter la voiture : une par appuis sur des flèches directionnelles, et une seconde par inclinaisons du smartphone.  
Voici une photo de notre carte avec les composants soudés :   
[[Fichier:Carte électronique avec les composants soudés.jpg|alt=Carte électronique avec les composants soudés|centré|vignette|Carte électronique avec les composants soudés]]
Nous avions fini la carte électronique, sa réalisation a pris la majeure partie de notre temps lors des séances. Il fallait donc ensuite réaliser un programme permettant de faire fonctionner et avancer la voiture.   
 
Fichier ZIP de notre carte électronique : [[Fichier:Voiture CCP.zip|vignette|Voiture fichiers de routage et schéma PCB]]
 
==Programme de la voiture :==
Le programme informatique était nécessaire pour le bon fonctionnement de la voiture, cependant comme le temps commençait à manquer, nous avons codé son programme en dehors des cours de projet.
 
Nous avons donc structuré notre code en plusieurs afin de le simplifier. Les premières fonctions permettent d'initialiser les entrées et les sorties du microcontrôleur afin de bien récupérer et envoyer les bonnes informations. De plus, dans ces fonctions, nous remettons les moteurs et les leds à LOW afin d'avoir une sécurité et qu'ils ne démarrent pas à l'initialisation. Ensuite, nous retrouvons les fonctions de déplacements. Ces fonctions gèrent les moteurs lorsqu'il faut avancer, reculer, tourner à droite, etc...
 
De plus, on retrouve une fonction permettant de récupérer les informations envoyées depuis la communication Bluetooth afin de faire fonctionner la voiture à distance. Une seconde fonction permet de traiter ces informations et de faire déplacer la voiture selon l'information reçue.
 
Nous pouvons aussi faire fonctionner la voiture en envoyant le programme informatique dans la voiture. Cependant, de cette manière, la voiture ne pourra pas être contrôlée et fera un trajet voulu.
 
La communication Bluetooth étant un de nos objectifs fixé, nous avons dû réaliser une application afin de pouvoir utiliser la voiture à distance.
 
Voici une vidéo de la carte avec une LED qui clignote :
[[Fichier:PCB clignote.mov|alt=LED qui clignote|centré|vignette|LED qui clignote]]
 
==Application Bluetooth :==
Nous nous étions fixé comme objectif que la voiture devait être contrôlée grâce à une application Bluetooth. Nous avons alors décidé de réaliser cette application grâce au site '''MIT App Inventor''', ce site est simple d'utilisation et permet de gérer des communications Bluetooth facilement. De plus, le temps a été investi surtout dans la carte électronique donc apprendre et programmer par nous-même dans un langage de programmation nouveau aurait été compliqué pour nous.
 
Nous avons décidé que les informations envoyées par communication Bluetooth serait sous forme hexadécimale. Le programme informatique du côté de l'ATMega16u2 recevra et traitera alors les informations reçues.
 
L'application devait avoir un aspect simple d'utilisation et sobre afin de faciliter l'expérience de l'utilisateur. L'application amènerait l'utilisateur sur une page permettant de choisir à quel appareil Bluetooth se connecter. Un statut indiquant si le smartphone est connecté ou non à l'appareil est aussi présent. L'élément le plus important de la page est le bloc de déplacement, composé de 4 boutons représentant des flèches directionnelles afin de piloter la voiture.
 
Lorsque nous avions terminé l'application pour piloter grâce à des flèches directionnelles, nous nous sommes rendu compte que nous pourrions réaliser aussi un pilotage par gyroscope. En effet, les informations transmises pour les déplacements restent les mêmes donc du côté du programme informatique, rien ne change. Nous avons deux moyens de piloter la voiture : une par appui sur des flèches directionnelles, et une seconde par inclinaison du smartphone.  


Voilà des captures d'écran montrant l'aspect et les fonctionnalités de l'application :  
Voilà des captures d'écran montrant l'aspect et les fonctionnalités de l'application :  
Ligne 45 : Ligne 81 :
Fichier:Gestion des boutons.jpg|Bloc de gestion des touches
Fichier:Gestion des boutons.jpg|Bloc de gestion des touches
Fichier:Gestion gyroscope.jpg|Bloc de gestion du gyroscope
Fichier:Gestion gyroscope.jpg|Bloc de gestion du gyroscope
</gallery>Après avoir programmé l'application, nous devions récupérer les informations et les traiter du côté de la carte électronique. Pour cela, nous implémenterons un programme informatique codé en C dans la mémoire de l'ATMega16u2.
</gallery>
 
'''Le fichier APK de l'application est disponible dans le GIT du projet.'''
 
= '''Epreuve complémentaire CAZIN Némo''' =
'''Lien du git :''' ''https://archives.plil.fr/ncazin/SE3_GROUPE_8.git''
 
== Introduction : ==
J’ai dû reprendre le projet lors de mon épreuve complémentaire de Semestre 6
 
Avant cela, avec mon groupe de travail, nous avions réussi à faire clignoter une LED malgré tous les problèmes que nous avions rencontrés comme des composants qui ne fonctionnait plus sur la carte ou alors des courts-circuits à faire nous-mêmes. Je ne traiterais donc pas ici la partie du clignotement de la LED.
 
== Préparation de la carte électronique : ==
Tout d’abord, lorsque j’ai repris le projet, je savais que les soudures des composants et du moteur continu avaient été faites, mais elles étaient fragiles du fait de la petite épaisseur des pistes reliant le moteur au driver. De plus, le voyage de la boite avec la carte électronique à l’intérieur avait complétement cassé les soudures du moteur.
 
Voici l’état de la carte lors de la reprise du projet :
[[Fichier:Carte pas de soudure.jpg|alt=Carte avec le moteur désoudé|centré|vignette|Carte avec le moteur désoudé]]
J’ai donc dû refaire les soudures du moteur, ce qui a été un peu compliqué, car j’ai du mal à souder en général. Mais en m’inspirant des photos que j’avais d’avant la reprise du projet, j’ai pu mieux m’en sortir. Voilà le résultat de la soudure du moteur continu :
[[Fichier:Carte moteur DC.jpg|alt=Carte avec le moteur continu soudé|centré|vignette|Carte avec le moteur continu soudé]]
Après cela, j’ai voulu continuer mon travail en faisant les soudures du moteur pas-à-pas. Ce moteur est très petit et les soudures à faire devaient être très précises. Pour que ce soit plus simple, j’ai utilisé 4 pins que j’ai soudé à la carte et sur les pins, des câbles sont reliés jusqu’aux quatre liaisons du moteur. Le moteur est alors déporté de la carte, mais ce n’est pas très important, car on veut juste le voir fonctionner et aucune roue n’est attachée. Ces soudures étaient vraiment compliquées à réaliser, car elles étaient très minutieuses à réaliser et souvent des soudures se cassaient lorsque j’en soudais une autre.
 
Voilà le résultat de la soudure du moteur pas à pas :
[[Fichier:Carte moteur pap.jpg|alt=Carte avec le moteur pas-à-pas soudé|centré|vignette|Carte avec le moteur pas-à-pas soudé]]Après avoir soudé tous les composants que je souhaitais, j'ai vérifié les anciennes soudures pour voir s'il n'y avait pas des câbles qui étaient cassés à cause du voyage. Après vérification, tout était bon et je pouvais commencer la programmation.
 
== Problèmes eu pendant la programmation de la carte sur ordinateur : ==
J'ai rencontré plusieurs problèmes lors de la programmation et lors de la reconnaissance de la carte par les machines.
 
Tout d'abord, il faut savoir que j'ai commencé développer mes programmes informatiques sur les machines de l’école à distance grâce à l’outil : '''https://tp-info.polytech-lille.fr/#'''
 
Ensuite, le premier problème était que certaines bibliothèques utilisées, notamment '''''<avr/io.h>''''' ne sont pas trouvables, ce qui fait que la compilation d'un de mes fichiers de test ne peut pas être réalisée. J'ai comme hypothèse que soit la librairie n'est pas installée sur les machines des salles de TP en C10X, soit il faut être en superutilisateur pour pouvoir compiler le fichier d'après les notes que j'ai des cours. Je ne peux pas me mettre en superutilisateur car il faut le mot de passe de la machine locale que je ne connais pas. Pour contourner ce problème, j'ai défini comme constantes toutes les variables utilisées mais ce n'est qu'une solution temporaire qui ne marchera peut-être pas lors de l'envoi du programme sur la carte, mais au moins j'ai réussi à compiler mes fichiers.
[[Fichier:Erreur include.jpg|alt=Message de l'erreur reçu par rapport à la librairie <avr/io.h>|centré|vignette|Message de l'erreur reçu par rapport à la librairie <avr/io.h>]]
 
 
 
Enfin, pour le second problème, j’ai voulu voir si la carte était reconnue depuis les machines à distance grâce à la commande shell « '''''lsusb''''' ». Cependant, lorsque je me connecte sur ces machines, les périphériques USB de mon ordinateur ne sont pas reconnus. En faisant plusieurs essais pour résoudre ce problème, j’ai compris que ce n’était pas possible et donc qu’il fallait passer par une autre méthode. Sois-je faisais directement la programmation sur Windows, mais télécharger les dépendances et le compilateur C était compliqué. Sois-je téléchargeais une machine virtuelle Ubuntu pour être directement sur un système Linux et plus simplement programmer. J’ai donc choisi la première option, car je craignais que la machine virtuelle ne reconnaisse pas elle aussi les périphériques USB.
 
J’ai donc modifié l’option développeur de mon Windows afin de pouvoir télécharger un environnement terminal Ubuntu qui fonctionne grâce à Windows Subsystem for Linux (WSL). J’ai alors rencontré une erreur lors du lancement du terminal Ubuntu :
[[Fichier:Erreur Ubuntu.jpg|alt=Erreur WSL pour Ubuntu|centré|vignette|Erreur WSL pour Ubuntu]]
J’ai alors trouvé une documentation de Microsoft sur le WSL qui m’a permis de résoudre ce problème ('''https://learn.microsoft.com/fr-fr/windows/wsl/troubleshooting'''). Après cela, j’ai voulu donc tester la commande « '''''lsusb''''' » mais encore une fois, une nouvelle erreur apparaît :
[[Fichier:Erreur libusb.jpg|alt=Erreur de la libusb sur Ubuntu|centré|vignette|Erreur de la libusb sur Ubuntu]]
J’ai donc télécharger la librairie libusb grâce à la commande « '''''sudo apt-get install libusb-1.0-0-dev''''' » que j’ai trouvé grâce aux informations de ce site : '''https://askubuntu.com/questions/629619/how-to-install-libusb''' , mais même en faisant cette commande, j’ai toujours eu la même erreur. Donc à ce stade du projet, cette solution n'était pas viable et devait être plus approfondie.
 
En parallèle, j'ai essayé d'installer une machine virtuelle Ubuntu sur mon ordinateur, mais Oracle VM VirtualBox n'accepte que les fichiers .xml alors que je me suis procuré un fichier .iso. Après avoir téléchargé le bon fichier, j'ai dû faire la manipulation de la première méthode pour me retrouver avec la même erreur de la libusb.
 
Après des essais directement réalisés sur les machines de l'école, j'ai remarqué que le microprocesseur n'était pas reconnu. Il doit y avoir donc une soudure ou une connexion qui a dû se casser, ou alors le microprocesseur qui ne fonctionne plus comme nous l'avions déjà eu au début du projet.
 
== Programmation du moteur continu : ==
J’ai donc commencé par la partie du moteur continu, car c’est sur cette partie que nous nous sommes arrêtés.
 
Afin de faire fonctionner le moteur, je devais faire un programme informatique afin de gérer cette fonctionnalité. J’ai tout d’abord créé une fonction pour initialiser les ports du moteur comme étant des sorties. Ensuite, j’ai créé une fonction « avancer » où je mets un des ports sous tension et l’autre non. Pour la fonction « reculer », il s’agit de la même chose mais il faut inverser quel port est sous tension. Enfin pour la fonction « arrêter », il suffit de mettre les deux ports à 0.
 
Voici donc le code pour faire fonctionner le moteur de cette façon :<syntaxhighlight lang="c">
//////////////////////////////////////////
/// INITIALISATION MOTEUR DC AVEC PORT ///
//////////////////////////////////////////
   
void initMotDC_Port(void){
    DDRB |= (1<<PB7);                  //PMW2 en OUTPUT
    DDRD |= (1<<PD0);                  //PMW1 en OUTPUT
    PORTB=(0<<PB7);                    //PMW2 à LOW
    PORTD=(0<<PD0);                    //PMW1 à LOW
}
 
////////////////////////////////////
/// CONTROLE MOTEUR DC AVEC PORT ///
////////////////////////////////////
 
void move_forwards(void){
    PORTB=(1<<PB7); //MOT1 à HIGH
    PORTD=(0<<PD0); //MOT2 à LOW
}
 
void move_backwards(void){
    PORTB=(0<<PB7); //MOT1 à LOW
    PORTD=(1<<PD0); //MOT2 à HIGH
}
 
void stop(void){
    PORTB=(0<<PB7); //MOT1 à LOW
    PORTD=(0<<PD0); //MOT2 à LOW 
}
</syntaxhighlight>Après avoir fait cela, je me suis demandé si nous pouvions contrôler la vitesse du moteur. J’ai alors regardé trouver une page d’un cours de PSE ('''https://rex.plil.fr/Enseignement/Systeme/Systeme.PSE/systeme053.html''') expliquant comment fonctionne les actionneurs simples grâce aux signaux PWM (Pulse Width Modulation). Une partie du programme pour l’initialisation des ports était donnée, cependant, il s’agissait de la gestion des sorties que je ne comprenais pas (OCR0A, OCR0B …), j’ai donc dû effectuer plusieurs recherches sur cette partie. Voici donc le code pour faire fonctionner le moteur de cette autre façon :<syntaxhighlight lang="c">
//////////////////////////////////////////
/// INITIALISATION MOTEUR DC AVEC OCR1 ///
//////////////////////////////////////////
 
void initMotDC_OCR(void){
    DDRB |= (1<<PB7);                  //PMW2 en OUTPUT
    DDRD |= (1<<PD0);                  //PMW1 en OUTPUT
    TCCR1A |= (1<<COM1A1)|(1<<COM1C1);  // Les ports PWM se comportent normalement
    TCCR1A |= (1<<WGM11)|(1<<WGM10);    // Minuteur mis en mode PWM
    TCCR1B |= (1<<CS10);                // Pas de pré-diviseur, démarre le compteur
 
///////////////////////////////////
/// CONTROLE MOTEUR DC AVEC OCR ///
///////////////////////////////////
 
void move_forwards_OCR(void){
    OCR1A = 512;
    OCR1C = 0;
}
 
void move_backwards_OCR(void){
    OCR1A = 0;
    OCR1C = 512;
}
 
void stop_OCR(void){
    OCR1A = 0;
    OCR1C = 0; 
}
</syntaxhighlight>
 
== Programmation du moteur pas à pas : ==
Comme je n'avais jamais travaillé sur un moteur pas à pas, j'ai voulu comprendre son fonctionnement. Après plusieurs recherches, j'ai compris que le moteur était constitué d'un rotor magnétique et de bobines. Nous avons ici un moteur pas à pas bipolaire, avec 4 sorties. Le moteur fonctionne par pas successifs comme une montre, ce qui signifie qu'il faut jouer avec chacune des sorties afin de le faire tourner pas par pas. En partant de ce principe, nous pouvons programmer une fonction pour que chaque sortie soit sous tension les unes à la suite des autres.
 
Voici le programme pour faire tourner le moteur pas à pas dans un sens :<syntaxhighlight lang="c">
///////////////////////////////////////
/// INITIALISATION MOTEUR PAS A PAS ///
///////////////////////////////////////
 
void initMotStepper(void){
    DDRC |= (1<<PC4);
    DDRC |= (1<<PC5);
    DDRC |= (1<<PC6);
    DDRC |= (1<<PC7);
}
 
/////////////////////////////////
/// CONTROLE MOTEUR PAS A PAS ///
/////////////////////////////////
   
void stepper_left(void){
    for(int i = 0; i<=100; i++){
        //M1_A+ à 1 puis 0
        PORTC=(1<<PC7);
        _delay_ms(5);
        PORTC=(0<<PC7);
       
        //M1_B- à 1 puis 0
        PORTC=(1<<PC4);
        _delay_ms(5);
        PORTC=(0<<PC4);
       
        //M1_A- à 1 puis 0
        PORTC=(1<<PC6);
        _delay_ms(5);
        PORTC=(0<<PC6);
       
        //M1_B+ à 1 puis 0
        PORTC=(1<<PC5);
        _delay_ms(5);
        PORTC=(0<<PC5);
    }
}
</syntaxhighlight>Pour aller dans l'autre sens, il suffit d'inverser le sens des broches des sorties :<syntaxhighlight lang="c">
void stepper_right(void){
    for(int i = 0; i<=100; i++){
        //M1_B+ à 1 puis 0
        PORTC=(1<<PC5);
        _delay_ms(5);
        PORTC=(0<<PC5);
       
        //M1_A- à 1 puis 0
        PORTC=(1<<PC6);
        _delay_ms(5);
        PORTC=(0<<PC6);
       
        //M1_B- à 1 puis 0
        PORTC=(1<<PC4);
        _delay_ms(5);
        PORTC=(0<<PC4);
       
        //M1_A+ à 1 puis 0
        PORTC=(1<<PC7);
        _delay_ms(5);
        PORTC=(0<<PC7);
    }
}
</syntaxhighlight>Voici ma documentation :
 
- '''https://www.tme.eu/fr/news/library-articles/page/41861/Moteur-pas-a-pas-types-et-exemples-dapplications-des-moteurs-pas-a-pas/'''
 
- '''https://www.youtube.com/watch?v=655p1N9tSKQ'''
 
- '''http://www.micropython.fr/modules_center/moteurs/pas_a_pas/moteur_pap/#le-principe-dun-moteur-pas-a-pas'''


== Programme informatique ==
== Programmation de la communication Bluetooth : ==
La partie Bluetooth était un de nos objectifs du début de projet afin de contrôler la voiture à distance et grâce à une application. Pour cela, j’ai dû refaire des recherches sur le sujet afin de mieux comprendre comment je pourrai faire. J’ai donc dû regarder la documentation de l’atmega16u2 et des cours en ligne d’autres universités pour bien comprendre. C’est alors que j’ai compris que la communication série UART permettrait de répondre à mes besoins. J’ai donc écrit une fonction qui permet l’initialisation de la communication série UART en activant la transmission (TX) et la réception (RX). Ensuite, dans cette même fonction, j’ai dû définir le format de la trame, elle est donc composée de 8 bits, c’est-à-dire un octet avec un bit d’arrêt.


== Notes : ==
Nous n’avons besoin que de recevoir des informations sur la communication série UART, pas d’en envoyer. C’est pour cela que j’ai donc dû faire une seconde fonction permettant de recevoir les informations de l’application sur le port RX de l’Atmega16u2.


Voici le code de la communication UART :<syntaxhighlight lang="c">
/////////////////////////////////////////
/// INITIALISATION COMMUNICATION UART ///
/////////////////////////////////////////


Séance 28/02
void UART_init(unsigned int baud_rate){
    // Calculer la valeur de UBRR en fonction du baud_rate
    unsigned int ubrr_val = FREQ_CPU / (16UL * baud_rate) - 1;   
    // Définir les valeurs UBRRH et UBRRL
    UBRRH = (unsigned char)(ubrr_val >> 8);
    UBRRL = (unsigned char)ubrr_val;
    // Activer la transmission et la réception
    UCSRB = (1 << TXEN) | (1 << RXEN);
    // Définir le format de trame: 8 bits de données, 1 bit d'arrêt
    UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
}


Réalisation du PCB : Alim et chargeur à finir (faire gaffe aux deux nomenclatures)
/////////////////////////////////////
/// RECUPERATION DES DONNEES UART ///
/////////////////////////////////////


int UART_receiver(void) {
    // Attendre que le tampon d'entrée soit plein
    while (!(UCSRA & (1 << RXC)));
    // Lire le caractère du tampon d'entrée
    return UDR;
}
</syntaxhighlight>Cette fonction ne pouvait pas être testée, car l’antenne Bluetooth n’est pas présente sur la carte électronique de la voiture. Cependant, ces recherches m’ont permis de mieux comprendre la communication série UART que j’avais mal comprise lors des TP du semestre 6.


Séance 14/03
== Programmation USB/LUFA ==
Pour cette partie de la programmation via USB/LUFA, j’ai repris le fichier utilisé lors de notre cours de TPI. Ce fichier avait quelques modifications à faire avant d’être utilisé. Tout d’abord, j’ai dû changer les Vendor ID et Product ID de la carte électronique, car celles utilisées maintenant n’est pas la même que pendant le cours de TPI. Normalement grâce à la commande "'''''lsusb -vvv"''''', on peut trouver le microcontrôleur utilisé et ces ID, mais nous les avions déjà noté auparavant. On trouve alors :


Finition du schéma (alim, chargeur, led, port Série, Bluetooth àfinir), début routage
-       VENDOR ID : 0x03EB  


https://www.ti.com/lit/ds/symlink/lm4040.pdf?ts=1678740694814&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FLM4040
-       PRODUCT ID : 0x2FEF


https://docs.rs-online.com/f3fa/0900766b81623cc8.pdf<nowiki/>*
Ensuite, des modifications étaient à faire sur les fichiers du descripteur. En effet, celui-ci avait du code qui faisait référence au joystick utilisé en TPI. J’ai donc juste gardé les fonctions qui faisaient référence aux actionneurs.


De plus, afin de pouvoir gérer les actionneurs, j’ai préparé en amont comment ils seront activés grâce aux octets à envoyer. Cependant, j’ai décidé d’utiliser qu’un seul octet de contrôle, car 2 était beaucoup trop pour les simples fonctions que nous avions. Nous avons alors un seul octet ayant chaque bit qui représente une fonction de contrôle de la voiture avec de droite à gauche :


Séance 21/03
-       Bit 0 : Allume la LED


Schéma fini, manque des footprints à faire pour 3 composants --> routage
-       Bit 1 : Fait avancer la voiture


-       Bit 2 : Fait reculer la voiture


-       Bit 3 : Fait tourner dans un sens la voiture


Séance 11/04
-       Bit 4 : Fait tourner dans l’autre sens la voiture


Routage terminé, retouche à faire (plan de masse etc..)
Par exemple, le schéma ci-dessous permet d’allumer la LED de la voiture, de la faire reculer, et en même temps de la faire tourner dans un sens :
[[Fichier:USB exemple.png|alt=Exemple d'octet|centré|vignette|Exemple d'octet ]]
Voici d'ailleurs le code du programme traitant chaque bit de l'octet pour exécuter les fonctions voulues : <syntaxhighlight lang="c">
void actionneurs_gestion(void){
Endpoint_SelectEndpoint(ACT_EPADDR);
if (Endpoint_IsOUTReceived()){
if (Endpoint_IsReadWriteAllowed()){
  uint16_t ACT_Report = Endpoint_Read_16_LE();


            //CONTROLE DES LEDS
            if(ACT_Report & (1<<0))
                led_on();
            else
                led_off();
       
//CONTROLE DU MOTEUR DC
if(ACT_Report & (1<<1))
                move_forwards();
            else if(ACT_Report & (1<<2))
                move_backwards();
else
                stop();
           
            //CONTROLE DU MOTEUR PAS A PAS
            if(ACT_Report & (1<<3))
                stepper_left();
            else if(ACT_Report & (1<<4))
                stepper_right();
}
/* Handshake the OUT Endpoint - clear endpoint and ready for next report */
Endpoint_ClearOUT();
}
}
</syntaxhighlight>Enfin, nous avons juste à envoyer l’octet de notre choix afin de gérer comme on veut les actionneurs.


Séance 2/05
En retravaillant sur cette partie, j’ai mieux compris le fonctionnement de la libusb que je n’avais pas beaucoup compris lors du cours de TPI. J’ai pu me documenter sur le sujet en faisant beaucoup de recherche, et même d’apprendre des nouvelles façons de travailler avec le langage C et d’avoir une meilleure syntaxe de programmation.


Réception de la carte
== Conclusion de mon travail durant l'épreuve complémentaire : ==
J'ai rencontré beaucoup de problèmes durant cette épreuve complémentaire. J'en ai résolu la plupart, mais certains étaient beaucoup trop compliqués et m'ont fait passer beaucoup de temps dessus. Il fallait donc que je m'organise pour ne pas passer tout le projet à résoudre certains problèmes et mettre de côté le nécessaire.


Rédaction du wiki
Principalement, je trouve que je me suis bien débrouillé. J'ai surtout pu me remettre à jour en programmation du langage C et sur la libusb. J'ai pu aussi améliorer mes compétences en soudure et en gestion de projet. Mais surtout, j'ai dû faire beaucoup de recherches pour bien comprendre certains aspects qui étaient nécessaires. En général, j'ai beaucoup appris durant cette épreuve et j'ai pu mettre en avant ma détermination à finir le projet.

Version actuelle datée du 4 septembre 2023 à 16:31

Projet SE3 : Premier Système

CAZIN Némo, CEGARRA Antoine, PALIFERRO Adrien

Lien du git : https://archives.plil.fr/ncazin/SE3_GROUPE_8.git

Objectifs fixés :

L'objectif principal de ce projet était de réaliser la commande d'une voiture au format 1:43 capable d'avancer et de reculer à l'aide d'un programme informatique. Avant de commencer le projet, nous nous sommes fixé plusieurs petits objectifs afin de mener au mieux le projet.

La voiture devait tout d'abord avancer, reculer, tourner à gauche et à droite. Des LEDs devaient être allumées lorsque la voiture effectue un déplacement.

Pour la commande de la voiture, nous voulions qu'elle soit commandée grâce à une commande Bluetooth et pilotée depuis un smartphone. Une application devait alors être faite pour gérer les déplacements. MIT App Inventor permet de gérer des communications Bluetooth et est simple d'utilisation.

Afin de pouvoir implémenter toutes ses fonctionnalités, nous devions réaliser une carte électronique gérée par un microcontrôleur ATMega16u2. D'autres module devaient être ajoutés pour la bonne réalisation de nos objectifs fixés.

La carte électronique :

La réalisation de la carte électronique a débuté par la création du schéma électrique sur KICAD. Nous avons implémenté ce que nous avions déjà prévu (Chargeur, moteurs, microcontrôleur...), cependant, pour certaines fonctionnalités, des composants n'étaient pas disponibles dans les librairies Sparkfun disponibles.

Nous avons donc créé les schémas de ces composants, c'est-à-dire le module Bluetooth FP-BM70BLE01FC2 ainsi que le driver du moteur DRV8210DRL grâce aux informations de leurs datasheet disponible sur Internet :

- Datasheet du module Bluetooth : https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/BM70_71-Bluetooth-Low-Energy-BLE-Module-DS60001372L.pdf

- Datasheet du driver du moteur : https://www.ti.com/lit/ds/slvsfy8b/slvsfy8b.pdf?ts=1683016270840&ref_url=https%253A%252F%252Fwww.google.com%252F

Au final, nous obtenons au final ce schéma correspondant :

Schéma de la voiture
Schéma de la voiture

Après avoir fait le schéma de la voiture, nous avons dû faire le routage de la carte électronique. La première chose a faire à été de prendre les côtes de la voiture afin que la carte électronique se mette bien en place dessus. De plus, nous avons dû prendre les mesures des côtes du moteur continu, celui-ci va être soudé au centre de la carte et est imposant, il fallait donc prévoir la place nécessaire que le composant prendrait.

Ensuite, nous avons dû réaliser les empreintes du module Bluetooth ainsi que du driver du moteur. Les mesures figurant sur leurs datasheet respectives, nous avons réussi simplement à les reproduire. Le plus compliqué a été de repérer les pâtes des composants que nous devions utiliser. Par exemple, sur le module Bluetooth, certaines entrées n'ont pas été utilisées. Nous avons aussi utilisé et adapter les empreintes des moteurs continus et pas à pas fournis par notre professeur M.Redon.

Après cela, nous avons commencé le routage. Nous avons commencer par router la carte le plus possible sur une seule face jusqu'à ce que ne l'on puisse plus. Sinon nous utilisions des vias afin de router sur l'autre face. Cependant, nous avons dû recommencer une seconde fois le routage, car le premier ne nous convenait pas. Nous avons aussi demandé de l'aide au professeur M.Boé afin de réaliser les plans de masse.

Voici une image du routage final notre carte électronique :

Routage de la carte électronique
Routage de la carte électronique

Voici aussi une représentation 3D de notre carte électronique :

Représentation 3D de notre carte électronique
Représentation 3D de notre carte électronique

Le routage fini, nous avons passé commande afin de recevoir notre carte électronique et voici celle-ci avec aucune soudure :

Enfin, la carte étant vierge, nous devions commencer la soudure des composants. Cette partie a été très compliquée à mettre en oeuvre, car dans le groupe, aucun de nous n'avait fait de soudure dans sa vie. Nous avons donc dû apprendre à ce moment comment faire, d'où les premières soudures un peu compliquées.

Nous avons eu un problème de reconnaissance du microprocesseur lors de la commande "lsusb", le matériel n'était pas détecté. Nous avons donc dû modifier le circuit qui comportait quelques erreurs, ainsi que remplacer les résistances et condensateurs afin de s'assurer de leur valeur. Finalement, nous avons dû changer le microprocesseur qui avec les précédents branchements avait surchauffé et était défectueux. Après avoir remplacé tous les composants, nous avons réussi à faire reconnaître le microprocesseur grâce à la commande "lsusb". Après cela, nous avons pu souder les derniers composants restants.

Voici une photo de notre carte avec les composants soudés :

Carte électronique avec les composants soudés
Carte électronique avec les composants soudés

Nous avions fini la carte électronique, sa réalisation a pris la majeure partie de notre temps lors des séances. Il fallait donc ensuite réaliser un programme permettant de faire fonctionner et avancer la voiture.

Fichier ZIP de notre carte électronique : Fichier:Voiture CCP.zip

Programme de la voiture :

Le programme informatique était nécessaire pour le bon fonctionnement de la voiture, cependant comme le temps commençait à manquer, nous avons codé son programme en dehors des cours de projet.

Nous avons donc structuré notre code en plusieurs afin de le simplifier. Les premières fonctions permettent d'initialiser les entrées et les sorties du microcontrôleur afin de bien récupérer et envoyer les bonnes informations. De plus, dans ces fonctions, nous remettons les moteurs et les leds à LOW afin d'avoir une sécurité et qu'ils ne démarrent pas à l'initialisation. Ensuite, nous retrouvons les fonctions de déplacements. Ces fonctions gèrent les moteurs lorsqu'il faut avancer, reculer, tourner à droite, etc...

De plus, on retrouve une fonction permettant de récupérer les informations envoyées depuis la communication Bluetooth afin de faire fonctionner la voiture à distance. Une seconde fonction permet de traiter ces informations et de faire déplacer la voiture selon l'information reçue.

Nous pouvons aussi faire fonctionner la voiture en envoyant le programme informatique dans la voiture. Cependant, de cette manière, la voiture ne pourra pas être contrôlée et fera un trajet voulu.

La communication Bluetooth étant un de nos objectifs fixé, nous avons dû réaliser une application afin de pouvoir utiliser la voiture à distance.

Voici une vidéo de la carte avec une LED qui clignote :

Application Bluetooth :

Nous nous étions fixé comme objectif que la voiture devait être contrôlée grâce à une application Bluetooth. Nous avons alors décidé de réaliser cette application grâce au site MIT App Inventor, ce site est simple d'utilisation et permet de gérer des communications Bluetooth facilement. De plus, le temps a été investi surtout dans la carte électronique donc apprendre et programmer par nous-même dans un langage de programmation nouveau aurait été compliqué pour nous.

Nous avons décidé que les informations envoyées par communication Bluetooth serait sous forme hexadécimale. Le programme informatique du côté de l'ATMega16u2 recevra et traitera alors les informations reçues.

L'application devait avoir un aspect simple d'utilisation et sobre afin de faciliter l'expérience de l'utilisateur. L'application amènerait l'utilisateur sur une page permettant de choisir à quel appareil Bluetooth se connecter. Un statut indiquant si le smartphone est connecté ou non à l'appareil est aussi présent. L'élément le plus important de la page est le bloc de déplacement, composé de 4 boutons représentant des flèches directionnelles afin de piloter la voiture.

Lorsque nous avions terminé l'application pour piloter grâce à des flèches directionnelles, nous nous sommes rendu compte que nous pourrions réaliser aussi un pilotage par gyroscope. En effet, les informations transmises pour les déplacements restent les mêmes donc du côté du programme informatique, rien ne change. Nous avons deux moyens de piloter la voiture : une par appui sur des flèches directionnelles, et une seconde par inclinaison du smartphone.

Voilà des captures d'écran montrant l'aspect et les fonctionnalités de l'application :

Pour réaliser cette application, il faut du code en interne, voici les codes que nous avons utilisé :

Le fichier APK de l'application est disponible dans le GIT du projet.

Epreuve complémentaire CAZIN Némo

Lien du git : https://archives.plil.fr/ncazin/SE3_GROUPE_8.git

Introduction :

J’ai dû reprendre le projet lors de mon épreuve complémentaire de Semestre 6

Avant cela, avec mon groupe de travail, nous avions réussi à faire clignoter une LED malgré tous les problèmes que nous avions rencontrés comme des composants qui ne fonctionnait plus sur la carte ou alors des courts-circuits à faire nous-mêmes. Je ne traiterais donc pas ici la partie du clignotement de la LED.

Préparation de la carte électronique :

Tout d’abord, lorsque j’ai repris le projet, je savais que les soudures des composants et du moteur continu avaient été faites, mais elles étaient fragiles du fait de la petite épaisseur des pistes reliant le moteur au driver. De plus, le voyage de la boite avec la carte électronique à l’intérieur avait complétement cassé les soudures du moteur.

Voici l’état de la carte lors de la reprise du projet :

Carte avec le moteur désoudé
Carte avec le moteur désoudé

J’ai donc dû refaire les soudures du moteur, ce qui a été un peu compliqué, car j’ai du mal à souder en général. Mais en m’inspirant des photos que j’avais d’avant la reprise du projet, j’ai pu mieux m’en sortir. Voilà le résultat de la soudure du moteur continu :

Carte avec le moteur continu soudé
Carte avec le moteur continu soudé

Après cela, j’ai voulu continuer mon travail en faisant les soudures du moteur pas-à-pas. Ce moteur est très petit et les soudures à faire devaient être très précises. Pour que ce soit plus simple, j’ai utilisé 4 pins que j’ai soudé à la carte et sur les pins, des câbles sont reliés jusqu’aux quatre liaisons du moteur. Le moteur est alors déporté de la carte, mais ce n’est pas très important, car on veut juste le voir fonctionner et aucune roue n’est attachée. Ces soudures étaient vraiment compliquées à réaliser, car elles étaient très minutieuses à réaliser et souvent des soudures se cassaient lorsque j’en soudais une autre.

Voilà le résultat de la soudure du moteur pas à pas :

Carte avec le moteur pas-à-pas soudé
Carte avec le moteur pas-à-pas soudé

Après avoir soudé tous les composants que je souhaitais, j'ai vérifié les anciennes soudures pour voir s'il n'y avait pas des câbles qui étaient cassés à cause du voyage. Après vérification, tout était bon et je pouvais commencer la programmation.

Problèmes eu pendant la programmation de la carte sur ordinateur :

J'ai rencontré plusieurs problèmes lors de la programmation et lors de la reconnaissance de la carte par les machines.

Tout d'abord, il faut savoir que j'ai commencé développer mes programmes informatiques sur les machines de l’école à distance grâce à l’outil : https://tp-info.polytech-lille.fr/#

Ensuite, le premier problème était que certaines bibliothèques utilisées, notamment <avr/io.h> ne sont pas trouvables, ce qui fait que la compilation d'un de mes fichiers de test ne peut pas être réalisée. J'ai comme hypothèse que soit la librairie n'est pas installée sur les machines des salles de TP en C10X, soit il faut être en superutilisateur pour pouvoir compiler le fichier d'après les notes que j'ai des cours. Je ne peux pas me mettre en superutilisateur car il faut le mot de passe de la machine locale que je ne connais pas. Pour contourner ce problème, j'ai défini comme constantes toutes les variables utilisées mais ce n'est qu'une solution temporaire qui ne marchera peut-être pas lors de l'envoi du programme sur la carte, mais au moins j'ai réussi à compiler mes fichiers.

Message de l'erreur reçu par rapport à la librairie <avr/io.h>
Message de l'erreur reçu par rapport à la librairie <avr/io.h>


Enfin, pour le second problème, j’ai voulu voir si la carte était reconnue depuis les machines à distance grâce à la commande shell « lsusb ». Cependant, lorsque je me connecte sur ces machines, les périphériques USB de mon ordinateur ne sont pas reconnus. En faisant plusieurs essais pour résoudre ce problème, j’ai compris que ce n’était pas possible et donc qu’il fallait passer par une autre méthode. Sois-je faisais directement la programmation sur Windows, mais télécharger les dépendances et le compilateur C était compliqué. Sois-je téléchargeais une machine virtuelle Ubuntu pour être directement sur un système Linux et plus simplement programmer. J’ai donc choisi la première option, car je craignais que la machine virtuelle ne reconnaisse pas elle aussi les périphériques USB.

J’ai donc modifié l’option développeur de mon Windows afin de pouvoir télécharger un environnement terminal Ubuntu qui fonctionne grâce à Windows Subsystem for Linux (WSL). J’ai alors rencontré une erreur lors du lancement du terminal Ubuntu :

Erreur WSL pour Ubuntu
Erreur WSL pour Ubuntu

J’ai alors trouvé une documentation de Microsoft sur le WSL qui m’a permis de résoudre ce problème (https://learn.microsoft.com/fr-fr/windows/wsl/troubleshooting). Après cela, j’ai voulu donc tester la commande « lsusb » mais encore une fois, une nouvelle erreur apparaît :

Erreur de la libusb sur Ubuntu
Erreur de la libusb sur Ubuntu

J’ai donc télécharger la librairie libusb grâce à la commande « sudo apt-get install libusb-1.0-0-dev » que j’ai trouvé grâce aux informations de ce site : https://askubuntu.com/questions/629619/how-to-install-libusb , mais même en faisant cette commande, j’ai toujours eu la même erreur. Donc à ce stade du projet, cette solution n'était pas viable et devait être plus approfondie.

En parallèle, j'ai essayé d'installer une machine virtuelle Ubuntu sur mon ordinateur, mais Oracle VM VirtualBox n'accepte que les fichiers .xml alors que je me suis procuré un fichier .iso. Après avoir téléchargé le bon fichier, j'ai dû faire la manipulation de la première méthode pour me retrouver avec la même erreur de la libusb.

Après des essais directement réalisés sur les machines de l'école, j'ai remarqué que le microprocesseur n'était pas reconnu. Il doit y avoir donc une soudure ou une connexion qui a dû se casser, ou alors le microprocesseur qui ne fonctionne plus comme nous l'avions déjà eu au début du projet.

Programmation du moteur continu :

J’ai donc commencé par la partie du moteur continu, car c’est sur cette partie que nous nous sommes arrêtés.

Afin de faire fonctionner le moteur, je devais faire un programme informatique afin de gérer cette fonctionnalité. J’ai tout d’abord créé une fonction pour initialiser les ports du moteur comme étant des sorties. Ensuite, j’ai créé une fonction « avancer » où je mets un des ports sous tension et l’autre non. Pour la fonction « reculer », il s’agit de la même chose mais il faut inverser quel port est sous tension. Enfin pour la fonction « arrêter », il suffit de mettre les deux ports à 0.

Voici donc le code pour faire fonctionner le moteur de cette façon :

//////////////////////////////////////////
/// INITIALISATION MOTEUR DC AVEC PORT ///
//////////////////////////////////////////
    
void initMotDC_Port(void){
    DDRB |= (1<<PB7);                   //PMW2 en OUTPUT
    DDRD |= (1<<PD0);                   //PMW1 en OUTPUT
    PORTB=(0<<PB7);                     //PMW2 à LOW
    PORTD=(0<<PD0);                     //PMW1 à LOW
}

////////////////////////////////////
/// CONTROLE MOTEUR DC AVEC PORT ///
////////////////////////////////////

void move_forwards(void){
    PORTB=(1<<PB7); //MOT1 à HIGH
    PORTD=(0<<PD0); //MOT2 à LOW
}

void move_backwards(void){
    PORTB=(0<<PB7); //MOT1 à LOW
    PORTD=(1<<PD0); //MOT2 à HIGH
}

void stop(void){
    PORTB=(0<<PB7); //MOT1 à LOW
    PORTD=(0<<PD0); //MOT2 à LOW   
}

Après avoir fait cela, je me suis demandé si nous pouvions contrôler la vitesse du moteur. J’ai alors regardé trouver une page d’un cours de PSE (https://rex.plil.fr/Enseignement/Systeme/Systeme.PSE/systeme053.html) expliquant comment fonctionne les actionneurs simples grâce aux signaux PWM (Pulse Width Modulation). Une partie du programme pour l’initialisation des ports était donnée, cependant, il s’agissait de la gestion des sorties que je ne comprenais pas (OCR0A, OCR0B …), j’ai donc dû effectuer plusieurs recherches sur cette partie. Voici donc le code pour faire fonctionner le moteur de cette autre façon :

//////////////////////////////////////////
/// INITIALISATION MOTEUR DC AVEC OCR1 ///
//////////////////////////////////////////

void initMotDC_OCR(void){
    DDRB |= (1<<PB7);                   //PMW2 en OUTPUT
    DDRD |= (1<<PD0);                   //PMW1 en OUTPUT
    TCCR1A |= (1<<COM1A1)|(1<<COM1C1);  // Les ports PWM se comportent normalement
    TCCR1A |= (1<<WGM11)|(1<<WGM10);    // Minuteur mis en mode PWM
    TCCR1B |= (1<<CS10);                // Pas de pré-diviseur, démarre le compteur

///////////////////////////////////
/// CONTROLE MOTEUR DC AVEC OCR ///
///////////////////////////////////

void move_forwards_OCR(void){
    OCR1A = 512;
    OCR1C = 0;
}

void move_backwards_OCR(void){
    OCR1A = 0;
    OCR1C = 512;
}

void stop_OCR(void){
    OCR1A = 0;
    OCR1C = 0;   
}

Programmation du moteur pas à pas :

Comme je n'avais jamais travaillé sur un moteur pas à pas, j'ai voulu comprendre son fonctionnement. Après plusieurs recherches, j'ai compris que le moteur était constitué d'un rotor magnétique et de bobines. Nous avons ici un moteur pas à pas bipolaire, avec 4 sorties. Le moteur fonctionne par pas successifs comme une montre, ce qui signifie qu'il faut jouer avec chacune des sorties afin de le faire tourner pas par pas. En partant de ce principe, nous pouvons programmer une fonction pour que chaque sortie soit sous tension les unes à la suite des autres.

Voici le programme pour faire tourner le moteur pas à pas dans un sens :

///////////////////////////////////////
/// INITIALISATION MOTEUR PAS A PAS ///
///////////////////////////////////////

void initMotStepper(void){
    DDRC |= (1<<PC4);
    DDRC |= (1<<PC5);
    DDRC |= (1<<PC6);
    DDRC |= (1<<PC7);
}

/////////////////////////////////
/// CONTROLE MOTEUR PAS A PAS ///
/////////////////////////////////
    
void stepper_left(void){
    for(int i = 0; i<=100; i++){
        //M1_A+ à 1 puis 0
        PORTC=(1<<PC7);
        _delay_ms(5);
        PORTC=(0<<PC7);
        
        //M1_B- à 1 puis 0
        PORTC=(1<<PC4);
        _delay_ms(5);
        PORTC=(0<<PC4);
        
        //M1_A- à 1 puis 0
        PORTC=(1<<PC6);
        _delay_ms(5);
        PORTC=(0<<PC6);
        
        //M1_B+ à 1 puis 0
        PORTC=(1<<PC5);
        _delay_ms(5);
        PORTC=(0<<PC5);
    }
}

Pour aller dans l'autre sens, il suffit d'inverser le sens des broches des sorties :

void stepper_right(void){
    for(int i = 0; i<=100; i++){
        //M1_B+ à 1 puis 0
        PORTC=(1<<PC5);
        _delay_ms(5);
        PORTC=(0<<PC5);
        
        //M1_A- à 1 puis 0
        PORTC=(1<<PC6);
        _delay_ms(5);
        PORTC=(0<<PC6);
        
        //M1_B- à 1 puis 0
        PORTC=(1<<PC4);
        _delay_ms(5);
        PORTC=(0<<PC4);
        
        //M1_A+ à 1 puis 0
        PORTC=(1<<PC7);
        _delay_ms(5);
        PORTC=(0<<PC7);
    }
}

Voici ma documentation :

- https://www.tme.eu/fr/news/library-articles/page/41861/Moteur-pas-a-pas-types-et-exemples-dapplications-des-moteurs-pas-a-pas/

- https://www.youtube.com/watch?v=655p1N9tSKQ

- http://www.micropython.fr/modules_center/moteurs/pas_a_pas/moteur_pap/#le-principe-dun-moteur-pas-a-pas

Programmation de la communication Bluetooth :

La partie Bluetooth était un de nos objectifs du début de projet afin de contrôler la voiture à distance et grâce à une application. Pour cela, j’ai dû refaire des recherches sur le sujet afin de mieux comprendre comment je pourrai faire. J’ai donc dû regarder la documentation de l’atmega16u2 et des cours en ligne d’autres universités pour bien comprendre. C’est alors que j’ai compris que la communication série UART permettrait de répondre à mes besoins. J’ai donc écrit une fonction qui permet l’initialisation de la communication série UART en activant la transmission (TX) et la réception (RX). Ensuite, dans cette même fonction, j’ai dû définir le format de la trame, elle est donc composée de 8 bits, c’est-à-dire un octet avec un bit d’arrêt.

Nous n’avons besoin que de recevoir des informations sur la communication série UART, pas d’en envoyer. C’est pour cela que j’ai donc dû faire une seconde fonction permettant de recevoir les informations de l’application sur le port RX de l’Atmega16u2.

Voici le code de la communication UART :

/////////////////////////////////////////
/// INITIALISATION COMMUNICATION UART ///
/////////////////////////////////////////

void UART_init(unsigned int baud_rate){
    // Calculer la valeur de UBRR en fonction du baud_rate
    unsigned int ubrr_val = FREQ_CPU / (16UL * baud_rate) - 1;    
    // Définir les valeurs UBRRH et UBRRL
    UBRRH = (unsigned char)(ubrr_val >> 8);
    UBRRL = (unsigned char)ubrr_val;
    // Activer la transmission et la réception
    UCSRB = (1 << TXEN) | (1 << RXEN);
    // Définir le format de trame: 8 bits de données, 1 bit d'arrêt
    UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
}

/////////////////////////////////////
/// RECUPERATION DES DONNEES UART ///
/////////////////////////////////////

int UART_receiver(void) {
    // Attendre que le tampon d'entrée soit plein
    while (!(UCSRA & (1 << RXC)));
    // Lire le caractère du tampon d'entrée
    return UDR;
}

Cette fonction ne pouvait pas être testée, car l’antenne Bluetooth n’est pas présente sur la carte électronique de la voiture. Cependant, ces recherches m’ont permis de mieux comprendre la communication série UART que j’avais mal comprise lors des TP du semestre 6.

Programmation USB/LUFA

Pour cette partie de la programmation via USB/LUFA, j’ai repris le fichier utilisé lors de notre cours de TPI. Ce fichier avait quelques modifications à faire avant d’être utilisé. Tout d’abord, j’ai dû changer les Vendor ID et Product ID de la carte électronique, car celles utilisées maintenant n’est pas la même que pendant le cours de TPI. Normalement grâce à la commande "lsusb -vvv", on peut trouver le microcontrôleur utilisé et ces ID, mais nous les avions déjà noté auparavant. On trouve alors :

-       VENDOR ID : 0x03EB  

-       PRODUCT ID : 0x2FEF

Ensuite, des modifications étaient à faire sur les fichiers du descripteur. En effet, celui-ci avait du code qui faisait référence au joystick utilisé en TPI. J’ai donc juste gardé les fonctions qui faisaient référence aux actionneurs.

De plus, afin de pouvoir gérer les actionneurs, j’ai préparé en amont comment ils seront activés grâce aux octets à envoyer. Cependant, j’ai décidé d’utiliser qu’un seul octet de contrôle, car 2 était beaucoup trop pour les simples fonctions que nous avions. Nous avons alors un seul octet ayant chaque bit qui représente une fonction de contrôle de la voiture avec de droite à gauche :

-       Bit 0 : Allume la LED

-       Bit 1 : Fait avancer la voiture

-       Bit 2 : Fait reculer la voiture

-       Bit 3 : Fait tourner dans un sens la voiture

-       Bit 4 : Fait tourner dans l’autre sens la voiture

Par exemple, le schéma ci-dessous permet d’allumer la LED de la voiture, de la faire reculer, et en même temps de la faire tourner dans un sens :

Exemple d'octet
Exemple d'octet

Voici d'ailleurs le code du programme traitant chaque bit de l'octet pour exécuter les fonctions voulues :

void actionneurs_gestion(void){
	Endpoint_SelectEndpoint(ACT_EPADDR);
	if (Endpoint_IsOUTReceived()){
		if (Endpoint_IsReadWriteAllowed()){
		  	uint16_t ACT_Report = Endpoint_Read_16_LE();

            //CONTROLE DES LEDS
            if(ACT_Report & (1<<0))
                led_on();
            else 
                led_off();
        
			//CONTROLE DU MOTEUR DC
			if(ACT_Report & (1<<1))
                move_forwards();
            else if(ACT_Report & (1<<2))
                move_backwards();	
			else
                stop();
            
            //CONTROLE DU MOTEUR PAS A PAS
            if(ACT_Report & (1<<3))
                stepper_left();
            else if(ACT_Report & (1<<4))
                stepper_right();
		}
		/* Handshake the OUT Endpoint - clear endpoint and ready for next report */
		Endpoint_ClearOUT();
	}
}

Enfin, nous avons juste à envoyer l’octet de notre choix afin de gérer comme on veut les actionneurs.

En retravaillant sur cette partie, j’ai mieux compris le fonctionnement de la libusb que je n’avais pas beaucoup compris lors du cours de TPI. J’ai pu me documenter sur le sujet en faisant beaucoup de recherche, et même d’apprendre des nouvelles façons de travailler avec le langage C et d’avoir une meilleure syntaxe de programmation.

Conclusion de mon travail durant l'épreuve complémentaire :

J'ai rencontré beaucoup de problèmes durant cette épreuve complémentaire. J'en ai résolu la plupart, mais certains étaient beaucoup trop compliqués et m'ont fait passer beaucoup de temps dessus. Il fallait donc que je m'organise pour ne pas passer tout le projet à résoudre certains problèmes et mettre de côté le nécessaire.

Principalement, je trouve que je me suis bien débrouillé. J'ai surtout pu me remettre à jour en programmation du langage C et sur la libusb. J'ai pu aussi améliorer mes compétences en soudure et en gestion de projet. Mais surtout, j'ai dû faire beaucoup de recherches pour bien comprendre certains aspects qui étaient nécessaires. En général, j'ai beaucoup appris durant cette épreuve et j'ai pu mettre en avant ma détermination à finir le projet.