SE3Binome2022-5
Présentation du projet
Objectif
Concevoir un modèle de voiture 1:43 équipée d'un microcontrôleur ATMega16u2 permettant de commander la voiture en se basant sur un programme. Nous avons choisi de rajouter une option de suivi d'une ligne droite, ceci se fera à l'aide d'un capteur QRE1113gr.
Composants
les composants à utiliser dans notre projet sont les suivants :
- Un microcontrôleur ATMega16u2
- Un capteur QRE1113gr
- Un mini-moteur à courant continu
- Un pilote du mini-moteur à courant continu (DRV8210DRLR)
- Un micro-moteur glissière pas à pas
- Une batterie LiPo
- Une puce de contrôle de charge de la batterie (MAX1811)
- Des leds pour simuler le système d'éclairage
- Des résistances
- Des capacités
- Un quartz
- Un port USB
- Des diodes
- Un AVR-ISP 6
- Des connecteurs
Caractéristiques et limites de notre système
caractéristiques
Pour comprendre le fonctionnement de suivi de ligne souhaité, il faut d'abord comprendre le fonctionnement du capteur QRE. C'est un capteur de réflexion infrarouge, il est utilisé pour détecter la présence ou l'absence d'objets réfléchissants à proximité. Il se compose d'une LED infrarouge émettant de la lumière infrarouge et d'un phototransistor qui mesure la quantité de lumière réfléchie. Lorsqu'un objet se trouve devant le capteur, il réfléchit la lumière infrarouge émise par la LED vers le phototransistor. Le phototransistor détecte cette lumière réfléchie et génère un courant proportionnel à son intensité. La valeur mesurée par le capteur dépend de la quantité de lumière infrarouge réfléchie par l'objet. Si l'objet est réfléchissant et renvoie une grande quantité de lumière infrarouge, le phototransistor générera un courant plus élevé, ce qui se traduira par une valeur positive lorsqu'elle est lue par le microcontrôleur. En revanche, si aucun objet réfléchissant n'est présent devant le capteur, la quantité de lumière infrarouge réfléchie sera faible. Par conséquent, le phototransistor générera un courant plus faible ou nul, ce qui se traduira par une valeur de capteur égale à zéro lorsqu'elle est lue par le microcontrôleur.
Limites
Les composants cités ci-dessus étaient soudés et utilisés dans notre carte, sauf la batterie et sa puce de contrôle, les diodes, l'AVR-ISP et les connecteurs.
Pour réinitialiser le microprocesseur afin de mettre un nouveau code, il faut à chaque fois utiliser un fil entre la masse et la broche de reset du AVR-ISP. Le rajout d'un bouton aurait était mieux.
Lors du routage de la carte, nous n'avons pas fait attention que le capteur doit être placé en bas, afin de détecter la ligne.
Après avoir fini le code pour tester le mini-moteur dc, nous nous rendons compte que le microprocessur n'est plus détectable en utilisant la commande lsusb. Nous avons vérifié les connections, essayé de changer le port usb mais sans résultat (pourtant que les leds et le capteur marchait bien). Nous avons alors tester le code sur la carte du groupe 2 en ajustant un peu la structure et en supprimant les parties correspondantes au capteur.
Avancement du projet
le 14/02 :
- Compréhension de l'idée directrice du projet
- Recherche de l'option à rajouter
le 28/02 :
- Début de conception de la schématique
le 21/03 :
- début du rajout des empreintes des composants
le 07/04 :
- Fin de la schématique
le 13/04 :
- Fin du routage de la carte
- Envoi du modèle aux enseignants pour le valider et commander la carte
le 02/05:
- Réception de la carte
- Soudure de quelques résistances et capacités
le 09/05:
- Les composants suivants sont déjà soudés par l'enseignant : ATMega16u2, le quartz
- Rajout des leds et des résistances restantes
- Début du code pour tester les leds
le 16/05:
- Fin du code pour tester les leds
- Réorganisation de la schématique
le 23/05:
- Soudure du capteur
- Implémentation du code pour tester le capteur
- Soudure du mini-moteur dc
le 29/05:
- Soudure du micro-moteur pas à pas
- Implémentation du code pour tester le mini-moteur dc
le 03/06:
- Test du code de moteur sur la carte du groupe 2
GIT
le lien de notre archive GIT : https://archives.plil.fr/yelqasta/pse-g5.git
Conception de la carte électronique
Composants et empreintes créés
nous avons créer le symbole du pilote du moteur DC via Kicad :
Après avoir mesurer les dimensions du mini-moteur continu on a pu créer l'empreinte suivante :
schéma
Réalisation du schématique du PCB sur le logiciel KiCad :
lors de la phase de soudure, l'enseignant nous a mentionné que le schéma du capteur n'est pas bon. Nous avons pu corriger le problème avec l'aide de l'enseignant en se basant sur le schéma suivant : https://cdn.sparkfun.com/datasheets/Sensors/Proximity/QRE1113-Digital-Breakout-v11.pdf
Visual 3D
Routage de la carte
Carte imprimée
Carte en étape intermédiaire
Premier Test de la carte
Comme vous le voyez dessus, le microcontrôleur est détecté en utilisant la commande lsusb. Néanmoins, après avoir fini le code du mini-moteur dc, le microcontrôleur n'est plus détectable pour une raison inconnue.
Eclairage
Les leds marchent bien ce qui nous a permi de passer à l'étape suivante ( souder le capteur et le coder )
Capteur
Le capteur marche bien, puisqu'il permet aux leds de s'allumer s'il détecte quelque chose, et s'éteignent sinon.
Moteurs
Nous avons soudé le pilote du mini-moteur dc, le mini-moteur DC et le micro-moteur glissière pas à pas.
Vidéo du fonctionnement du mini-moteur dc
Comme indiqué, nous ne pouvions plus programmer le microprocesseur. Pour cela , nous avons testé notre code sur la carte du groupe 2 :
Voici le code utilisé pour tester le moteur sur la carte du groupe 2, il ne reste qu'à changer les pins pour convenir à leur structure :
#include "io.h"
#include <util/delay.h>
#define MAX_LED 4
#define PORTB_OUTPUT 0x50
#define PORTC_OUTPUT 0x84
#define PORTD_OUTPUT 0x01
unsigned char led1[] = {0x00, 0x80, 0x00}; // PC7
unsigned char led5[] = {0x40, 0x00, 0x00}; // PB6
unsigned char led6[] = {0x10, 0x00, 0x00}; // PB4
unsigned char led8[] = {0x00, 0x04, 0x00}; // PC2
unsigned char *leds[] = {led1, led5, led6, led8};
unsigned char qre1113gr[] = {0x01, 0x00, 0x00}; // PD0
#define PORTB_INPUT 0x00
#define PORTC_INPUT 0x00
#define PORTD_INPUT 0x00
void control_motor(int enable) {
// Set appropriate signals for motor control using DRV8210DRLR
if (enable) {
// Enable the motor in the desired direction (e.g., set appropriate motor pins high/low)
PORTC |= (1 << PC6); // Set PC6 high
PORTB &= ~(1 << PB7); // Set PB7 low
} else {
// Disable the motor (e.g., set all motor pins low)
PORTC &= ~(1 << PC6); // Set PC6 low
PORTB &= ~(1 << PB7); // Set PB7 low
}
}
unsigned char input_get(unsigned char *pin) {
unsigned char port_num = pin[0] >> 4; // Extract the port number from the pin value
unsigned char pin_num = pin[0] & 0x0F; // Extract the pin number from the pin value
switch (port_num) {
case 0: // PORTB
return (PINB >> pin_num) & 0x01;
case 1: // PORTC
return (PINC >> pin_num) & 0x01;
case 2: // PORTD
return (PIND >> pin_num) & 0x01;
default:
return 0; // Invalid port number
}
}
int main(void) {
unsigned char imasks[] = {PORTB_INPUT, PORTC_INPUT, PORTD_INPUT};
unsigned char pullup[] = {0x00, 0x00, 0x01};
inputs_init(imasks, pullup);
unsigned char omasks[] = {PORTB_OUTPUT, PORTC_OUTPUT, PORTD_OUTPUT};
outputs_init(omasks);
while (1) {
control_motor(1);
_delay_ms(300);
control_motor(0);
inputs_init(imasks, pullup);
}
return 0;
}
Voici le code final en se basant sur les mêmes fonctions utilisées ci-dessus :
#include "io.h"
#include <util/delay.h>
#define MAX_LED 4
#define PORTB_OUTPUT 0x50
#define PORTC_OUTPUT 0x84
#define PORTD_OUTPUT 0x01
unsigned char led1[] = {0x00, 0x80, 0x00}; // PC7
unsigned char led5[] = {0x40, 0x00, 0x00}; // PB6
unsigned char led6[] = {0x10, 0x00, 0x00}; // PB4
unsigned char led8[] = {0x00, 0x04, 0x00}; // PC2
unsigned char *leds[] = {led1, led5, led6, led8};
unsigned char qre1113gr[] = {0x01, 0x00, 0x00}; // PD0
#define PORTB_INPUT 0x00
#define PORTC_INPUT 0x00
#define PORTD_INPUT 0x00
void control_motor(int enable) {
// Set appropriate signals for motor control using DRV8210DRLR
if (enable) {
// Enable the motor in the desired direction (e.g., set appropriate motor pins high/low)
PORTC |= (1 << PC6); // Set PC6 high
PORTB &= ~(1 << PB7); // Set PB7 low
} else {
// Disable the motor (e.g., set all motor pins low)
PORTC &= ~(1 << PC6); // Set PC6 low
PORTB &= ~(1 << PB7); // Set PB7 low
}
}
// The motor here is running anti clock-wise
unsigned char input_get(unsigned char *pin) {
unsigned char port_num = pin[0] >> 4; // Extract the port number from the pin value
unsigned char pin_num = pin[0] & 0x0F; // Extract the pin number from the pin value
switch (port_num) {
case 0: // PORTB
return (PINB >> pin_num) & 0x01;
case 1: // PORTC
return (PINC >> pin_num) & 0x01;
case 2: // PORTD
return (PIND >> pin_num) & 0x01;
default:
return 0; // Invalid port number
}
}
int main(void) {
unsigned char imasks[] = {PORTB_INPUT, PORTC_INPUT, PORTD_INPUT};
unsigned char pullup[] = {0x00, 0x00, 0x01};
inputs_init(imasks, pullup);
unsigned char omasks[] = {PORTB_OUTPUT, PORTC_OUTPUT, PORTD_OUTPUT};
outputs_init(omasks);
while (1) {
// Get the value read by the sensor
unsigned char qre_value = input_get(qre1113gr);
if (qre_value > 0) {
// Infra-red light detected, set everything on
output_set(leds, 0);
output_set(leds, 1);
output_set(leds, 2);
output_set(leds, 3);
control_motor(1);
} else {
// Nothing detected, set everything off
output_unset(leds, 0);
output_unset(leds, 1);
output_unset(leds, 2);
output_unset(leds, 3);
control_motor(0);
}
inputs_init(imasks, pullup); // reset the values
}
return 0;
}
Conclusion
Nous avons appris beaucoup de nouvelles compétences, notamment la conception et le routage d'une carte électronique, la soudure des composants et la manipulation d'un capteur.
Nous aurions pu avancer sur la partie LUFA et micro-moteur glissière pas à pas si nous n'avons pas eu le problème de détection du microcontrôleur. La batterie aussi reste à faire.