RobotGEII Capteurs Ultrasons : Différence entre versions
Ligne 94 : | Ligne 94 : | ||
== {{Vert|Arduino et TIMER}} == | == {{Vert|Arduino et TIMER}} == | ||
+ | |||
Pour la programmation de la carte capteur, nous utiliserons la carte Arduino MEGA2560, d'une part pour nous permettre de reprendre nos travaux précédents mais aussi en raison de ses nombreux pins disponibles afin que notre projet n'utilise qu'une carte (tout le groupe travaillant sur le même robot). | Pour la programmation de la carte capteur, nous utiliserons la carte Arduino MEGA2560, d'une part pour nous permettre de reprendre nos travaux précédents mais aussi en raison de ses nombreux pins disponibles afin que notre projet n'utilise qu'une carte (tout le groupe travaillant sur le même robot). | ||
Ligne 141 : | Ligne 142 : | ||
== {{Vert|Organigramme de fonctionnement}} == | == {{Vert|Organigramme de fonctionnement}} == | ||
− | [[Fichier:organigrammecapteur.png| | + | |
+ | [[Fichier:organigrammecapteur.png|100px|thumb|left|Organigramme]] | ||
Notre programme sera simple : il sera constitué de deux modes, l'un utilisant tous les capteurs à la fois, l'autre utilisant les capteurs les un après les autres. | Notre programme sera simple : il sera constitué de deux modes, l'un utilisant tous les capteurs à la fois, l'autre utilisant les capteurs les un après les autres. | ||
Ligne 147 : | Ligne 149 : | ||
S'il en détecte un, il passe alors au second mode pour mieux connaître la position de l'obstacle. | S'il en détecte un, il passe alors au second mode pour mieux connaître la position de l'obstacle. | ||
− | {{Boîte déroulante/début|titre=[[Programme | + | {{Boîte déroulante/début|titre=[[Programme ProgUS]]}} |
<source lang=c> | <source lang=c> | ||
#include <util/delay.h> | #include <util/delay.h> | ||
Ligne 416 : | Ligne 418 : | ||
== {{Vert|Tests effectués avec la carte finale (Conclusion du travail du groupe capteur ultrason)}} == | == {{Vert|Tests effectués avec la carte finale (Conclusion du travail du groupe capteur ultrason)}} == | ||
+ | |||
Après quelques tests, la carte finale semble marcher correctement, chaque capteur détecte des objets allant jusqu'à 3m de distance. | Après quelques tests, la carte finale semble marcher correctement, chaque capteur détecte des objets allant jusqu'à 3m de distance. |
Version actuelle datée du 16 décembre 2015 à 13:31
Sommaire
Principe de fonctionnement d'un HC-SR04 (DASSIE)
Principe de base d'une onde ultrasonique
L'ultrason est une onde mécanique et élastique, qui se propage au travers de supports fluides, solides, gazeux ou liquides. La gamme de fréquences des ultrasons se situe entre 20 000 et 10 000 000 Hertz, trop élevées pour être perçues par l'oreille humaine.
Le nom vient du fait que leur fréquence est trop élevée pour être audible pour l'oreille humaine (le son est trop aigu : la gamme de fréquences audibles par l'homme se situe entre 20 et 20 000 Hertz), de la même façon que les infrasons désignent les sons dont la fréquence est trop faible pour être perceptible par l'oreille humaine.
Le principe est d'utiliser une onde ultrason se déplaçant à la vitesse du son soit environs 340ms⁻¹ ce qui est beaucoup plus simple et moins chère qu'un capteur infrarouge utilisant une onde infrarouge dont la vitesse est celle de la lumière soit environs 3*10⁸m/s
Le principe utilisé ici est le même, par le biais d'un capteur HC-SR04
Capteurs à ultrason : HC-SR04
Le capteur à ultrason HC-SR04 est donc un capteur utilisant la technologie ultrason permettant de détecter des objets tel un sonar dans un cône de détection face au capteur.
Les caractéristiques du composant sont les suivantes :
- Alimentation : 5 Volts
- Consommation : 15 milliAmpères
- Portée : 3 cm à 250 cm (soit 2.5m)
- Typé d'émission : Impulsion TTL de 10µs
- Fréquence d'émission : 40k Hertz
- Cône d'émission : 30° (soit +/- 15°)
- Calcul simple pour utilisation avec un module Arduino : Distance (cm) = durée de l'impulsion (µs) / 58
Le principe de fonctionnement est simple, une impulsion dont la longueur d'onde λ = 10µs
(lien d'aide pour finir la partie 1 : http://www.iut-troyes.univ-reims.fr/wikigeii/index.php/Sp%C3%A9cial:Liste_des_fichiers + https://itechnofrance.wordpress.com/2013/03/12/utilisation-du-module-ultrason-hc-sr04-avec-larduino/ + http://www.iut-troyes.univ-reims.fr/wikigeii/index.php?title=Robot_:_Hector&action=edit )
Réalisation de la carte (MATHIEU)
Réalisation du schéma
Pour réaliser le schéma sous Eagle, il a d'abord fallu créer le composant HC-RS04 et l'importer dans la bibliothèque. Pour ce faire, on a dû suivre différentes étapes qui sont :
Création du symbole
On crée tout d'abord le symbole qui est un représentation graphique du composant où l'on pourra nommer les pattes pour une question de pratique
Création du package
Le package ou empreinte est très important étant donné que ce sera le composant que l'on pourra placer sur le schéma, il faut donc placer avec précision les pattes de celui-ci et reproduire les dimensions réelles du composant vu par le dessus pour éviter tout contact avec d'autres composants lors de la réalisation du schéma.
Création du device
Enfin, le device sert à connecter le symbole et le package, il suffira alors d'associer la patte réelle du package avec la patte schématisée du symbole pour finaliser la création du composant.
Câblage des capteurs
Pour la connexion entre la carte capteur et le shield, nous n'avons pas utilisé le même câblage que pour le prototype, en effet, pour un soucis de pratique, nous avons décidé de positionner les Trigger et Echo de façon à faciliter le câblage. Voici un schéma qui représente la façon dont nous l'avons câblée.
Sur ce schéma sont représentés par des rectangles les 7 capteurs utilisés qui sont reliés sur un connecteur de 16 ports lui-même relié à la carte shield sur un connecteur identique.
Il ne reste donc plus qu'à créer le schéma de la carte en important le fichier que l'on vient de créer
Pour le board, étant donné que nous avons des contraintes de positionnement de capteur, il a fallu placer ces derniers de telles sortes qu'ils soient espacés de 30° pour couvrir tout l'avant du robot. De plus, il a fallu dimensionner le contour du board de façon à ce qu'on puisse le placer sur le dessus du robot tout en gardant le maximum de placer pour les autres cartes.Nous avons réalisés ce board en double face vu la difficulté de câblage de ce dernier.
Programmation (EUNG)
Arduino et TIMER
Pour la programmation de la carte capteur, nous utiliserons la carte Arduino MEGA2560, d'une part pour nous permettre de reprendre nos travaux précédents mais aussi en raison de ses nombreux pins disponibles afin que notre projet n'utilise qu'une carte (tout le groupe travaillant sur le même robot).
Voici les pins que nous utiliserons :
Capteur n°1 | Capteur n°2 | Capteur n°3 | Capteur n°4 | Capteur n°5 | Capteur n°6 | Capteur n°7 | |
---|---|---|---|---|---|---|---|
Trigger | 37 - PC0 | 36 - PC1 | 35 - PC2 | 34 - PC3 | 33 - PC4 | 32 - PC5 | 31 - PC6 |
Echo | 8 - PK0 | 9 - PK1 | 10 - PK2 | 11 - PK3 | 12 - PK4 | 13 - PK5 | 14 - PK6 |
Etant donné que nous utilisons une carte Arduino, nous en profiterons pour utiliser le TIMER2 dont nous expliquerons le fonctionnement ci dessous. Qu'est ce qu'un timer? Un timer est un compteur interne au microcontrôleur. L'intérêt du timer est qu'il compte sans cesse permettant ainsi à notre programme de faire autre chose, contrairement à la fonction delay() ce qui nous restreint énormément dans notre cas. En effet, on veut que notre robot "scan" les alentours tout en se mouvant tranquillement et ceci par le biais des interruptions. Comme son nom l'indique, le timer peut interrompre le programme à intervalles réguliers pour envoyer nos ondes sonores.
Organigramme de fonctionnement
Notre programme sera simple : il sera constitué de deux modes, l'un utilisant tous les capteurs à la fois, l'autre utilisant les capteurs les un après les autres. L'idée est de scanner toute la zone en face du robot tant qu'il ne rencontre pas d'obstacles. S'il en détecte un, il passe alors au second mode pour mieux connaître la position de l'obstacle.
#include <util/delay.h>
#define distUSmini 2000
#define CW 0
#define CCW 1
#define A 0
#define B 1
/* _Trigger_
37 - PC0
36 - PC1
35 - PC2
34 - PC3
33 - PC4
32 - PC5
31 - PC6
_Echo_
8 - PK0
9 - PK1
10 - PK2
11 - PK3
12 - PK4
13 - PK5
14 - PK6
*/
boolean toggle1 = 0;
volatile unsigned long t[8];
unsigned long tfin, tdebut, d[8];
volatile boolean recpt;
volatile boolean newmesure = false;
volatile char numCapt;
volatile uint8_t USmode = 0;
char AIA = 5;
char AIB = 4;
char BIA = 2;
char BIB = 3;
void setup() {
Serial.begin(115200);
pinMode(31, OUTPUT);
pinMode(32, OUTPUT);
pinMode(33, OUTPUT);
pinMode(34, OUTPUT);
pinMode(35, OUTPUT);
pinMode(36, OUTPUT);
pinMode(37, OUTPUT);
pinMode(AIA, OUTPUT);
pinMode(AIB, OUTPUT);
pinMode(BIA, OUTPUT);
pinMode(BIB, OUTPUT);
cli();
TCCR2A = 0;
TCCR2B = 0;
OCR2A = 156;
TCCR2B |= (1 << WGM12);
TCCR2B |= (1 << CS11);
TCCR2B |= (1 << CS10);
TCCR2B |= (1 << CS12);
TIMSK2 |= (1 << OCIE1A);
PCICR |= 1 << PCIE2;
sei();
}
ISR(TIMER2_COMPA_vect)
{
static boolean start = true;
if (start == true)
{
if (USmode == 0) numCapt = 7;
if (USmode == 1)
{
numCapt++;
if (numCapt >= 7) numCapt = 0;
}
TCCR2B &= ~((1 << CS12) | (1 << CS10));
OCR2A = 150;
if (numCapt == 7)
{
PORTC = 0b01111111;
PCMSK2 = 0b01111111;
}
else
{
PORTC = 1 << numCapt;
PCMSK2 = 1 << numCapt;
}
}
else
{
PORTC = 0;
recpt = false;
TCCR2B |= ((1 << CS12) | (1 << CS10));
OCR2A = 30;
}
start = !start;
}
ISR(PCINT2_vect)
{
if (recpt == false)
{
tdebut = micros();
recpt = true;
}
else
{
tfin = micros();
if ((tfin - tdebut) > 50)
{
t[numCapt] = tfin - tdebut;
recpt = false;
newmesure = true;
}
}
}
void loop() {
static unsigned long dateAffichage = 0, dateActuelle;
dateActuelle = millis();
test();
if (newmesure == true)
{
if (USmode == 1)
{
if (t[numCapt] > distUSmini)
{
USmode = 0;
}
}
else
{
if (t[7] < distUSmini)
{
USmode = 1;
}
}
if ((dateActuelle - dateAffichage) > 200)
{
dateAffichage = dateActuelle;
Serial.print("Mode:");
Serial.println(USmode, DEC);
Serial.print("Duree 0: ");
Serial.print(t[0], DEC);
Serial.println(" us.");
Serial.print("Duree 1: ");
Serial.print(t[1], DEC);
Serial.println(" us.");
Serial.print("Duree 2: ");
Serial.print(t[2], DEC);
Serial.println(" us.");
Serial.print("Duree 3: ");
Serial.print(t[3], DEC);
Serial.println(" us.");
Serial.print("Duree 4: ");
Serial.print(t[4], DEC);
Serial.println(" us");
Serial.print("Duree 5: ");
Serial.print(t[5], DEC);
Serial.println(" us.");
Serial.print("Duree 6: ");
Serial.print(t[6], DEC);
Serial.println(" us.");
Serial.print("Distance +proche: ");
Serial.print(t[7], DEC);
Serial.println(" us");
Serial.println("");
}
newmesure = false;
}
}
void test()
{
if (t[3] > 3000) avancer1(); // obstacle>3000
//else if(t[3]>1500) avancer2(); // 3000>obstacle>1500
//else if(t[3]>800) avancer3(); // 1500>obstacle>800
else if (t[3] > 800) AvProp(); //3000>obstacle>800
else stopdrive(); // obstacle<800
}
void AvProp()
{
drive(A, CW, t[3] / 30 + 50);
drive(B, CW, t[3] / 30 + 20);
}
void avancer1() //avancer+++
{
drive(A, CW, 100);
drive(B, CW, 100);
}
void avancer2() //avancer++
{
drive(A, CW, 50);
drive(B, CW, 50);
}
void avancer3() //avancer+
{
drive(A, CW, 25);
drive(B, CW, 25);
}
void stopdrive() //stop
{
drive(A, CW, 0);
drive(B, CW, 0);
}
void gauche() //tournergauche
{
drive(A, CCW, 50);
drive(B, CW, 50);
}
void drive(byte MOTOR, byte dir, byte spd)
{
if (MOTOR == A)
{
digitalWrite(AIB, dir);
analogWrite(AIA, spd);
}
else if (MOTOR == B)
{
digitalWrite(BIB, dir);
analogWrite(BIA, spd);
}
}
Tests effectués avec la carte finale (Conclusion du travail du groupe capteur ultrason)
Après quelques tests, la carte finale semble marcher correctement, chaque capteur détecte des objets allant jusqu'à 3m de distance. Le passage d'un mode à l'autre fonctionne également. Pour aller plus loin, nous sommes allé emprunter le module permettant de commander les moteurs ainsi que la carte d'alimentation d'autres groupes, après un rapide code ajouté pour commander ces derniers, nous obtenions un robot pouvant détecter les obstacles tout en avançant. Nous nous sommes alors restreints à l'utilisation du capteur avant afin de faire naviguer notre robot dans la salle : dès la rencontre d'un obstacle, celui ci devait tourner à droite, agissant ainsi comme un robot aspirateur. De peur que le robot ne soit endommager par les éventuels chocs, la vitesse a été programmée pour être proportionnelle à la distance séparant le robot de l'obstacle, évitant ainsi tous risques.
Étant donné que les autres groupes n'ont pas avancé aussi vite, ce sont les seuls tests effectués avec un robot naviguant par ses propres moyens en esquivant les obstacles et murs.