RobotGEII Capteurs Ultrasons

De troyesGEII
Aller à : navigation, rechercher


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.


Principedefct.png


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

Sonarethan.jpg

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.


Capteursultrason.png


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

Wikisymbol.png

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

Wikipackage.png

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

Wikidevice.png

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.

Capteurwik.png

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

Wikischema.png

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.


Wikiboard.png


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).

Arduino Mega Pinout Diagram


Voici les pins que nous utiliserons :

Pins utilisés sur la carte Arduino Mega selon Trigger/Echo
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

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. 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.

Programme ProgUS

#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.