Voiture automate suiveur de ligne

Bonjour ou bonsoir à tout le monde, je suis nouveau sur Arduino et en ce moment je fais un projet sur une voiture automate suiveur de ligne. Comme je débute (pas beaucoup de connaissances niveau programmation) j’ai essayé de faire quelque chose sur le logiciel Arduino. Le voici :

/*
Programme voiture automate
La voiture suit une ligne, quand elle rencontre un obstacle (qui est détecté par un capteur ultrason)
celle-ci la contourne automatiquement. Il n’y a qu’un type d’obstacle.
J’ai deux capteurs de lignes, mais je ne sais pas comment faire pour que la voiture suive correctement les lignes.
La voiture ne peut pas reculer, on actionne le moteur à l’aide d’un transistor (c’est un moteur à courant continu)
Pour changer de direction, on fait passer plus ou moins de courant dans une bobine, ça fait bouger l’aimant qui est rélié à la direction
(d’ailleurs je sais changer le sens du courant avec le pont en H mais pas changer l’intensité du courant…). on peut néanmoins gérer l’intensité du courant. On fait les mesures avec les courants qui sortent d’Arduino.
*/

/constantes définissant par la suite les broches/

//En entrée
const boolean PIN_CAPTEUR_LIGNEG = 1;
const boolean PIN_CAPTEUR_LIGNED = 2;
const float PIN_CAPTEUR_ULTRASON = A1;
const boolean PIN_BOUTON_ONOFF = 4;

//En sortie
const boolean PIN_MOTEUR = 5;
const boolean PIN_PNP1 = 6;
const boolean PIN_PNP2 = 7;
const boolean PIN_NPN1 = 8;
const boolean PIN_NPN2 = 9;

// Constantes diverses du programme
//Vitesse du moteur
const int VITESSE_DU_MOTEUR_VIRAGE = 100;

//tempo tourner
const int TEMPO_TOURNER = 100;

//seuil de détection d’un obstacle
const float SEUIL_OBSTACLE = 200;

//Variables globales
boolean valeurcapteurligneg;
boolean valeurcapteurligned;
float valeurcapteurultrason;
boolean onoff;

// Fonction permettant de contourner l’obstacle
void Contourner()
{
Arretmoteur();
Moteurauralenti();
Tourneradroite();
delay(TEMPO_TOURNER);
Arretmoteur();
Tourneragauche();
Arretmoteur();
Tourneradroite();
}

//Fonction arret moteur
void Arretmoteur() // on bloque le transistor
{
int PIN_MOTEUR = 0;
int PIN_PNP1 = 0;
int PIN_PNP2 = 0;
int PIN_NPN1 = 0;
int PIN_NPN2 = 0;
}

//Fonction moteurauralenti
void Moteurauralenti() // on fait une modulation temporelle sur le transistor pour abaisser la tension aux bornes du moteur
{
int PIN_MOTEUR = 1;
int PIN_PNP1 = 0;
int PIN_PNP2 = 0;
int PIN_NPN1 = 0;
int PIN_NPN2 = 0;
}

// Fonction permettant de tourner à droite
void Tourneradroite() // nécessite un pont en H (pour gérer la vitesse et la direction
// on agit sur le sens et l’intensité du courant qui passe dans une bobine)
{
int PIN_MOTEUR = 1;
int PIN_PNP1 = 0;
int PIN_PNP2 = 1;
int PIN_NPN1 = 1;
int PIN_NPN2 = 0;
}

// Fonction permettant de tourner à gauche
void Tourneragauche() // nécessite un pont en H (pour gérer la vitesse et la direction
// on agit sur le sens et l’intensité du courant qui passe dans une bobine)
{
int PIN_MOTEUR = 1;
int PIN_PNP1 = 1;
int PIN_PNP2 = 0;
int PIN_NPN1 = 0;
int PIN_NPN2 = 1;
}

//Fonction avancer tout droit
void Avancertoutdroit() // on sature le transistor
{
int PIN_MOTEUR = 1;
int PIN_PNP1 = 1;
int PIN_PNP2 = 1;
int PIN_NPN1 = 1;
int PIN_NPN2 = 1;
}

// Fonction permettant de suivre la ligne
void Avancerligne()

{
int PIN_CAPTEUR_LIGNEG = HIGH;

if (1 == digitalRead (valeurcapteurligneg)) // si le capteur de gauche se met en état HIGH le robot doit se déplacer vers la droite
{

while (1 == valeurcapteurligned)

{
void Tourneradroite();
int PIN_MOTEUR = 1;
int PIN_PNP1 = 0;
int PIN_PNP2 = 1;
int PIN_NPN1 = 1;
int PIN_NPN2 = 0;
}

}

if (1 == digitalRead (valeurcapteurligned)) // si le capteur de droite se met en état HIGH le robot doit se déplacer vers la gauche

{

while (1 == valeurcapteurligneg)

{
void Tourneragauche();
int PIN_MOTEUR = 1;
int PIN_PNP1 = 1;
int PIN_PNP2 = 0;
int PIN_NPN1 = 0;
int PIN_NPN2 = 1;
}

}

else Avancertoutdroit();
int PIN_MOTEUR = 1;
int PIN_PNP1 = 1;
int PIN_PNP2 = 1;
int PIN_NPN1 = 1;
int PIN_NPN2 = 1;

}

// Fonction appelée une fois au démarrage
void setup()
{
// Initialiser le sens des broches
// En entrées
pinMode(PIN_CAPTEUR_LIGNEG, INPUT);
pinMode(PIN_CAPTEUR_LIGNED, INPUT);
pinMode(PIN_CAPTEUR_ULTRASON, INPUT);
pinMode(PIN_BOUTON_ONOFF, INPUT);

// En sorties
pinMode(PIN_MOTEUR, OUTPUT);
pinMode(PIN_PNP1, OUTPUT);
pinMode(PIN_PNP2, OUTPUT);
pinMode(PIN_NPN1, OUTPUT);
pinMode(PIN_NPN2, OUTPUT);
}

// Fonction appelée périodiquement
void loop()
{

onoff = digitalRead(PIN_BOUTON_ONOFF);
valeurcapteurligneg = digitalRead(PIN_CAPTEUR_LIGNEG);
valeurcapteurligned = digitalRead(PIN_CAPTEUR_LIGNED);
valeurcapteurultrason = analogRead(PIN_CAPTEUR_ULTRASON);

if( onoff == false )
{
// Le return fait quitter la fonction loop()
return;
}

// tant que le capteur d’obstacle ne détecte pas un obstacle à moins d’une certaine distance on a au choix:
while(valeurcapteurultrason<SEUIL_OBSTACLE)
{
Avancerligne();
}
if (valeurcapteurultrason>=SEUIL_OBSTACLE)
{
Contourner();
}
}

(il n'y avait plus de place) ça serait sympa si vous pouviez m'aider à trouver mes erreurs et merci d'avance pour votre aide.

Salut,

Primo : Il y a une chose qui faut pensé a amélioré c'est la syntaxe car avec des majuscules partout on s'y retrouve plus pour nous personne qui souhaite t'aider, essaye de simplifié et de raccourcir le nom de tes variables (bien sur libre a toi de la choisir).

Secondo : Pourqoui assigner la valeur "1" quand tu souhaite que le pont en H se met en marche ? C'est avec la fonction digitalWrite(x , HIGH);

Peut tu donner détaillé un peut plus d'info sur le matériel du robot ?

La voiture c'est une Nikko (US PAT No: 4.471.566), batterie de 9.6V, je travaille sur une carte Arduino Leonardo, 1 module suiveur de ligne Grove SEN21177P, 1 capteur ultrason (LV-MaxSonar-EZ2 Maxbotix) et j'améliorai la lecture du programme

Voici la version améliorée du programme (je pense :sweat_smile:)

/* Programme voiture automate La voiture suit une ligne, quand elle rencontre un obstacle (qui est détecté par un capteur ultrason) celle-ci la contourne automatiquement. Il n'y a qu'un type d'obstacle. J'ai deux capteurs de lignes, mais je ne sais pas comment faire pour que la voiture suive correctement les lignes. La voiture ne peut pas reculer, on actionne le moteur à l'aide d'un transistor (c'est un moteur à courant continu) Pour changer de direction, on fait passer plus ou moins de courant dans une bobine, ça fait bouger l'aimant qui est rélié à la direction (d'ailleurs je sais changer le sens du courant avec le pont en H mais pas changer l'intensité du courant...). on peut néanmoins gérer l'intensité du courant. On fait les mesures avec les courants qui sortent d'Arduino. */

/constantes définissant par la suite les broches/

//En entrée const boolean PIN_CAPTEUR_LIGNEG = 1; const boolean PIN_CAPTEUR_LIGNED = 2; const float PIN_CAPTEUR_ULTRASON = A1; const boolean PIN_BOUTON_ONOFF = 4;

//En sortie const boolean PIN_MOTEUR = 5; const boolean PIN_PNP1 = 6; const boolean PIN_PNP2 = 7; const boolean PIN_NPN1 = 8; const boolean PIN_NPN2 = 9;

// Constantes diverses du programme //Vitesse du moteur const int VITESSE_DU_MOTEUR_VIRAGE = 100;

//tempo tourner const int TEMPO_TOURNER = 100;

//seuil de détection d'un obstacle const float SEUIL_OBSTACLE = 200;

//Variables globales boolean valeurcapteurligneg; boolean valeurcapteurligned; float valeurcapteurultrason; boolean onoff;

// Fonction permettant de contourner l'obstacle void Contourner() { Arretmoteur(); Moteurauralenti(); Tourneradroite(); delay(TEMPO_TOURNER); Arretmoteur(); Tourneragauche(); Arretmoteur(); Tourneradroite(); }

//Fonction arret moteur void Arretmoteur() // on bloque le transistor { digitalWrite(PIN_MOTEUR, LOW); digitalWrite(PIN_PNP1, LOW); digitalWrite(PIN_PNP2, LOW); digitalWrite(PIN_NPN1, LOW); digitalWrite(PIN_NPN2, LOW); }

//Fonction moteurauralenti void Moteurauralenti() // on fait une modulation temporelle sur le transistor pour abaisser la tension aux bornes du moteur { digitalWrite(PIN_MOTEUR, HIGH); while(PIN_PNP1 == HIGH) // mettre PIN_PNP1 en LOW { digitalWrite(PIN_PNP1, LOW); delay(500) // attendre 500ms digitalWrite(PIN_PNP1, HIGH); delay(500) // attendre 500ms } digitalWrite(PIN_PNP2, HIGH); digitalWrite(PIN_NPN1, HIGH); digitalWrite(PIN_NPN2, HIGH); }

// Fonction permettant de tourner à droite void Tourneradroite() /* nécessite un pont en H (pour gérer la vitesse et la direction on agit sur le sens et l'intensité du courant qui passe dans une bobine) */ { digitalWrite(PIN_MOTEUR, HIGH); digitalWrite(PIN_PNP1, LOW); while(PIN_PNP2 == HIGH) // mettre PIN_PNP2 en LOW { digitalWrite(PIN_PNP2, LOW); delay(500) // attendre 500ms digitalWrite(PIN_PNP2, HIGH); delay(500) // attendre 500ms } while(PIN_NPN1 == HIGH) // mettre PIN_NPN1 en LOW { digitalWrite(PIN_NPN1, LOW); delay(500) // attendre 500ms digitalWrite(PIN_NPN1, HIGH); delay(500) // attendre 500ms } digitalWrite(PIN_NPN2, LOW); }

// Fonction permettant de tourner à gauche void Tourneragauche() /* nécessite un pont en H (pour gérer la vitesse et la direction on agit sur le sens et l'intensité du courant qui passe dans une bobine) */ { digitalWrite(PIN_MOTEUR, HIGH); while(PIN_PNP1 == HIGH) // mettre PIN_PNP1 en LOW { digitalWrite(PIN_PNP1, LOW); delay(500) // attendre 500ms digitalWrite(PIN_PNP1, HIGH); delay(500) // attendre 500ms } digitalWrite(PIN_PNP2, LOW); digitalWrite(PIN_NPN1, LOW); while(PIN_NPN2 == HIGH) // mettre PIN_NPN2 en LOW { digitalWrite(PIN_NPN2, LOW); delay(500) // attendre 500ms digitalWrite(PIN_NPN2, HIGH); delay(500) // attendre 500ms } }

//Fonction avancer tout droit void Avancertoutdroit() // on sature le transistor { digitalWrite(PIN_MOTEUR, HIGH); digitalWrite(PIN_PNP1, LOW); digitalWrite(PIN_PNP2, HIGH); digitalWrite(PIN_NPN1, HIGH); digitalWrite(PIN_NPN2, LOW); }

et la suite:

// Fonction permettant de suivre la ligne
void Avancerligne()
{
int PIN_CAPTEUR_LIGNEG = HIGH;
if (valeurcapteurligneg == HIGH ) // si le capteur de gauche se met en état HIGH le robot doit se déplacer vers la droite
{
while(valeurcapteurligned == 1)
{
void Tourneradroite()
{
digitalWrite(PIN_MOTEUR, HIGH);
digitalWrite(PIN_PNP1, LOW);
while(PIN_PNP2 == HIGH) // mettre PIN_PNP2 en LOW
{
digitalWrite(PIN_PNP2, LOW);
delay(500) // attendre 500ms
digitalWrite(PIN_PNP2, HIGH);
delay(500) // attendre 500 ms
}
while(PIN_NPN1 == HIGH) // mettre PIN_NPN1 en LOW
{
digitalWrite(PIN_NPN1, LOW);
delay(500) // attendre 500ms
digitalWrite(PIN_NPN1, HIGH);
delay(500) // attendre 500ms
}
digitalWrite(PIN_NPN2, LOW);
}
}
}
if (valeurcapteurligned == HIGH) // si le capteur de droite se met en état HIGH le robot doit se déplacer vers la gauche
{
while (valeurcapteurligned == 1)
{
void Tourneragauche()
{
digitalWrite(PIN_MOTEUR, HIGH);
while(PIN_PNP1 == HIGH) // mettre PIN_PNP1 en LOW
{
digitalWrite(PIN_PNP1, LOW);
delay(500) // attendre 500ms
digitalWrite(PIN_PNP1, HIGH);
delay(500) // attendre 500ms
}
digitalWrite(PIN_PNP2, LOW);
digitalWrite(PIN_NPN1, LOW);
while(PIN_NPN2 == HIGH) // mettre PIN_NPN2 en LOW
{
digitalWrite(PIN_NPN2, LOW);
delay(500) // attendre 500ms
digitalWrite(PIN_NPN2, HIGH);
delay(500) // attendre 500ms
}
}
else Avancertoutdroit()
{
digitalWrite(PIN_MOTEUR, HIGH);
digitalWrite(PIN_PNP1, LOW);
digitalWrite(PIN_PNP2, HIGH);
digitalWrite(PIN_NPN1, HIGH);
digitalWrite(PIN_NPN2, LOW);
}
}
}
}

// Fonction appelée une fois au démarrage
void setup()
{
// Initialiser le sens des broches
// En entrées
pinMode(PIN_CAPTEUR_LIGNEG, INPUT);
pinMode(PIN_CAPTEUR_LIGNED, INPUT);
pinMode(PIN_CAPTEUR_ULTRASON, INPUT);
pinMode(PIN_BOUTON_ONOFF, INPUT);

// En sorties
pinMode(PIN_MOTEUR, OUTPUT);
pinMode(PIN_PNP1, OUTPUT);
pinMode(PIN_PNP2, OUTPUT);
pinMode(PIN_NPN1, OUTPUT);
pinMode(PIN_NPN2, OUTPUT);
}

// Fonction appelée périodiquement
void loop()
{

onoff = digitalRead(PIN_BOUTON_ONOFF);
valeurcapteurligneg = digitalRead(PIN_CAPTEUR_LIGNEG);
valeurcapteurligned = digitalRead(PIN_CAPTEUR_LIGNED);
valeurcapteurultrason = analogRead(PIN_CAPTEUR_ULTRASON);

if( onoff == false )
{
// Le return fait quitter la fonction loop()
return;
}

// tant que le capteur d’obstacle ne détecte pas un obstacle à moins d’une certaine distance on a au choix:
while(valeurcapteurultrason<SEUIL_OBSTACLE)
{
Avancerligne();
}
if (valeurcapteurultrason>=SEUIL_OBSTACLE)
{
Contourner();
}
}

Il reste toujours des problème de syntaxe qui peuvent toujours nuire, sans parler de l'essentiel comme la gestion de la vitesse. Je t'invite a utiliser cette librairie qui te permettra d'alléger ton code et d'y voir un peut mieux : https://github.com/sudar/DCMotorBot

J'ai essayé de comprendre ce que tu m'as donné et voici ce que j'ai fait:

/* Programme voiture automate La voiture suit une ligne, quand elle rencontre un obstacle (qui est détecté par un capteur ultrason) celle-ci la contourne automatiquement. Il n'y a qu'un type d'obstacle. J'ai deux capteurs de lignes, mais je ne sais pas comment faire pour que la voiture suive correctement les lignes. La voiture ne peut pas reculer, on actionne le moteur à l'aide d'un transistor (c'est un moteur à courant continu) Pour changer de direction, on fait passer plus ou moins de courant dans une bobine, ça fait bouger l'aimant qui est rélié à la direction (d'ailleurs je sais changer le sens du courant avec le pont en H mais pas changer l'intensité du courant...). on peut néanmoins gérer l'intensité du courant. On fait les mesures avec les courants qui sortent d'Arduino. */

/constantes définissant par la suite les broches/

//En entrée const boolean PIN_CAPTEUR_LIGNEG = 1; const boolean PIN_CAPTEUR_LIGNED = 2; const float PIN_CAPTEUR_ULTRASON = A1; const boolean PIN_BOUTON_ONOFF = 4;

//En sortie const boolean PIN_MOTEUR = 5; const boolean PIN_PNP1 = 6; const boolean PIN_PNP2 = 7; const boolean PIN_NPN1 = 8; const boolean PIN_NPN2 = 9;

// Constantes diverses du programme //Vitesse du moteur const int VITESSE_DU_MOTEUR_VIRAGE = 100;

//tempo tourner const int TEMPO_TOURNER = 100;

//seuil de détection d'un obstacle const float SEUIL_OBSTACLE = 200;

//Variables globales boolean valeurcapteurligneg; boolean valeurcapteurligned; float valeurcapteurultrason; boolean onoff;

// Fonction permettant de contourner l'obstacle void Contourner() { Arretmoteur(); Moteurauralenti(); Tourneradroite(); delay(TEMPO_TOURNER); Arretmoteur(); Tourneragauche(); Arretmoteur(); Tourneradroite(); }

//Fonction arret moteur void Arretmoteur() // on bloque le transistor { digitalWrite(PIN_MOTEUR, LOW); }

//Fonction moteurauralenti void Moteurauralenti() // on fait une modulation temporelle sur le transistor pour abaisser la tension aux bornes du moteur { digitalWrite(PIN_MOTEUR, HIGH); delay(500) // attendre 500ms digitalWrite(PIN_PNP1, LOW); delay(500) // attendre 500ms digitalWrite(PIN_PNP2, HIGH); delay(500) // attendre 500ms digitalWrite(PIN_NPN1, LOW); delay(500) // attendre 500ms digitalWrite(PIN_NPN2, HIGH); delay(500) // attendre 500ms }

// Fonction permettant de tourner à droite void Tourneradroite() /* nécessite un pont en H (pour gérer la vitesse et la direction on agit sur le sens et l'intensité du courant qui passe dans une bobine) */ { digitalWrite(PIN_MOTEUR, HIGH); digitalWrite(PIN_PNP1, LOW); digitalWrite(PIN_PNP2, HIGH); delay(500) // attendre 500ms digitalWrite(PIN_NPN1, LOW); delay(500) // attendre 500ms digitalWrite(PIN_NPN2, HIGH); }

// Fonction permettant de tourner à gauche void Tourneragauche() /* nécessite un pont en H (pour gérer la vitesse et la direction on agit sur le sens et l'intensité du courant qui passe dans une bobine) */ { digitalWrite(PIN_MOTEUR, HIGH); digitalWrite(PIN_PNP1, HIGH); delay(500) // attendre 500ms digitalWrite(PIN_PNP2, LOW); digitalWrite(PIN_NPN1, LOW); digitalWrite(PIN_NPN2, HIGH); delay(500) // attendre 500ms }

//Fonction avancer tout droit void Avancertoutdroit() // on sature le transistor { digitalWrite(PIN_MOTEUR, HIGH); digitalWrite(PIN_PNP1, LOW); digitalWrite(PIN_PNP2, HIGH); digitalWrite(PIN_NPN1, HIGH); digitalWrite(PIN_NPN2, LOW); }

(c'est qu'une partie, je ne mets pas le reste car c'est inutile pour l'instant)

Je t'invite a voir ceci :

http://www.kmitl.ac.th/~kswichit/ROBOT/Follower.pdf

Tu peux mettre le code entre balises [code ] avec le bouton #

Pour ton code:

Remarque 1 : toute instruction doit se terminer par ;

delay(500) // attendre 500ms doit donc s'écrire delay(500); // attendre 500ms

Remarque 2 : ne pas confondre entiers et booléens

const boolean PIN_MOTEUR = 5; me semble bizarre, tu veux déclarer une variable entière pour définir un numéro d'ordre (le no de pin) mais tu définis cette constante sous forme de booléen qui normalement ne signifie que vrai ou faux, donc 2 états (avec par convention 0 = faux et vrai pour les autres valeurs). Mais en faisant cela, tu t'exposes à des soucis si tu ne sais pas comment le compilateur va gérer cette déclaration. Pour ma part, je préfère : const byte PIN_MOTEUR = 5;

Remarque 3 : ne pas confondre 'adresse' et 'valeur'

en fait tu as le même problème avec les ports analogiques. Le numéro du pin de ton capteur US est le 1 (notée A1 pour Arduino) qui est un entier. La valeur que tu vas lire sur ce port sera aussi un entier entre 0 et 1023 (que tu pourras convertir en valeur réelle si nécessaire via une conversion d'échelle).

La déclaraton suivante a l'intention - je suppose - de définir le numéro du port : const float PIN_CAPTEUR_ULTRASON = A1; donc elle doit être (le 'float' définit une valeur réelle incorrecte ici) const byte PIN_CAPTEUR_ULTRASON = A1;

Cette variable n'a aucune raison de changer sur toute la durée de vie de ton programme (le cablage ne va pas bouger tout seul), c'est donc une constante d'où l'utilisation de 'const' et par convention l'usage de majuscules.

En ce qui concerne la valeur lue sur ce port, tu peux ajouter une variable pour la mémoriser (dépassant 255 puisque 1023 max un octet -byte- n'est plus suffisant) comme par exemple: int valeur_lue_pour_capteur_ultrason = 0; Le =0 n'est pas nécessaire puisque sûrement dans ton code tu écriras valeur_lue_pour_capteur_ultrason = analogRead(PIN_CAPTEUR_ULTRASON); mais pour moi il est assez dangereux de ne pas fixer des valeurs intiales à toutes mes variables