Binome2015-5 : Différence entre versions

De Wiki de bureau d'études PeiP
(Réalisation du PCB)
(Principales étapes :)
Ligne 148 : Ligne 148 :
  
 
Les circuits imprimés ont ainsi été reçus très rapidement .
 
Les circuits imprimés ont ainsi été reçus très rapidement .
 +
 +
== Programmation : ==
 +
 +
La partie programmation est le gros lot du projet . Utilisant une plateforme Arduino Mega , nous avons dû nous familiariser avec le langage arduino , qui consiste en une simplification du langage C .
 +
Nous avons donc suivi quelques cours dispensés par plusieurs plateformes d'éducation en ligne afin de connaître les principales subtilités du langage .
 +
Le premier programme que nous avons réalisé fût celui du contrôle moteur . Chaque moteur étant connecté a une sortie PWM et digitale , nous avons dû renvoyer un signal analogique pour le contrôle de la vitesse ( valeur allant de 0 à 255 ) , l'entrée digitale étant utilisée pour faire tourner la roue dans le sens horaire ou trigonométrique .
 +
Le programme réalisé est très simple et répond a toute nos attentes :
 +
 +
  void avancer(int moteur,boolean direct,int vitesse)
 +
  {
 +
 
 +
    //avance par defaut
 +
    boolean montre = HIGH;
 +
    boolean trigo = LOW;
 +
    if(!direct){ //si boolean nul , recule
 +
      montre = LOW;
 +
      trigo = HIGH;
 +
    }
 +
 
 +
    if(moteur == 1) //moteur 1 selon les branchement
 +
    {
 +
      digitalWrite(AIN1,montre); //AIN1 cntrol le sens du courant
 +
      digitalWrite(AIN2,trigo); //AIN2 aussi autre sens
 +
      analogWrite(PWMA,vitesse); //control vitesse analogique pr garder une vitesse stable (asservis)
 +
    }
 +
    else
 +
    {
 +
      digitalWrite(BIN1,montre);
 +
      digitalWrite(BIN2,trigo);
 +
      analogWrite(PWMB,vitesse);
 +
    }
 +
     
 +
  }
 +
  //Tourner
 +
  //tourner(0,75); //tourbne a fguahce
 +
  //tourner(1,75); //tourne a droite
 +
  void tourner(boolean sens,int vitesse)
 +
  {
 +
    if(sens)
 +
    avancer(1,1,vitesse);
 +
    avancer(2,1,vitesse);
 +
    if(!sens)
 +
    avancer(1,0,vitesse);
 +
    avancer(2,0,vitesse);
 +
   
 +
  }
 +
  void arret()
 +
  {
 +
    digitalWrite(STBY,LOW); //standby off
 +
  }
 +
  //démarrer
 +
  void demarrer()
 +
  {
 +
    digitalWrite(STBY,HIGH); //standby on
 +
  }
 +
 +
Nous avons donc divisé le tout en trois fonctions principales permettant de mettre en marche ou d'arrêter le moteur et d'avancer et une fonction secondaire utilisant les précédentes , permettant de tourner .
 +
 +
Nous nous sommes ensuite penchés sur la partie détection ultrason , qui s'est également traduite par un code simple mesurant la distance entre un objet et le capteur ultrason par émission d'impulsions :
 +
 +
  float distanceUltraSon(int trig,int echo)
 +
  {
 +
    digitalWrite(trig,HIGH);
 +
    delayMicroseconds(10);
 +
    digitalWrite(trig,LOW);
 +
    unsigned long pulsation = pulseIn(echo,HIGH);/*duree de l'etat
 +
    car echo change si il recoit un signal */
 +
    if(pulsation>3000)//signal perdu
 +
      {
 +
      return 0.0;
 +
      }
 +
    else{
 +
      pulsation = pulsation/2; //division de laller retour
 +
     
 +
      float tmps = pulsation/1000000.0; //conversion en sec
 +
      float dist = (tmps*340)*100.0; //formule de base en cm
 +
     
 +
      return dist;} 
 +
  }
 +
 +
Vient ensuite la partie de la détection de la balle InfraRouge par les phototransistor . Cette partie est celle qui nous a posée le plus de problèmes car nous les phototransistor renvoyaient continuellement des données brouillés par la lumière ambiante : il était donc impossible de différencier ces valeurs de celle de la balle ,sauf si celle-ci était vraiment très proche des capteurs .
 +
Dans un premier temps , nous avons reliés ces capteurs a une résistance de 330 Ohm et avons simplement utilisé un analogRead afin de recevoir la valeur renvoyée . Cette méthode fut rapidement abandonnée à cause du problème énoncé précédemment . Nous nous sommes alors penchés sur un programme plus complexe qui nous permettrait de capter simplement les signaux infrarouges pulsés . Le principe est le suivant : pendant un petit laps de temps , nous réalisons un grand nombre d'acquisitions et enregistrons les valeurs dans un tableau . Sachant que la balle est pulsée (supposons une pulsation a 600 Hz) , elle renvoie une valeurs chaque deux millisecondes environ dans le meilleur des cas , ce qui se traduit par une successions de valeurs positives et négatives . Le lumière renvoyée par le soleil par exemple , n'est quant a elle , pas pulsée , il s'agit donc de valeurs continues et très variables . Ainsi , notre programme vérifie si deux valeurs qui se suivent sont très proches . Si oui , il s'agit de la balle , sinon , il s'agit d'une autre source de lumière .
 +
 +
  int detectionBalle(int a)
 +
  {
 +
  int tab[300] = {0};
 +
  int i=0;
 +
  int somme = 0;
 +
  for(i=0;i<300;i++)
 +
  {
 +
    int b = IR(a);
 +
    tab[i] = b;
 +
  }
 +
  int boucle;
 +
  int tab2[300];
 +
    for(i=0;i<300;i++)
 +
    {
 +
      if (tab[i]<0)
 +
      {
 +
      tab2[i]=0;
 +
      }
 +
      else
 +
      {
 +
      tab2[i]=tab[i];
 +
      }
 +
    }
 +
    i=0;
 +
    int compteurvar=0;
 +
    for(i=0;i<300;i++)
 +
    {
 +
      somme += tab2[i];
 +
      if((tab2[i+1]<tab2[i]*0.2)||(tab2[i+1]>tab2[i]*1.8))
 +
      {
 +
      compteurvar++;
 +
      }
 +
    }
 +
    if (compteurvar>=30)
 +
    {
 +
    return (int)(somme/compteurvar);
 +
    }
 +
  return 0;
 +
  }
 +
 +
Ce code fonctionne parfaitement lorsque le robot n'est pas en mouvement . Lorsqu'il l'est , les valeurs sont erronés et le robot tourne sur lui même , ou suit des mauvaises directions .
 +
 +
La partie concernant les capteurs de lignes à été réalisée rapidement . Cependant, nous avons rencontré un obstacle majeur : si le robot avance trop rapidement sur une ligne , les valeurs des capteurs de lignes ne sont pas rafraîchies assez rapidement et la ligne n'est donc pas détectée .

Version du 26 mars 2016 à 16:56

Introduction :

Le projet de cette saison consiste à réaliser un jeu de balle entre des robots que nous allons construire nous même. Notre binôme a choisi de travailler sur le robot joueur ainsi que les cages de buts. La clé pour l'aboutissement du projet consiste a un travail d'équipe afin de pouvoir mettre en commun les avancées de chacun, c'est dans ce but que nous tenons cette page régulièrement actualisée au fil des séances de cours et de recherche personnelle.

Descriptif des séances :

Séance 1 : 18/01/16

La première séance à , en grande partie , consisté à l'établissement du cahier des charges . Nous en sommes venus a conclure sur une liste de matériel nécessaire , les contraintes auxquels sera soumis le robot , ainsi que les différentes options possibles pour les contourner . Nous avons pensé que les contraintes mécaniques devront être les premières à être débattus , ce qui nous à amené à conclure quant au système de pince à utiliser , ainsi que le système de tir . Les pièces nécessaires à ce sujet seront imprimés en 3D pour les pièces nécessitant peu de précision , ou coupé au laser pour le reste . Nous avons également convenu que le châssis a 2 roues convenait mieux a notre projet , en raison de sa plus grande mobilité .


Séance 2 : 21/01/16

La seconde séance nous a permis de construire le châssis 2 roues (photos à venir ) et de commencer à programmer sur l'Arduino Mega . Ainsi , nous avons pu écrire l'algorithme permettant la mesure de la distance par ultrason , ainsi que le contrôle global du servomoteur à utiliser grâce a la librairie associée .

Séance 3 : 25/01/16

  • Découverte du logiciel freecad
  • Dessin des engrenages pour la pince du robot

Séance 4 : 28/01/16

  • impression 3D des engrenages grace au logiciel Cura
  • Dessin des barres dentées pour la pince grâce au logiciel freecad

Séance 5 : 29/01/16

  • Création d'une maquette en carton pour tester le systeme de récepteurs infrarouge
  • Codage du programme controlant les recepteurs infrarouge

Séance 6 : 01/02/16

  • essai d'impression d'une première pince 3D. Cette impression fut peu concluante mais nous a permis de comprendre le fonctionnement de l'imprimante 3D, mieux maitriser le logiciel freecad pour dessiner les pièces et de voir quels etaient les problemes de notre système.
  • Installation des recepteurs infrarouge sur le robot.

Séance 7 : 04/02/16

  • Travail sur le problème des recepteurs infrarouges qui ne fonctionnent pas. Nous obtenons par moment des valeurs mais n'arrivons pas à faire marcher le systeme correctement.
  • Réalisation sur freecad d'une nouvelle pince qui doit être plus efficace. Nous attendons donc de pouvoir l'imprimer pour la tester.

Séance 8 : 08/02/16

  • Résolution du problème des recepteurs infrarouges ne fonctionnant pas normalement.

Nous avons du démonter tout le circuit pour rebrancher les recepteurs un par un et finalement, obtenir un résultat satisfaisant. Nous réglerons le programme pour localiser la balle durant une autre séance.

  • Nous avons commencé à utiliser les capteurs noir et blanc mais pour l'instant, ceci ne fonctionne pas bien sauf en collant les capteurs à la surface voulut.

Séance 9 : 11/02/16

Séance 10 : 22/02/16

  • Impression des derniers composants de la pince. Il ne manque plus que les taquets sur lesquels les roues dentées vont tourner. Nous les réaliserons en bois.

Séance 11 : 25/02/16

Début de la réalisation des 3 circuits imprimés a réaliser . Le premier concerne le contrôleur moteur , le module XBee ainsi que le capteur Ultrason . Un second PCB sera disposé de façon a concentrer les connections reliés aux capteurs infrarouges . Et enfin , un troisième sera placés sur le châssis inférieur du robot et servira a connecter les deux servomoteurs utilisés pour le système de tir et la pince , et les capteurs de lignes .

Nous avons également pu mettre en avant une contrainte supplémentaire concernant les capteurs infrarouges : ils renvoient une valeur même lorsque la balle n'est pas présente . Cette contrainte sera surmontée dans la prochaine séance .

Séance 12 : 03/03/16

La pince est fonctionnelle . Elle a été réalisée grâce a un système d'engrenages , un premier engrenage étant connecté a un servomoteur qui actionne le mouvement suivi par les 3 autres engrenages . Deux barrettes dentées sont reliés aux roues dentés des extrémités

Séance 13 : 07/03/16

Nous avons fini par contourner la contrainte des valeurs incohérentes des capteurs InfraRouge en réalisant un nombre conséquent d'acquisitions (500 acquisitions consécutives) , qui sont stockés dans un tableau . Afin de confirmer la présence de la balle et non d'une autre source infrarouge temporaire , on vérifie que lorsqu'une valeur est enregistrée, elle est suivi par une autre valeur plus ou moins élevée . Si c'est le cas , la balle est présente sinon , il s'agit de parasites . La prochaine séance sera entièrement consacrée a la détection de la balle et au PCB.

Séance 14 : 10/03/16

Cette séance à été entièrement consacrée a la détection de la balle . Nous avons pu mettre au point le système de détection de balle énoncé lors du résumé de la séance précédente : nous avons ainsi rencontrés quelques problèmes , liés dans certains cas à une sortie de la capacité de mémoire de l'arduino , soit a des valeurs erratiques dues a la lumière du jour . Le capteur situé à l'avant retournait ainsi continuellement une valeur (petite , mais assez pour faire croire au programme que la balle est présente ) .

Séance 15 : 14/03/2016

Nous avons continués a mettre au point le programme consistant a détecter la balle . Quelques problèmes liés à la sortie de mémoire ont été réglés en réalisant moins de tours de boucles ( ce qui inclus une petite perte de précision ) . Concernant les PCB , nous avons finalement réalisés 3 PCB concernant respectivement les capteurs de lignes , à plaquer sur le châssis inférieur , les servomoteurs , à mettre prés de la pince , et finalement , le PCB principal à utiliser sur l'Arduino et contenant les composants principaux .

Séance 16 : 17/03/2016

Le programme pour la détection de la balle est au point , il ne détecte que la balle pulsée a 600 Hz , et aucune source non pulsée . Il ne manque plus qu'à l'intégrer au programme principal . Le problème rencontré précédemment était simplement dû au fait que la balle n'était pas pulsée ( les autres binômes travaillant sans modulation de signal) . La gravure du PCB à quant a elle été interrompue en raison d'un problème de format , nous ne l'avons appris qu'à la fin de la séance , nous allons donc nous pencher dessus pour le faire valider à la prochaine séance .

Séance 17 : 21/03/2016

Le problème du PCB était que les fichiers n'étaient pas au bon format . Nos enseignants nous ont expliqués comment soumettre le PCB sous un bon format , ce qui a été fait . Nous avons pu recevoir le PCB principal deux heures plus tard , les deux autres rencontrant toujours un problème dont la source reste à déterminer car le rendu sur le visualiseur Gerber ne montrer pas de problèmes pour nous (Le mail de refus précise un problème de drills ) . Nous avons terminés le programme visant a orienter le robot selon la puissance de la puissance du signal envoyé par la balle . Nous nous sommes alors penchés sur les capteurs de lignes , que nous avons entièrement finis lors de cette séance : le robot ne sort pas des zones délimités . A la rencontre d'une ligne noire , il recule puis change d'angle . Cependant un problème majeur a été rencontré : le rafraîchissement des valeurs n'est parfois pas assez rapide et si elle ne se fait pas alors que le robot traverse une ligne , elle n'est pas détectée . Une solution consiste a prendre un des capteurs et le placer a l'arrière du robot . Nous allons en discuter lors de la prochaine séance . Un autre problème à été mis en avant : du fait du nombre élevé de composants , si les piles ne sont pas entièrement chargés , l'Arduino ne tourne pas , et s'ils ont passés plus d'une heure à alimenter les tests , elles ne fonctionnement plus que par intermittence .

Principales étapes :

La pince

Pour fabriquer cette pince, nous avons utilisés les logiciels Freecad et Cura.

Les différents éléments de la pince : - 2 serres - 4 roues dentées - 4 taquets servant d'axe de rotation - la plaque principale de la pince.

les 2 serres, les 4 roues dentées ainsi que la plaque principale ont été dessinées sur Freecad puis imprimées grâce à l'imprimante 3D du Fabricarium. Mais les 4 taquets n'ont pas pu être imprimés par imprimante 3D car ceux ci étaient trop fins et de forme cylindrique ce que l'imprimante a plus de mal à produire. Les 4 taquets ont donc été réalisés en découpant un long clou de diamètre voulu (3.5mm) et un tuyau de diamètre légèrement supérieur.

Réalisation du PCB

PCB Capteurs de lignes

La réalisation du PCB est une étape majeure de notre projet : elle permet d'éviter les nombreux faux contacts rencontrés sur la plaque d'essai , de rendre plus compacte la disposition des composants , mais surtout , sa réalisation nous a permis d'en apprendre plus sur les circuits imprimé et de nous familiariser avec la méthode à suivre . La première version du PCB n'était pas du tout fonctionnelle car nous ne savions pas que les fils ne peuvent pas se croiser , information qui nous a rapidement été donné et nous nous sommes empressés de réaliser un PCB fonctionnel . En une semaine , nous avions conclus notre premier PCB principal où étaient inclus tout les composants de notre robot . Nos enseignants nous ont proposés de faire plusieurs cartes afin d'alléger le nombre de fils sur le robot ( chose que nous tentons d'éviter , d'où le choix d'un PCB au lieu de la plaque d'essai ) . Le premier envoi de la carte a l'impression s'est soldé par une erreur due au format , en effet , nous n'avions remplacé que le format du drill par .drd et laissé les autres dans leurs format exporté de Fritzing . Cette erreur a retardée l'impression d'une semaine de plus .

PCB Capteurs de lignes

Nous avons fait vérifié nos fichiers par un visualiseur Gerber avant de procéder à la validation de la demande d'impression . Le viewer Gerber permet de s'assurer que notre PCB sera bien interprété par la machine en nous imprimant a l'écran les différent fichiers exportés un a un : ainsi , nous pouvons voir les positionnement des drills , des pastilles , le plan de masse et les connexions .

Les circuits imprimés ont ainsi été reçus très rapidement .

Programmation :

La partie programmation est le gros lot du projet . Utilisant une plateforme Arduino Mega , nous avons dû nous familiariser avec le langage arduino , qui consiste en une simplification du langage C . Nous avons donc suivi quelques cours dispensés par plusieurs plateformes d'éducation en ligne afin de connaître les principales subtilités du langage . Le premier programme que nous avons réalisé fût celui du contrôle moteur . Chaque moteur étant connecté a une sortie PWM et digitale , nous avons dû renvoyer un signal analogique pour le contrôle de la vitesse ( valeur allant de 0 à 255 ) , l'entrée digitale étant utilisée pour faire tourner la roue dans le sens horaire ou trigonométrique . Le programme réalisé est très simple et répond a toute nos attentes :

 void avancer(int moteur,boolean direct,int vitesse)
 {
 
   //avance par defaut
   boolean montre = HIGH;
   boolean trigo = LOW;
   if(!direct){ //si boolean nul , recule
     montre = LOW;
     trigo = HIGH;
   }
 
   if(moteur == 1) //moteur 1 selon les branchement
   {
     digitalWrite(AIN1,montre); //AIN1 cntrol le sens du courant 
     digitalWrite(AIN2,trigo); //AIN2 aussi autre sens
     analogWrite(PWMA,vitesse); //control vitesse analogique pr garder une vitesse stable (asservis)
   }
   else
   {
     digitalWrite(BIN1,montre);
     digitalWrite(BIN2,trigo);
     analogWrite(PWMB,vitesse);
   }
     
 }
 //Tourner
 //tourner(0,75); //tourbne a fguahce
 //tourner(1,75); //tourne a droite
 void tourner(boolean sens,int vitesse)
 {
   if(sens)
   avancer(1,1,vitesse);
   avancer(2,1,vitesse);
   if(!sens)
   avancer(1,0,vitesse);
   avancer(2,0,vitesse);
   
 }
 void arret()
 {
   digitalWrite(STBY,LOW); //standby off
 }
 //démarrer
 void demarrer()
 {
   digitalWrite(STBY,HIGH); //standby on
 }

Nous avons donc divisé le tout en trois fonctions principales permettant de mettre en marche ou d'arrêter le moteur et d'avancer et une fonction secondaire utilisant les précédentes , permettant de tourner .

Nous nous sommes ensuite penchés sur la partie détection ultrason , qui s'est également traduite par un code simple mesurant la distance entre un objet et le capteur ultrason par émission d'impulsions :

 float distanceUltraSon(int trig,int echo)
 {
   digitalWrite(trig,HIGH);
   delayMicroseconds(10);
   digitalWrite(trig,LOW);
   unsigned long pulsation = pulseIn(echo,HIGH);/*duree de l'etat 
   car echo change si il recoit un signal */
   if(pulsation>3000)//signal perdu
     {
     return 0.0;
     }
   else{
     pulsation = pulsation/2; //division de laller retour
     
     float tmps = pulsation/1000000.0; //conversion en sec
     float dist = (tmps*340)*100.0; //formule de base en cm
     
     return dist;}   
 }

Vient ensuite la partie de la détection de la balle InfraRouge par les phototransistor . Cette partie est celle qui nous a posée le plus de problèmes car nous les phototransistor renvoyaient continuellement des données brouillés par la lumière ambiante : il était donc impossible de différencier ces valeurs de celle de la balle ,sauf si celle-ci était vraiment très proche des capteurs . Dans un premier temps , nous avons reliés ces capteurs a une résistance de 330 Ohm et avons simplement utilisé un analogRead afin de recevoir la valeur renvoyée . Cette méthode fut rapidement abandonnée à cause du problème énoncé précédemment . Nous nous sommes alors penchés sur un programme plus complexe qui nous permettrait de capter simplement les signaux infrarouges pulsés . Le principe est le suivant : pendant un petit laps de temps , nous réalisons un grand nombre d'acquisitions et enregistrons les valeurs dans un tableau . Sachant que la balle est pulsée (supposons une pulsation a 600 Hz) , elle renvoie une valeurs chaque deux millisecondes environ dans le meilleur des cas , ce qui se traduit par une successions de valeurs positives et négatives . Le lumière renvoyée par le soleil par exemple , n'est quant a elle , pas pulsée , il s'agit donc de valeurs continues et très variables . Ainsi , notre programme vérifie si deux valeurs qui se suivent sont très proches . Si oui , il s'agit de la balle , sinon , il s'agit d'une autre source de lumière .

 int detectionBalle(int a)
 {
 int tab[300] = {0};
 int i=0;
 int somme = 0;
 for(i=0;i<300;i++)
 {
   int b = IR(a);
   tab[i] = b;
 }
 int boucle;
 int tab2[300];
   for(i=0;i<300;i++)
   {
     if (tab[i]<0)
     {
     tab2[i]=0;
     }
     else
     {
     tab2[i]=tab[i];
     }
   }
   i=0;
   int compteurvar=0;
   for(i=0;i<300;i++)
   {
     somme += tab2[i];
     if((tab2[i+1]<tab2[i]*0.2)||(tab2[i+1]>tab2[i]*1.8))
     {
     compteurvar++;
     }
   }
   if (compteurvar>=30)
   {
   return (int)(somme/compteurvar);
   }
 return 0;
 }

Ce code fonctionne parfaitement lorsque le robot n'est pas en mouvement . Lorsqu'il l'est , les valeurs sont erronés et le robot tourne sur lui même , ou suit des mauvaises directions .

La partie concernant les capteurs de lignes à été réalisée rapidement . Cependant, nous avons rencontré un obstacle majeur : si le robot avance trop rapidement sur une ligne , les valeurs des capteurs de lignes ne sont pas rafraîchies assez rapidement et la ligne n'est donc pas détectée .