You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
9.6 KiB
Arduino

// lineFollowerBot.ino
// Programme basique permettant à un robot de suivre une ligne dessinée au sol.
//
// Un projet du hackerspace Ventres Mous.
// =============================================================================
//
// IDENTIFICATION DES BROCHES DE LARDUINO UTILISÉES PAR LE PROJET
//
// =============================================================================
// Chaque broche de lArduino est identifiée par un numéro. Afin de faciliter
// la lecture du code, on leur donne des noms parlants.
// Broches sur lesquelles les moteurs sont connectés.
// Ce sont des broches de sortie numériques.
#define MOTEUR_GAUCHE 2
5 years ago
#define MOTEUR_DROITE 8
// Broches sur lesquelles les capteurs sont connectés.
// Ce sont des broches de lecture analogique.
#define CAPTEUR_GAUCHE A0
#define CAPTEUR_DROITE A1
// Broches sur lesquelles les leds de suivi détalonnage sont connectées.
// Ce sont des broches de sortie numériques.
#define ETALONNAGE_LED_GAUCHE 4
#define ETALONNAGE_LED_DROITE 5
// Broche sur laquelle le bouton détalonnage est connecté.
// Cest une broche de lecture numérique.
#define ETALONNAGE_BOUTON 12
// Les 2 états possible du bouton détalonnage : pressé et relevé.
#define BOUTON_PRESSE 1
#define BOUTON_RELEVE 0
5 years ago
// Variables utilisées pour définir les seuils de détection des capteurs. Les
// seuils sont réglés à 200 par défaut.
int seuil_gauche = 200;
int seuil_droite = 200;
// =============================================================================
//
// INITIALISATION DES BROCHES DE LARDUINO
//
// =============================================================================
// Cette fonction est exécutée une seule fois lors de lallumage de lArduino.
// Son rôle consiste à configurer lArduino pour un usage précis, dans le cas
// présent pour un robot suiveur de ligne.
void setup() {
// Configure les broches des moteurs en sortie numérique. Ces broches seront
// soit à 0 volt, soit à 5 volts. Les broches de lArduino ne sont pas faites
// pour alimenter un moteur, elles serviront à piloter des transistors qui,
// eux, alimenteront les moteurs.
pinMode(MOTEUR_GAUCHE, OUTPUT);
pinMode(MOTEUR_DROITE, OUTPUT);
// Configure les broches des leds de suivi détalonnage en sortie numérique.
// Les leds consomment très peu dénergie, elles seront directement pilotées
// par les broches de lArduino.
pinMode(ETALONNAGE_LED_GAUCHE, OUTPUT);
pinMode(ETALONNAGE_LED_DROITE, OUTPUT);
// Configure la broche du bouton détalonnage en entrée numérique.
pinMode(ETALONNAGE_BOUTON, INPUT);
// Les broches analogiques des capteurs sont obligatoirement en mode lecture
// analogique. Il ny a donc pas de réglage à faire sur ces broches.
5 years ago
Serial.begin(9600);
}
5 years ago
// =============================================================================
//
// GESTION DU BOUTON DÉTALONNAGE
//
// =============================================================================
5 years ago
// Attend jusquà ce que le bouton détalonnage soit enfoncé ou relaché.
// Le paramètre etat peut prendre 2 valeurs : BOUTON_PRESSE et BOUTON_RELEVE.
// Si la fonction est appelée avec BOUTON_PRESSE, elle ne laissera le programme
// continuer que si le bouton est enfoncé. Si elle est appelée avec
// BOUTON_RELEVE, elle ne laissera le programme continuer que si le bouton est
// relevé.
void continuer_si(int etat) {
while(digitalRead(ETALONNAGE_BOUTON) != etat) delay(1);
}
5 years ago
// =============================================================================
//
// GESTION DES LEDS DÉTALONNAGE
//
// =============================================================================
// Fait clignoter les leds détalonnage pour indiquer à lutilisateur que
// létalonnage est terminé.
void clignoter() {
// Fait clignoter 5 fois les leds. Clignoter consiste à allumer puis éteindre.
for(int b = 0; b < 5; b++) {
// Allume les leds détalonnage (les broches sont réglées à 5 volts).
digitalWrite(ETALONNAGE_LED_GAUCHE, HIGH);
digitalWrite(ETALONNAGE_LED_DROITE, HIGH);
// Attend 0,2 secondes (200 millisecondes).
delay(200);
// Éteint les leds détalonnage (les broches sont réglées à 0 volt).
digitalWrite(ETALONNAGE_LED_GAUCHE, LOW);
digitalWrite(ETALONNAGE_LED_DROITE, LOW);
// Attend 0,2 secondes (200 millisecondes).
delay(200);
}
}
5 years ago
// Éteint les deux leds détalonnage.
void eteindre() {
// Éteint les 2 leds de débogage en mettant leurs broches à 0 volt.
digitalWrite(ETALONNAGE_LED_GAUCHE, LOW);
digitalWrite(ETALONNAGE_LED_DROITE, LOW);
}
5 years ago
// =============================================================================
//
// ÉTALONNAGE DES CAPTEURS DU ROBOT
//
// =============================================================================
// Étalonne les capteurs pour établir la différence entre la ligne et le sol.
void etalonnage() {
// Variables qui vont recevoir les valeurs minimales et maximales des capteurs
// gauche et droite (Lunité importe peu). Elles permettent de garder en
// mémoire létat du capteur afin de pouvoir effectuer des calculs plus tard.
int min_gauche;
int min_droite;
int max_gauche;
int max_droite;
// Arrête les 2 moteurs, le robot ne bouge plus.
moteur_arret();
// Létalonnage est déclenché quand lutilisateur appuie sur le bouton
// détalonnage. On attend que le bouton soit relaché pour étalonner.
continuer_si(BOUTON_RELEVE);
5 years ago
Serial.println("BOUTON_RELEVE");
// Lit létat des deux capteurs.
min_gauche = analogRead(CAPTEUR_GAUCHE);
min_droite = analogRead(CAPTEUR_DROITE);
// Éteint les deux leds détalonnage.
eteindre();
// Attend que lutilisateur clique sur le bouton (clic = appui + relache).
continuer_si(BOUTON_PRESSE);
continuer_si(BOUTON_RELEVE);
5 years ago
Serial.println("BOUTON_PRESSE_RELEVE");
// Lit létat des deux capteurs.
max_gauche = analogRead(CAPTEUR_GAUCHE);
max_droite = analogRead(CAPTEUR_DROITE);
// Le seuil correspond à la valeur située entre les valeurs minimales et
// maximales que le capteur retourne.
seuil_gauche = (min_gauche + max_gauche) / 2;
seuil_droite = (min_droite + max_droite) / 2;
5 years ago
Serial.println("FIN_ETALONNAGE");
clignoter();
}
5 years ago
// =============================================================================
//
// GESTION DES DEUX MOTEURS
//
// =============================================================================
5 years ago
// Arrête les deux moteurs. Le robot ne bouge plus.
void moteur_arret() {
5 years ago
Serial.println("ARRET_MOTEUR");
digitalWrite(MOTEUR_GAUCHE, LOW);
digitalWrite(MOTEUR_DROITE, LOW);
}
5 years ago
// Fait tourner le robot à droite.
void moteur_droite() {
// Pour tourner à droite, on bloque le côté droit et on fait avancer le côté
// gauche.
5 years ago
Serial.println("MOTEUR_DROITE");
digitalWrite(MOTEUR_GAUCHE,HIGH);
digitalWrite(MOTEUR_DROITE,LOW);
5 years ago
}
// Fait tourner le robot à gauche.
void moteur_gauche() {
// Pour tourner à gauche, on bloque le côté gauche et on fait avancer le côté
// droit.
5 years ago
Serial.println("MOTEUR_GAUCHE");
digitalWrite(MOTEUR_GAUCHE, LOW);
digitalWrite(MOTEUR_DROITE, HIGH);
}
5 years ago
// Fait tourner les deux moteurs. Le robot avance.
void moteur_avance() {
5 years ago
Serial.println("MOTEUR_AVANCE");
digitalWrite(MOTEUR_GAUCHE, HIGH);
digitalWrite(MOTEUR_DROITE, HIGH);
}
5 years ago
// =============================================================================
//
// BOUCLE PRINCIPALE
//
// =============================================================================
// La fonction loop est appelée en boucle par lArduino. Un Arduino est prévu
// pour ce genre de tâche : exclusive et répétitive.
// Le programme considère que le robot démarre la ligne entre les deux capteurs.
void loop() {
// Variables qui vont recevoir les valeurs des capteurs.
int valeur_gauche;
int valeur_droite;
// Si le bouton détalonnage est pressé, on lance létalonnage.
if(digitalRead(ETALONNAGE_BOUTON) == 1) etalonnage();
// Lit létat des deux capteurs.
valeur_gauche = analogRead(CAPTEUR_GAUCHE);
valeur_droite = analogRead(CAPTEUR_DROITE);
// Fait avancer le robot si les deux capteurs identifient le sol.
if((valeur_gauche < seuil_gauche) && (valeur_droite < seuil_droite)) {
moteur_avance();
return;
5 years ago
}
// Tourne à droite si le capteur de gauche identifie le sol et le capteur de
// droite identifie la ligne. Cela veut dire que le robot dévie à gauche par
// rapport à la ligne quil doit suivre. On corrige en tournant à droite
// jusquà ce que la ligne soit à nouveau entre les deux capteurs.
if((valeur_gauche < seuil_gauche) && (valeur_droite > seuil_droite)) {
moteur_droite();
5 years ago
// Attend que le capteur de droite identifie le sol.
while(analogRead(CAPTEUR_DROITE) > seuil_droite) delay(1);
return;
5 years ago
}
// Tourne à gauche si le capteur de gauche identifie la ligne et le capteur de
// droite identifie le sol. Cela veut dire que le robot dévie à droite par
// rapport à la ligne quil doit suivre. On corrige en tournant à gauche
// jusquà ce que la ligne soit à nouveau entre les deux capteurs.
if((valeur_gauche > seuil_gauche) && (valeur_droite < seuil_droite)) {
moteur_gauche();
// Attend que le capteur de gauche identifie le sol.
while(analogRead(CAPTEUR_GAUCHE) > seuil_gauche) delay(1);
return;
5 years ago
}
// Arrête le robot si les deux capteurs identifient chacun le sol. Cela veut
// dire que le robot a perdu la ligne, il est plus prudent de larrêter.
if((valeur_gauche > seuil_gauche) && (valeur_droite > seuil_droite)) {
moteur_arret();
return;
5 years ago
}
}