Binome2017-2 : Différence entre versions

De Wiki de bureau d'études PeiP
(CODE)
(Bilan :)
 
(69 révisions intermédiaires par 3 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 +
<include nopre noesc src="/home/pedago/ppeip/include/video-Robot_Binome02_2017-iframe.html" />
 +
__TOC__
 +
<br style="clear: both;">
 
Copyright '''Valérianne et Théo'''
 
Copyright '''Valérianne et Théo'''
  
https://itechnofrance.wordpress.com/2013/04/19/librairie-irremote-pour-arduino/
+
 
  
 
== Notre PROJEEEET: ==
 
== Notre PROJEEEET: ==
Ligne 27 : Ligne 30 :
 
Vitesse de pointe: ''30km/h, soit 8,333 m/s''''
 
Vitesse de pointe: ''30km/h, soit 8,333 m/s''''
  
Il sera doté d'intelligence artificielle, de 2 roues motrices indépendantes mais reliées par un même axe ainsi que de capteurs ultra son et infra rouge dans le but de détecter obstacles et proies. Il s'intégrera à son écosystème au moyen d'une led infrarouge, qui lui confèrera le titre de prédateurs aux yeux de tout les autres robots en présence. Il pourra occasionnelement passer sous contrôle télécommandé grâce à une rapsberry intégrée dans son organisme.
+
Il sera doté d'intelligence artificielle, de 2 roues motrices indépendantes mais reliées par un même axe ainsi que de capteurs ultra son et infra rouge dans le but de détecter obstacles et proies. Il s'intégrera à son écosystème au moyen d'une led infrarouge, qui lui confèrera le titre de prédateur aux yeux de tous les autres robots en présence. Il pourra occasionnelement passer sous contrôle télécommandé grâce à une rapsberry intégrée dans son organisme.
 +
 
 +
 
 +
Pour donner vie à Jean Kevin il nous fallait donc:
 +
* Créer le circuit imprimé, reliant le micro processeur aux différents actionneurs et capteurs.
 +
* Concevoir un algorythme de fonctionnement.
 +
* Programmer une "RapsberryPi" de façon à pouvoir contrôler notre robot à distance.
 +
* Imaginer et réaliser une base mécanique, capable de contenir les organes de Jean Kevin.
 +
 
  
  
Pour donner vie à Jean Kevin il nous fallait donc:
+
===<span style="color:red"> Etape 1: Création du circuit imprimé </span>===
-Créer le circuit imprimer, reliant le micro processeur aux différents actionneur et capteurs.
 
-Concevoir un algorythme de fonctionnement.
 
-Programmer une "RapsberryPi" de façon à pouvoir contrôler notre robot à distance.
 
-Imaginer et réaliser une base mécanique, capable de contenir les organes de Jean Kevin.
 
  
 +
Nous avons pris comme modèle la carte proposée dans le descriptif du projet [[Fichier:RobotPCB pcb.png|200px|right]]. Nous avons gardé que ce qui nous intéressait pour notre robot, à savoir un Servo moteur, deux Moteurs standars, trois Capteurs infrarouges, un Sonar et différentes leds de contrôle. Le 2nd Servo moteur et le détecteur de suivi de ligne ont donc été enlevé, et la carte réorganisée, pour un placement plus "propre" des trous de fixation ainsi que pour rapprocher une capacité servant à stabiliser le courant entrant dans la carte (en effet la distance entre l'alimentation et la capacité aurait pu créer des variations de courant).
  
 +
Après avoir modifier le routage de la carte nous avions ceci:
  
=== Etape 1: Création du circuit imprimé ===
+
[[Fichier:fritzing.jpg|200px]]
Nous avons pris comme modèle la carte proposée dans le descriptif du projet (PHOTO). Nous n'avons garder que ce qui nous intéressait pour notre robot, à savoir un Servo moteur, deux Moteurs standars, trois Capteurs infrarouges, un Sonar et différentes led de contrôles. Le 2nd Servo moteur et le detecteur de suivi de ligne ont donc étaient enlevé, et la carte réorganiser, pour un placement plus "propre" des trous de fixation ainsi que pour rapprocher une capacité servant à stabiliser le courant entrant dans la carte (en effet la distance entre l'alimentation et la capacité aurait pu créer des variations de courant).
 
  
Après avoir modifier le rootage de la carte nous avions ceci: (PHOTO)
+
Nous avons envoyé ce modèle à imprimer en Chine.
Nous avons envoyer ce modèle à imprimer en Chine.
+
 
 +
[[Fichier:circuit-vide.jpg|200px]]
  
 
Vient ensuite le soudage des composants:
 
Vient ensuite le soudage des composants:
-Les composants non traversants tels que les resistances, les capacités ou le processeur sont soudé au circuit à l'aide d'une pâte (Explication du principe de la pâte). Après un passage au four, cette pâte durcie et permet d'assurer le lien entre les composants et le circuit.
+
*Les composants non traversants tels que les résistances, les capacités ou le processeur sont soudés au circuit à l'aide d'une pâte. Après un passage au four, cette pâte durcie et permet d'assurer le lien entre les composants et le circuit.
PHOTO + COURBE
 
-Les composants traversants quant à eux sont soudé au fer avec de l'étain.
 
PHOTO
 
  
Il a fallu effectuer avec l'aide de Thierry (nom ?) des corrections sur certaines soudures à cause de la présence de ponts. On a donc eu recourt a fil à désouder ainsi qu'au décapeur thermique. Notre circuit était maintenant pret pour ses premiers tests.
+
[[Fichier:soudurev2.jpg|200px|thumb|left]]
 +
[[Fichier:four.jpg|200px|thumb||center|"Four de soudure"]]
  
TEST 1:
 
Mise sous alimentation du circuit -> une led s'allume ✔
 
  
TEST 2:
+
*Les composants traversants quant à eux sont soudé au fer avec de l'étain.
Installation d'un boot loader à partir d'un Arduino Uno, ce boot permettra à notre circuit de ce comporter comme un arduino, en regardant à  chaque démarrage si rien ne se trouve dans la partie USB. Si un programme s'y trouve, celui co sera exécuter directement. -> installation réussi ✔
 
  
TEST 3:
+
[[Fichier:soudurev1.jpg|200px]]
Programmation directe sur la carte -> ✗ ECHEC
 
En effet lors du téléversement de notre programme rien ne se passe, l'information n'est pas transmise. Après observation le problème provenait d'un pont présent entre les pâtes de la fiche USB, entre la masse et (...). La localisation du pont le rendait compliqué à enlevé, cependant, à l'aide d'un décapeur thermique, d'un fer à soudé, d'un clou et de Alexandre Boe (sourtout Alexandre Boe) celui ci fut détruit.
 
  
TEST 3.1:
+
*Il a fallu effectuer avec l'aide de Thierry des corrections sur certaines soudures à cause de la présence de ponts. On a donc eu recourt au fil à désouder ainsi qu'au décapeur thermique. Notre circuit était maintenant prêt pour ses premiers tests.
Programmation directe sur la carte -> ✗ ECHEC encore
 
Cette fois on s'aperçois grâce au led de contrôle que la communication fonctionne de l'USB au processeur mais pas du processeur à l'USB. Le problème venant probablement d'une mauvaise soudure entre ces deux points.
 
Cette fois la solution fut donnée par Xavier Redon qui souda à nouveau le chemin entre ces deux points.
 
  
TEST 3.2:
 
Programmation directe sur la carte -> Le programme fonctionne ✔
 
  
Le cerveau de notre prédateur était donc prêt. Il restait à vérifier que ce cerveau communique bien avec ses différents membres (moteurs capteurs etc...)
+
* TEST 1:
 +
Mise sous alimentation du circuit -> une led s'allume ✔
 +
[[Fichier:test-alim.jpg|200px|right]]
 +
<br style="clear: both;" />
  
TEST 4:
+
* TEST 2:
Communication avec les composants:
+
Installation d'un boot loader à partir d'un Arduino Uno, ce boot permettra à notre circuit de ce comporter comme un arduino, en regardant à chaque démarrage si rien ne se trouve dans la partie USB. Si un programme s'y trouve, celui ci sera exécuté directement. -> installation réussie
Servo moteur:
+
[[Fichier:test-arduino.jpg|200px|right]]
  Moteur A et B:
+
<br style="clear: both;" />
Sonar:
 
Tsop: ?
 
  
Au moment ou plus rien ne semblait pouvoir altérer la croissance notre JeanKevin, une nouvelle analyse de Xavier Redon lui décela une malformation electronique: En effet lors du déplacement d'une capacité lors du rootage de la carte, une des sortie du FTDI (le 3.3v) fut relié directement à l'alimentation 9V. Fort heureusement l'erreure fut repérée avant la mise sous tension du circuit par la sortie en question, ce qui nous évita de voir notre FTDI griller.
+
* TEST 3:
(Sreen)
+
Programmation directe sur la carte -> ✗ ECHEC
Quelques coups de bistouri plus tard notre circuit fut corrigé et intégralement fonctionnel !
 
Cependant nous avons ici un cerveau vide ou presque, il est temps de le remplir.
 
  
=== Etape 2: L'algorythme de fonctionnement ===
+
En effet lors du téléversement de notre programme rien ne se passe, l'information n'est pas transmise. Après observation le problème provenait d'un pont présent entre les pâtes de la fiche USB, entre la masse et Rx. La localisation du pont le rendait compliqué à enlever, cependant, à l'aide d'un décapeur thermique, d'un fer à soudé, d'un clou et de Alexandre Boé (sourtout Alexandre Boé) celui ci fut détruit.
Jean Kévin, s'il n'est pas télécommandé, doit être autonome, capable d'éviter les obstacles, de rechercher et d'identifier un proie, de la poursuivre et pourquoi pas, d'anticiper sa trajectoire.
 
Nous avons établis ce schéma de fonctionnement (SCHEMA)
 
  
A partir du schéma nous avons batis un algorythme se subdivisant en différents blocs:
+
* TEST 3.1:
 +
Programmation directe sur la carte -> ✗ ECHEC encore
  
'''-La recherche d'une proie :'''
+
Cette fois on s'aperçoit grâce aux leds de contrôle que la communication fonctionne de l'USB au processeur mais pas du processeur à l'USB. Le problème venant probablement d'une mauvaise soudure entre ces deux points. Cette fois la solution fut donnée par Xavier Redon qui souda à nouveau le chemin entre ces deux points.
  
Notre robot s'il ne trouvait pas de proie, devait partir à leur recherche, dans le but de ne pas toujours chercher dans la même zone il effectuera donc une rotation de 420° autour de lui même. Sil détecte une proie durant sa rotation il s'arrête, sinon il continue, une fois sa rotation terminée, le robot avance de 30cm et recommence jusqu'à ce qu'il trouve une cible. La rotation de 420° permet d'éviter d'effectuer des recherche en ligne droite.
+
* TEST 3.2:
  
Ce mode de recherche donne lieu à l'algorythme ci contre:
+
Programmation directe sur la carte -> Le programme fonctionne ✔
  
'''-L'évitement d'obstacle :'''
+
Le cerveau de notre prédateur était donc prêt. Il restait à vérifier que ce cerveau communique bien avec ses différents membres (moteurs capteurs etc...)
  
'''-Les virages :'''
+
* TEST 4: 
 +
[[Fichier:test-sonar.jpg|150px|right]]
  
Dans un soucis d'efficacité nous avons doté notre robot de 2 modes de rotations:
+
Communication avec les composants:
 +
**Servo moteur: ✔
 +
**Moteur A et B: ✔         
 +
**Sonar: ✔
 +
**Tsop: ✔
  
Le choix entre ces deux modes se fera en fonction de l'angle du virage à effectuer.
+
Au moment ou plus rien ne semblait pouvoir altérer la croissance de notre JeanKevin, une nouvelle analyse de Xavier Redon lui décela une malformation électronique : En effet lors du déplacement d'une capacité lors du rootage de la carte, une des sortie du FTDI (le 3.3v) fut relié directement à l'alimentation 9V. Fort heureusement l'erreur fut repérée avant la mise sous tension du circuit par la sortie en question, ce qui nous évita de voir notre FTDI griller.
  
Pour un virage < 30°, c'est l'axe sur lequel sont fixés les roues qui tournera grâce à un Servo moteur.
+
Quelques coups de bistouri/soudeur plus tard notre circuit fut corrigé et intégralement fonctionnel !
Pour un virage > 30°, une des deux roue s'arrêtera de tournée pendant que l'autre continuera, la rotation sera donc plus rapide et plus forte.
+
Cependant nous avons ici un cerveau vide ou presque, il est temps de le remplir.
 +
<br style="clear: both;" />
  
C'est à cette fin que nous avons créer l'algorythme ci contre:
+
===<span style="color:red"> Etape 2: L'algorithme de fonctionnement </span>===
 +
Jean Kévin, s'il n'est pas télécommandé, doit être autonome, capable d'éviter les obstacles, de rechercher et d'identifier un proie, de la poursuivre et pourquoi pas, d'anticiper sa trajectoire.
 +
Nous avons bâti un algorithme se subdivisant en différentes fonctions:
  
 +
'''-La recherche d'une cible :'''
  
 +
Notre robot s'il ne trouvait pas de proie, devait partir à leur recherche. Dans le but de ne pas toujours chercher dans la même zone, il effectuera donc une rotation de 420° autour de lui même. Sil détecte une proie durant sa rotation il s'arrête, sinon il continue. Une fois sa rotation terminée, le robot avance de 30cm et recommence jusqu'à ce qu'il trouve une cible. La rotation de 420° permet d'éviter d'effectuer des recherches en ligne droite.
  
=== Etape 3: Conception Mécanique ===
+
Ce mode de recherche donne lieu à l'algorithme ci contre:
Jean Kévin possède un cerveau et des organes, il est donc temps de lui donner un structure ! L'idéal est que cette structures s'adapte aux formes des différents composants pour éviter d'avoir trop de trous et fixations.
 
  
Voici les plans:
+
'''<span style="color:green">-Avancer Tout droit :</span>'''
  
 +
ToutDroit()
 +
digitalWrite(MotorD1,HIGH);
 +
digitalWrite(MotorD2,LOW);
 +
analogWrite(SpeedD,150);
 +
digitalWrite(MotorG1,HIGH);
 +
digitalWrite(MotorG2,LOW);
 +
analogWrite(SpeedG,142);
  
  
 +
'''<span style="color:green">-Rotation :</span>'''
 +
void Rotation ()
 +
{
 +
// Tourne dans le sens des aiguilles d'une montre , moteur droit à l'arrêt, moteur gauche tourne
 +
beaucoupD();
 +
}
  
  
=== Etape 4: La Rapsberry ===
+
'''<span style="color:green">-Les virages :</span>'''
  
== Séance du 15 janvier: ==
+
Dans un soucis d'efficacité nous avons doté notre robot de 2 modes de rotations:
 +
Le choix entre ces deux modes se fera en fonction de l'angle du virage à effectuer.
  
 +
*Pour un virage < 30°: On module la vitesse des moteurs pour faire des virages légers
 +
*Pour un virage > 30°, une des deux roues inversera son sens de rotation pendant que l'autre gardera le même, la rotation sera donc plus rapide et plus forte.
  
Découverte des objectifs et mise en place du cahier des charges. Nous souhaitons réaliser un robot "prédateur". Nous allons concevoir un robot simple car nous voulons nous concentrer sur la partie électronique et informatique. Nous allons réaliser notre circuit imprimé en nous basant sur celui qui nous est donné en exemple. Enfin,  nous allons programmer le robot pour qu'il puisse se déplacer de manière autonome. Cependant, lorsqu'il captera un signal wifi avec son raspberry pi, on pourra le commander depuis notre téléphone. 
+
C'est à cette fin que nous avons créer les fonctions ci contre:
  
Matériel nécessaire pour la partie mécanique:
+
void beaucoupG()
- Châssis à partir de plexiglas
+
{
- Roues motorisées
+
// moteur droit tourne, gauche recule
- Roue libre (bille)
+
digitalWrite(MotorG2,HIGH); // gauche
- Servo-moteurs
+
digitalWrite(MotorG1,LOW); // gauche
- Boîtier Piles
+
analogWrite(SpeedG,100); // vitesse gauche
+
digitalWrite(MotorD2,LOW); // droite
 +
digitalWrite(MotorD1,HIGH); // droite
 +
analogWrite(SpeedD,100);// vitesse droite
 +
}
  
+
void beaucoupD()
+
{
+
// moteur gauche tourne, droit recule
+
digitalWrite(MotorG1,HIGH);// gauche
+
digitalWrite(MotorG2,LOW);//gauche
+
analogWrite(SpeedG,100); // vitesse gauche
+
digitalWrite(MotorD1,LOW);// droit
+
digitalWrite(MotorD2,HIGH);// droit
Composants électroniques nécessaires:
+
analogWrite(SpeedD,100);// vitesse droite
 +
}
  
- Carte électronique
+
void trenteD()  
- Micro-contrôleur ATMega328p
+
{
- Adaptateur FTDI (USB-UART) et port USB
+
// moteur gauche tourne plus vite que le gauche
- Contrôleur-moteur
+
digitalWrite(MotorG1,HIGH);// gauche
- 3 Capteurs infrarouge
+
digitalWrite(MotorG2,LOW);//gauche
- Capteur Ultrasons
+
analogWrite(SpeedG,VitesseG); // vitesse gauche
- Régulateur 5V
+
digitalWrite(MotorD1,LOW);// droit
- Quartz 16 MHz
+
digitalWrite(MotorD2,HIGH);// droit
- 2 capacités 10microF
+
analogWrite(SpeedD,VitesseD);// vitesse droite
- 6 capacités 100nF
+
}
- 1 capacité 1mF
 
- 1 résistance 1kOhm
 
- 1 résistance 220Ohm
 
- 1 Diode
 
 
  
+
void trenteG()
+
{
+
// moteur droit tourne plus vite que le gauche
+
digitalWrite(MotorG1,HIGH);// gauche
+
digitalWrite(MotorG2,LOW);//gauche
+
analogWrite(SpeedG,VitesseG); // vitesse gauche
+
digitalWrite(MotorD1,LOW);// droit
+
digitalWrite(MotorD2,HIGH);// droit
+
analogWrite(SpeedD,VitesseD);// vitesse droite
+
}
 
 
 
 
 
Matériel informatique:
 
  
- Carte Raspberry Pi 3
 
- Caméra
 
- Batterie Raspberry
 
  
== Séance du 16 janvier: ==
+
'''<span style="color:green">-Les obstacles :</span>'''
  
 +
La détection des obstacles est également très importante, celle-ci s'effectue à l'aide du sonar et donne lieu à 2 fonctions, une fonction calculant la distance entre le sonar et les obstacles, une autre étant une procédure d'évitement des obstacles.
  
Nous avons réfléchi sur l'aspect esthétique de notre futur robot. (Image ?)
+
int DetectObstacle()
Nous avons analysé le circuit imprimé fournit par les professeurs sur le logiciel Fritzing pour ne garder que les éléments dont nous avions besoin. Nous avons donc enlevé le détecteur de ligne, un servo moteur. Nous avons passé du temps pour rétablir les connections compromises par la suppression de ces éléments. C'est très interessant de travailler sur le circuit imprimé, et de voir les différentes vues proposées, qui permettent de bien se rendre compte de la forme de chaque fonction, et comment elles sont reliées entre elles.
+
{
 +
long cm;
 +
cm=mesureSonar();
 +
Serial.print("Distancem : ");
 +
Serial.println(cm);
 +
if (cm<20)
 +
  {
 +
    return 1;
 +
  }
 +
  else
 +
  {
 +
    return 0;
 +
  }
 +
}
  
== Séance du 18 janvier: ==
+
void EviteObstacle(long temps)
 +
 +
    reculer();
 +
    delay(400);
 +
    while (millis() - (temps+400) <= 500)
 +
    {
 +
    beaucoupG();
 +
    if (DetectObstacle() == 1 && DectectCible() == 0)
 +
{
 +
    EviteObstacle(previousMillis = millis());
 +
}
 +
}
 +
}
 +
 
 +
On utilise donc toute ces fonctions dans le loop qui permet au robot de fonctionner de façon autonome en faisant appel aux différentes fonctions.
 +
Pour identifier les différentes pin du micro processeur nous avons utiliser l'image ci-contre:
 +
[[Fichier:Arduinovaltheo.png|300px|thumb|left|"Atmega"]]
  
 +
Puis dans un soucis de lisibilité nous avons modifié dans le programme le numéro des pins par un nom plus explicite:
 +
int broche_reception = A0;
 +
int MotorG2 = A5;
 +
int MotorG1 = 4;
 +
int Stdby = 9;
 +
int SpeedG = 10;
 +
int MotorD1 = 8;
 +
int MotorD2 = 7;
 +
int SpeedD = 6;
 +
int servo = 3;
 +
int SonarEnvoi = A4;
 +
int SonarRecept = A3;
  
Nous avons travaillé sur le routage de notre circuit imprimé pour qu'il soit le plus efficace possible. Nous avons modifié le placement de la capacité 4, qui était trop loin de l'alimentation. Elle ne remplissait pas sa fonction, qui est de lisser la tension dans les câbles. Notre circuit est prêt à être imprimé. Nous avons ensuite commencé le code de notre robot. La difficulté est de savoir dans quelle direction tourner en fonction de là où est la proie et de trouver la manière la plus efficace de tourner dans le but de rattraper la proie. Nous avons 3 capteurs infrarouge sur notre robot. La meilleure solution pour nous est de réduire le champs de balayage des capteurs pour avoir une plus grande information de l'emplacement de la proie. Par exemple, si le capteur de droite et du milieu détecte une présence, alors on fera tourner le robot vers la droite, à l'aide du servo-moteur qui va incliner l'axe des roues. S'il y a uniquement le capteur de droite qui détecte une proie, alors on fera tourner le robot en faisant tourner la roue gauche plus vite que l'autre.
+
<br style="clear: both;" />
  
== Séance du 19 janvier: ==
+
===<span style="color:red"> Etape 3: Conception Mécanique </span>===
 +
Jean Kévin possède un cerveau et des organes, il est donc temps de lui donner une structure ! L'idéal est que cette structure s'adapte aux formes des différents composants pour éviter d'avoir trop de trous et fixations.
  
 +
Nous avons donc eu plusieurs idées et versions de châssis [[Fichier:araignee.jpg|200px|thumb|right|"Les prémices de Jean Kévin"]] pour au final arriver à un châssis sur 2 étages pour permettre la fixation de la carte électronique, de la Rapsberry, d'une batterie et d'un bloc de piles.
  
Nous avons commencé le squelette du code. Cependant, nous avons beaucoup d'interrogations sur la façon dont va réagir notre robot. La difficulté est que nous ne pouvons pas tester notre code sur le robot pour le moment et que beaucoup de parties vont rester en suspens. Nous avons choisi d'utiliser la fonction milis(). Cette fonction permet d'effectuer plusieurs actions en même temps, ici tourner et repérer une proie, contrairement à la fonction delay().
+
[[Fichier:Etage_1.jpg|500px|thumb|left|"Etage 1"]] [[Fichier:Etage_2.jpg|410px|thumb|center|"Etage 2"]]
  
== Séance du 22 janvier: ==
 
  
Nous nous sommes familiarisé avec le logiciel Onshape. Nous ne sommes pas habitué à raisonner de manière mécanique (???). Il a été difficile de construire notre dôme en 3d que nous allons mettre à l'arrière du châssis. Il abritera le circuit imprimé et les piles.
 
  
  
== Séance du 25 janvier: ==
+
Les composants du robots sont maintenus sur le châssis à l'aide d'un système de cales sur chacun de leurs côtés.
  
Nous avons conçu la base de notre châssis. Nous avons choisi de faire des encoches pour fixer le dôme sur ce châssis. Il reste maintenant à réfléchir à l'emplacement des trous pour fixer le circuit imprimé et les autres éléments (moteurs, servo moteur, sonar et capteurs infrarouge) au châssis. Nous avons ensuite continué notre code en définissant les différentes fonctions principales de notre robot. Par exemple, avancer tout droit, tourner, détecter une cible...
+
Conception:
 +
Les plans du châssis ont donc été créés sur le logiciel en ligne "Onshape". Ce logiciel nous a permis de paramétrer les distances entre les différents éléments du châssis ainsi que de stocker ces distances dans des variables pour rendre plus simple et plus rapide les éventuelles modifications de dimension que nous pouvions apporter à Jean Kévin.
 +
La découpe de ces éléments s'effectua à la découpeuse laser. Il a donc fallu exporter les plans de Onshape au logiciel "Inkscape". Le transfert de logiciel a, pour une raison inconnue, engendrer une modification de l'échelle du plan. Après avoir calculé le coefficient entre les dimensions réelles et les dimensions sur Inkscape nous avons pu corriger celles ci et lancer la découpe.
 +
Nos éléments découpés, nous n'avions plus qu'à assembler notre robot à l'aide des vis et des cales prévues à cet effet.
  
Notre code:
+
Et voilà ! Après plusieurs semaines/mois de gestation, notre Jean Kévin arriva physiquement parmi nous ! Prêt à détruire le monde.
  
  
#include <Servo.h>
 
  
Servo myServo; unsigned long previousRotation = 0; unsigned long TimeRotaion = 5000
 
  
 +
===<span style="color:red"> Etape 4: La Rapsberry </span>===
  
void setup() {
+
Nous souhaitions pouvoir prendre le contrôle de Jean Kévin pour éviter tout débordement. Pour cela, nous l'avons doté d'une Raspberry Pi. Après avoir initialisé la Raspberry, nous avons commencé à concevoir la page html qui servira d'interface entre nous et Jean Kévin. Nous pouvons donc soit le contrôler à l'aide de deux curseurs, un qui gère la vitesse, et l'autre la rotation, soit avec une manette NES connectée en USB sur le PC.
 +
Pour prendre le contrôle, il faut se connecter au réseau "Pouloulou" et de se rendre à l'adresse: 192.168.100.1/serial.php
  
pinMode(1, OUTPUT); // moteur gauche
+
= Détail des séances : =
pinMode(2, OUTPUT); // moteur droit
 
pinMode(3, OUTPUT); // Servo
 
pinMode(4, OUTPUT); // Infra
 
pinMode(5, OUTPUT); // Infra
 
pinMode(6, OUTPUT); // Infra
 
pinMode(7, OUTPUT); // Sonar
 
}
 
  
int ToutDroit()
+
== Séance du 15 janvier: ==
{
 
  digitalWrite(1,HIGH);
 
  digitalWrite(2,HIGH);
 
  //delay
 
}
 
  
int StopRotation()
 
{
 
  digitalWrite(1,LOW);
 
  digitalWrite(2,LOW);
 
  //delay
 
}
 
  
 +
Découverte des objectifs et mise en place du cahier des charges. Nous souhaitons réaliser un robot "prédateur". Nous allons concevoir un robot simple car nous voulons nous concentrer sur la partie électronique et informatique. Nous allons réaliser notre circuit imprimé en nous basant sur celui qui nous est donné en exemple. Enfin, nous allons programmer le robot pour qu'il puisse se déplacer de manière autonome. Cependant, lorsqu'il captera un signal wifi avec sa raspberry pi, on pourra le commander depuis notre téléphone. 
  
int 90D()
+
== Séance du 16 janvier: ==
{
 
  digitalWrite(1,HIGH);
 
  digitalWrite(2,LOW);
 
  // delay
 
}
 
  
int 90G()
 
{
 
  digitalWrite(1,LOW);
 
  digitalWrite(2,HIGH);
 
  //delay
 
}
 
  
int 30D()
+
Nous avons réfléchi sur l'aspect esthétique de notre futur robot. Nous allons lui concevoir une coque pour que tous les éléments soient invisibles de l'extérieur.
{
+
Nous avons analysé le circuit imprimé fourni par les professeurs sur le logiciel Fritzing pour ne garder que les éléments dont nous avions besoin. Nous avons donc enlevé le détecteur de ligne, un servo moteur. Nous avons passé du temps pour rétablir les connections compromises par la suppression de ces éléments. C'est très intéressant de travailler sur le circuit imprimé, et de voir les différentes vues proposées, qui permettent de bien se rendre compte de la forme de chaque fonction, et comment elles sont reliées entre elles.
  AngleDir = analogRead(A4);
 
  digitalWrite(3,AngleDir-30); // ou +30 en fonction du servo
 
  //delay
 
}
 
  
int 30G()
+
== Séance du 18 janvier: ==
{
 
  AngleDir = analogRead(A4);
 
  digitalWrite(3,AngleDir+30); // ou - 30 en focntion du servo
 
  //delay
 
}
 
  
int Rotation ()
 
{
 
  digitalWrite(1,HIGH);
 
  digitalWrite(2,LOW);
 
  }
 
 
 
void loop() {
 
  
Obstacle = analogRead(A0);
+
Nous avons travaillé sur le routage de notre circuit imprimé pour qu'il soit le plus efficace possible. Nous avons modifié le placement de la capacité 4, qui était trop loin de l'alimentation. Elle ne remplissait pas sa fonction, qui est de lisser la tension dans les câbles. Notre circuit est prêt à être imprimé. Nous avons ensuite commencé le code de notre robot. La difficulté est de savoir dans quelle direction tourner en fonction de là où est la proie et de trouver la manière la plus efficace de tourner dans le but de rattraper la proie. Nous avons 3 capteurs infrarouge sur notre robot. La meilleure solution pour nous est de réduire le champs de balayage des capteurs pour avoir une plus grande information de l'emplacement de la proie. Par exemple, si le capteur de droite et du milieu détecte une présence, alors on fera tourner le robot vers la droite, à l'aide du servo-moteur qui va incliner l'axe des roues. S'il y a uniquement le capteur de droite qui détecte une proie, alors on fera tourner le robot en faisant tourner la roue gauche plus vite que l'autre.
Cible1= analogRead(A1);
 
Cible2= analogRead(A2);
 
Cible3= analogRead(A3);
 
  
Rotation ()
+
== Séance du 19 janvier: ==
  
if (Cible1 || Cible2 || Cible3) // Cible détectée ?
 
{
 
    StopRotation
 
    Poursuite
 
    {
 
      if (Cible1)
 
      {
 
        90D();
 
      }
 
      else if (Cible1 and Cible2)
 
      {
 
        30D();
 
      }
 
      else if (Cible2)
 
      {
 
        ToutDroit();
 
      }
 
      else if (Cible2 and Cible3)
 
      {
 
        30G;
 
      }
 
      else if (Cible3)
 
      {
 
        90G;
 
      }
 
      else if (Cible1 and Cible2 and Cible3)
 
      {
 
        ToutDroit();
 
      }
 
    }
 
}
 
 
if (millis() - previousRotation >= TimeRotation) {
 
  previousRotation = millis();
 
  StopRotation ;
 
  toutdroit() ; // Avance 3 secondes
 
}
 
  
}
+
Nous avons commencé le squelette du code. Cependant, nous avons beaucoup d'interrogations sur la façon dont va réagir notre robot. La difficulté est que nous ne pouvons pas tester notre code sur le robot pour le moment et que beaucoup de parties vont rester en suspens. Nous avons choisi d'utiliser la fonction milis(). Cette fonction permet d'effectuer plusieurs actions en même temps, ici tourner et repérer une proie, contrairement à la fonction delay().
  
 +
== Séance du 22 janvier: ==
  
 +
Nous nous sommes familiarisés avec le logiciel Onshape. Nous ne sommes pas habitués à raisonner de manière mécanique, c'est-à-dire en étant efficace dans l'utilisation du logiciel comme par exemple en enregistrant les distances dans des variables. Il a été difficile de construire notre dôme en 3d que nous allons mettre à l'arrière du châssis. Il abritera le circuit imprimé et les piles.
  
  
if (DistanceObstacle < 10) {
+
== Séance du 25 janvier: ==
  90G(); 
 
}
 
// put your main code here, to run repeatedly:
 
  
}
+
Nous avons conçu la base de notre châssis. Nous avons choisi de faire des encoches pour fixer le dôme sur ce châssis. Il reste maintenant à réfléchir à l'emplacement des trous pour fixer le circuit imprimé et les autres éléments (moteurs, servo moteur, sonar et capteurs infrarouge) au châssis. Nous avons ensuite continué notre code en définissant les différentes fonctions principales de notre robot. Par exemple, avancer tout droit, tourner, détecter une cible...
  
 
== Séance du 26 janvier: ==
 
== Séance du 26 janvier: ==
Ligne 340 : Ligne 310 :
 
== Séance du 29 janvier: ==
 
== Séance du 29 janvier: ==
  
Nous avons commencé la configuration en point d'accès de la Raspberry. Puis nous avons fait l'inventaire des pièces dont nous avions besoin pour notre circuit imprimé. (Image ?)
+
Nous avons commencé la configuration en point d'accès de la Raspberry. Puis nous avons fait l'inventaire des pièces dont nous avions besoin pour notre circuit imprimé.
  
 
== Séance du 1 février: ==
 
== Séance du 1 février: ==
  
Nous avons continué la configuration de notre raspberry. Nous avons initialisé le serveur web puis nous avons ajouter un nom de réseau pour la Raspberry Pi, nous l'avons appelé jeankevin.org. Enfin, nous avons établi une communication série. Cependant, pour que le serveur Web communique avec notre raspberry il faut passer par un serveur websocket. Ce type de processus est lancé au démarrage de la machine et accapare le port série. Nous ne pensions pas que la configuration de la raspberry nous prendrait autant de temps. Nous avons du mal à utiliser le terminal linux et nous ne connaissons pas les différentes commandes, ce qui ralentit notre progression.
+
Nous avons continué la configuration de notre raspberry. Nous avons initialisé le serveur web puis nous avons ajouté un nom de réseau pour la Raspberry Pi, nous l'avons appelé jeankevin.org. Enfin, nous avons établi une communication série. Cependant, pour que le serveur Web communique avec notre raspberry il faut passer par un serveur websocket. Ce type de processus est lancé au démarrage de la machine et accapare le port série. Nous ne pensions pas que la configuration de la raspberry nous prendrait autant de temps. Nous avons du mal à utiliser le terminal linux et nous ne connaissons pas les différentes commandes, ce qui ralentit notre progression.
 
 
  
  
Ligne 372 : Ligne 341 :
 
== Séance du 19 février: ==
 
== Séance du 19 février: ==
  
Nous avons testé les moteurs A et B et le sonar à l'aide de petits programmes simples. Nous avons décidé de ne plus utiliser de servo moteur pour les virages de 30 degrés car nous pensons qu'il n'aura pas assez de force pour entraîner la rotation des roues.  
+
Nous avons testé les moteurs A et B et le sonar à l'aide de petits programmes simples. Nous avons décidé de ne plus utiliser de servo moteur pour les virages de 30 degrés car nous pensons qu'il n'aura pas assez de force pour entraîner la rotation des roues. Nous utiliserons l'emplacement du servo moteur pour y mettre un buzzer pour que notre robot puisse faire un peu de musique.
  
 
== Séance du 22 février: ==  
 
== Séance du 22 février: ==  
Ligne 384 : Ligne 353 :
 
== Séance du 8 mars :==
 
== Séance du 8 mars :==
  
Nous avons voulu tester tous les éléments en même temps. Cependant, nous avons remarqué que les moteurs ne tournaient plus. En effet, nous les avions testé avant les vacances, et avant la correction du court circuit par Xavier Redon. En étant uniquement branché sur le PC, les moteurs étaient alimentés par le microprocesseur alors qu'ils doivent uniquement être alimenté par les piles 9V. Une fois les piles branchées, tout fonctionnait correctement. Nous avons aussi continué le code en modifiant les noms des pins que l'ont avait mis aléatoirement par celles correspondantes en ce référant à l'image ci-dessous.
+
Nous avons voulu tester tous les éléments en même temps. Cependant, nous avons remarqué que les moteurs ne tournaient plus. En effet, nous les avions testé avant les vacances, et avant la correction du court circuit par Xavier Redon. En étant uniquement branché sur le PC, les moteurs étaient alimentés par le microprocesseur alors qu'ils doivent uniquement être alimentés par les piles 9V. Une fois les piles branchées, tout fonctionnait correctement. Nous avons aussi continué le code en modifiant les noms des pins que l'ont avait mis aléatoirement par celles correspondantes en se référant à de la documentation.
 
 
[[Fichier:Arduinovaltheo.png]]
 
  
 
== Séance du 12 mars :==
 
== Séance du 12 mars :==
Ligne 404 : Ligne 371 :
 
Nous avons remarqué un défaut au niveau des moteurs : à une même vitesse donnée ils ne tournent pas à la même vitesse donc notre robot ne va pas exactement tout droit. Nous mettons un décalage de 10 entre la vitesse du moteur gauche et celui du moteur droit. Nous avons amélioré le code en utilisant la fonction millis() à la place de la fonction delay() pour permettre de continuer à détecter les cibles et obstacles pendant qu'il avance ou qu'il tourne. Nous avons aussi remarqué que le robot fonctionnait très bien en l'air quand on teste avec nos mains ses réactions, mais une fois au sol, il détecte des obstacles imaginaires. L'environnement est trop complexe pour le sonar qui a une faible précision.
 
Nous avons remarqué un défaut au niveau des moteurs : à une même vitesse donnée ils ne tournent pas à la même vitesse donc notre robot ne va pas exactement tout droit. Nous mettons un décalage de 10 entre la vitesse du moteur gauche et celui du moteur droit. Nous avons amélioré le code en utilisant la fonction millis() à la place de la fonction delay() pour permettre de continuer à détecter les cibles et obstacles pendant qu'il avance ou qu'il tourne. Nous avons aussi remarqué que le robot fonctionnait très bien en l'air quand on teste avec nos mains ses réactions, mais une fois au sol, il détecte des obstacles imaginaires. L'environnement est trop complexe pour le sonar qui a une faible précision.
  
== Nos codes de test: ==
 
  
 +
== Séance du 26 mars: ==
  
 +
Nous avons découpé des morceaux de plexiglas pour mieux maintenir les piles et la raspberry. Puis nous avons essayé d'inclure la gestion des TSOPs dans notre code. Les 3 TSOPs envoient les informations sur le même pin donc nous les allumons un par un pour savoir d'où vient le signal reçu (TSOP de gauche ou TSOP de droite par exemple). Dans un code à part, les TSOPs fonctionnent. Sans TSOPS, le robot fonctionne normalement. Mais lorsqu'on intègre les TSOPs dans le code principal, le robot ne réagit plus normalement, il ne détecte plus les obstacles et ne tourne plus. On pense qu'il reste bloqué dans la boucle de détection d'IR, qui ne fait rien tant qu'il ne capte rien. Alors que s'il ne capte rien, il ne doit pas rentrer dans la boucle de détection d'IR. De plus, les TSOPs ont une trop grande zone de détection donc il est difficile de s'en servir pour se diriger. A cause du manque de temps, nous avons décidé de ne pas mettre les TSOPs sur notre robot. Il est donc capable de se déplacer tout seul mais il ne pourra pas capter les proies.
  
Test Moteur A et B simultanéments:
 
  
void setup() {
+
== Séance du 9 avril: ==
  // put your setup code here, to run once:
 
  pinMode(8,OUTPUT);
 
  pinMode(7,OUTPUT);
 
  pinMode(6,OUTPUT); //vitesse
 
  pinMode(9,OUTPUT); // standby
 
  pinMode(10,OUTPUT);
 
  pinMode(4,OUTPUT);
 
  pinMode(A5,OUTPUT); //vitesse
 
  
}
+
Nous avons commencé la page html qui nous permettra de télécommander le robot. Au début, nous pensions faire quatre flèches dans chaque direction pour le diriger. Puis nous avons décidé de le commander à l'aide de deux curseurs, un qui gère la vitesse et un qui gère les virages. Cependant, les deux curseurs envoyaient en simultanée des informations donc nous avons essayé d'utiliser delay() et millis() dans le code pour réussir à discerner s'il s'agit de la vitesse ou du virage mais cette solution ne fonctionnait pas.
  
void loop() {
+
== Séance du 16 avril: ==
  // put your main code here, to run repeatedly:
 
  analogWrite(6, 1000);
 
  digitalWrite(8,HIGH);
 
  digitalWrite(7,LOW);
 
  digitalWrite(9,HIGH);
 
  analogWrite(10, 500);
 
  digitalWrite(4,LOW);
 
  digitalWrite(A5,HIGH);
 
  delay(2000);
 
  analogWrite(6, 500);
 
  digitalWrite(8,LOW);
 
  digitalWrite(7,HIGH);
 
  delay(2000);
 
 
 
}
 
  
Test moteur A:
+
Nous avons eu l'idée de faire varier le curseur qui gère la vitesse entre 0 et 125 et le curseur qui gère le virage entre 130 et 250. Si le curseur virage est à 130, il tourne à gauche à 90 degrés, s'il est à 250, il tourne à droite à 90 degrés, et à 190 le robot va tout droit. Nous avons modifié le code en conséquence. Enfin, nous voulons pouvoir choisir à partir de la page html si on prend le contrôle du robot ou si on le laisse en mode automatique. Nous avons eu quelques difficultés à faire en sorte que le mode automatique tourne en permanence tant qu'on ne reprend pas le contrôle.
  
 +
= Loop final =
  
 
+
void loop()  
void setup() {
+
{  
  // put your setup code here, to run once:
+
   if (Serial.available()>0)
  pinMode(8,OUTPUT);
+
   {
  pinMode(7,OUTPUT);
+
    int action=(int)Serial.read();
  pinMode(6,OUTPUT); //vitesse
+
    if (action == 253) etat=0; else etat=-1; // INTELLIGENCE ARTIFICIELLE
  pinMode(9,OUTPUT); // standby
+
    if (action<125 && action != 0) vitesse = action*2;
}
+
    else if (action>=130 && action<190 && vitesse != 0)
 
+
      {
void loop() {
+
      gauche = (190-action)*2;
  // put your main code here, to run repeatedly:
+
      droite=0;
  analogWrite(6, 1000);
+
      }
  digitalWrite(7,HIGH);
+
    else if (action>=190 && action<251 && vitesse != 0)
  digitalWrite(8,LOW);
+
      {
  digitalWrite(9,HIGH);
+
      droite = (action-190)*2;
  delay(2000);
+
      gauche=0;
  analogWrite(6, 500);
+
      }
  digitalWrite(7,LOW);
+
    else if (action == 0)
  digitalWrite(8,HIGH);
+
      {vitesse=0; gauche=0; droite=0;}
  digitalWrite(9,HIGH);
+
     else if (action == 254) {arriere(vitesse); delay(1000);}
  delay(2000);
+
      
 
+
}
+
     droite1=vitesse-droite;
 
+
     gauche1=vitesse-gauche;
 
+
     if (droite1<0) droite1=0;
Test moteur B:
+
     if (gauche1<0) gauche1=0;
 
+
     ToutDroit3(droite1,gauche1);
 
 
 
 
void setup() {
 
   // put your setup code here, to run once:
 
  pinMode(4,OUTPUT);
 
  pinMode(A5,OUTPUT);
 
  pinMode(10,OUTPUT); //vitesse
 
   pinMode(9,OUTPUT); // standby
 
}
 
 
 
void loop() {
 
  // put your main code here, to run repeatedly:
 
  analogWrite(10, 1000);
 
  digitalWrite(4,HIGH);
 
  digitalWrite(A5,LOW);
 
  digitalWrite(9,HIGH);
 
  delay(2000);
 
  analogWrite(10, 500);
 
  digitalWrite(4,LOW);
 
  digitalWrite(A5,HIGH);
 
  digitalWrite(9,HIGH);
 
  delay(2000);
 
 
 
}
 
 
 
Test Sonar :
 
 
 
// définition des broches utilisées
 
int trig = A4;
 
int echo = A3;
 
long lecture_echo;
 
long cm;
 
 
 
void setup()
 
{
 
  pinMode(trig, OUTPUT);
 
  digitalWrite(trig, LOW);
 
  pinMode(echo, INPUT);
 
  Serial.begin(9600);
 
  pinMode(A0, OUTPUT);
 
}
 
 
 
void loop()
 
{
 
  digitalWrite(trig, HIGH);
 
  delayMicroseconds(10);
 
  digitalWrite(trig, LOW);
 
  lecture_echo = pulseIn(echo, HIGH);
 
  cm = lecture_echo/58;
 
  Serial.print("Distancem : ");
 
  Serial.println(cm);
 
  delay(1000);
 
  if (cm<5)
 
  {digitalWrite(A0,HIGH);}
 
  if (cm>5)
 
  {digitalWrite(A0,LOW);}
 
}
 
 
 
Test TSOP 1:
 
 
 
/* void setup() {
 
 
 
  Serial.begin(9600);
 
  pinMode(A0,OUTPUT);
 
 
 
  pinMode(2, INPUT);
 
 
 
}
 
 
 
void loop() {
 
  digitalWrite(A0,HIGH);
 
 
 
  int p = 0; //variable de comptage pour tableau
 
 
 
  int tLow,tHigh; //variables de stockage de temps fictif
 
 
 
  int duree[32][2]; //tableau de stockage des temps de 32 sur 2
 
 
 
  Serial.println("Go"); //lancement de la procédure
 
 
 
  while (digitalRead(2)) {} // attente de changement d'état
 
 
 
 
 
 
 
  while (p < 32) { // boucle de stockage des données
 
 
 
    tLow=0; //initialisation du temps fictif pour état BAS
 
 
 
    tHigh=0;//initialisation du temps fictif pour état HAUT
 
 
 
     while (!digitalRead(2)) { //tant que le récepteur reçoit un signal LOW
 
 
 
      tLow++; //on incrémente le temps fictif pour état bas
 
 
 
    }
 
 
 
    while (digitalRead(2)) { //tant que le récepteur reçoit un signal HIGH
 
 
 
      tHigh++; //on incrémente le temps fictif pour état haut
 
 
 
     }
 
 
 
     duree[p][0] = tLow; //stockage dans tableau
 
 
 
     duree[p][1] = tHigh; //stockage dans tableau
 
 
 
     p++;
 
 
 
  }
 
 
 
 
 
 
 
  //affichage du tableau
 
 
 
  Serial.print("LOW\t");
 
 
 
  for (int p = 0; p < 32; p++) {
 
 
 
     Serial.print(duree[p][0]);
 
 
 
     Serial.print("\t");
 
 
 
 
   }
 
   }
 
  Serial.println();
 
 
  Serial.print("HIGH\t");
 
 
  for (int p = 0; p < 32; p++) {
 
 
    Serial.print(duree[p][1]);
 
 
    Serial.print("\t");
 
 
  }
 
 
  Serial.println();
 
 
 
 
 
  delay(3000);// attente pour nouvelle procédure
 
 
}
 
*/
 
 
void setup() {
 
 
  Serial.begin(9600);
 
pinMode(A0,OUTPUT);
 
}
 
 
void loop() {
 
digitalWrite(A0,HIGH);
 
  Serial.println(digitalRead(2));
 
 
}
 
 
 
// Test TSOP 2
 
 
#include <boarddefs.h>
 
#include <ir_Lego_PF_BitStreamEncoder.h>
 
#include <IRremoteInt.h>
 
#include <IRremote.h>
 
 
 
 
 
void setup() {
 
 
Serial.begin(9600);
 
pinMode(A1,OUTPUT);
 
 
pinMode(2, INPUT);
 
 
}
 
 
void loop() {
 
 
digitalWrite(A1,HIGH);
 
 
int p = 0; //variable de comptage pour tableau
 
 
int tLow,tHigh; //variables de stockage de temps fictif
 
 
int duree[32][2]; //tableau de stockage des temps de 32 sur 2
 
 
Serial.println("Go"); //lancement de la procédure
 
 
while (digitalRead(2)) {} // attente de changement d'état
 
 
 
while (p < 32) { // boucle de stockage des données
 
 
  tLow=0; //initialisation du temps fictif pour état BAS
 
 
  tHigh=0;//initialisation du temps fictif pour état HAUT
 
 
  while (!digitalRead(2)) { //tant que le récepteur reçoit un signal LOW
 
 
    tLow++; //on incrémente le temps fictif pour état bas
 
 
  }
 
 
  while (digitalRead(2)) { //tant que le récepteur reçoit un signal HIGH
 
 
    tHigh++; //on incrémente le temps fictif pour état haut
 
 
  }
 
 
  duree[p][0] = tLow; //stockage dans tableau
 
 
  duree[p][1] = tHigh; //stockage dans tableau
 
 
  p++;
 
 
}
 
 
 
//affichage du tableau
 
 
Serial.print("LOW\t");
 
 
for (int p = 0; p < 32; p++) {
 
 
  Serial.print(duree[p][0]);
 
 
  Serial.print("\t");
 
 
}
 
 
Serial.println();
 
 
Serial.print("HIGH\t");
 
 
for (int p = 0; p < 32; p++) {
 
 
  Serial.print(duree[p][1]);
 
 
  Serial.print("\t");
 
 
}
 
 
Serial.println();
 
 
 
delay(3000);// attente pour nouvelle procédure
 
 
}
 
 
 
 
 
/* void setup() {
 
 
Serial.begin(9600);
 
 
pinMode(A1,OUTPUT); }
 
 
void loop() { digitalWrite(A1,HIGH);
 
 
Serial.println(digitalRead(2));
 
 
}
 
*/
 
 
== CODE ==
 
 
   
 
   
    #include <boarddefs.h>
 
#include <ir_Lego_PF_BitStreamEncoder.h>
 
#include <IRremoteInt.h>
 
#include <IRremote.h>
 
 
 
// Pour utiliser millis
 
 
 
// Pour utiliser TSOP 1
 
int broche_reception = A0; // broche A0 utilisée 'VCC1 utilisé en IR1)
 
IRrecv reception_ir1(broche_reception); // crée une instance
 
decode_results decode_ir1; // stockage données reçues
 
 
 
 
void setup() {
 
 
pinMode(A5, OUTPUT); // moteur gauche AVANT
 
pinMode(4, OUTPUT); // moteur gauche ARRIERE
 
pinMode(10, OUTPUT);//vitesse
 
pinMode(9, OUTPUT);//standby
 
 
 
pinMode(8,OUTPUT);// moteur droit AVANT
 
pinMode(7,OUTPUT); // ARRIERE
 
pinMode(6,OUTPUT); //vitesse
 
//pinMode(9,OUTPUT); // standby
 
 
digitalWrite(9,HIGH);
 
pinMode(3, OUTPUT); // Servo
 
 
pinMode(A0,INPUT);// Normalement VCC Infra gauche TSOP 1 mais IR1
 
pinMode(2, OUTPUT); // IR mais VCC
 
Serial.begin(9600);
 
reception_ir1.enableIRIn(); // démarre la réception
 
pinMode(A1, INPUT); // Infra TSOP 2 milieu  mais IR2
 
pinMode(2, OUTPUT); // IR mais VCC
 
 
pinMode(A2,INPUT); // Infra TSOP 3 droite mais IR3
 
pinMode(2, OUTPUT); // IR mais VCC
 
 
// Sonar
 
 
pinMode(A4, OUTPUT);// trig
 
 
//digitalWrite(trig, LOW);
 
 
pinMode(A3, INPUT);//echo
 
Serial.begin(9600);
 
 
pinMode(A0, OUTPUT);// alimentation ??
 
// Pour utiliser le sonar
 
long lecture_echo;
 
long cm;
 
}
 
 
void ToutDroit() {
 
 
digitalWrite(8,HIGH);
 
digitalWrite(7,LOW);
 
analogWrite(10,100);
 
digitalWrite(4,HIGH);
 
digitalWrite(A5,LOW);
 
analogWrite(6,100);
 
//delay
 
 
}
 
 
void StopRotation() {
 
 
// moteur gauche se met aussi à l'arrêt
 
 
digitalWrite(4,LOW);
 
digitalWrite(A5,LOW);
 
 
//delay
 
 
}
 
 
void reculer() {
 
digitalWrite(7,HIGH);
 
digitalWrite(8,LOW);
 
analogWrite(10,100);
 
digitalWrite(A5,HIGH);
 
digitalWrite(4,LOW);
 
analogWrite(6,100);
 
 
}
 
void beaucoupD() {
 
 
// moteur gauche tourne, droit à l'arrêt
 
digitalWrite(4,HIGH); // gauche
 
digitalWrite(A5,LOW); // gauche
 
digitalWrite(7,LOW); // droite
 
digitalWrite(8,LOW); // droite
 
// delay
 
 
}
 
 
void beaucoupG() {
 
 
// moteur droit tourne, gauche à l'arrêt
 
digitalWrite(4,LOW);// gauche
 
digitalWrite(A5,HIGH);//gauche
 
analogWrite(10,100); // vitesse gauche
 
digitalWrite(7,LOW);// droit
 
digitalWrite(8,HIGH);// droit
 
analogWrite(6,100);// vitesse droite
 
//delay
 
 
}
 
 
void trenteD() {
 
 
// moteur gauche tourne plus vite que le gauche
 
  digitalWrite(10,255); //vitesse moteur gauche max
 
  digitalWrite(6,180); //vitesse moteur droit moyenne
 
  delay(2500);
 
}
 
 
void trenteG() {
 
// moteur droit tourne plus vite que le gauche
 
  digitalWrite(10,180); //vitesse lmoteur gauche moyenne
 
  digitalWrite(6,255); //vitesse moteur droit au max
 
  delay(2500);
 
 
}
 
 
void Rotation () {
 
 
// Tourne dans le sens des aiguilles d'une montre , moteur droit à l'arrêt, moteur gauche tourne
 
 
digitalWrite(4,HIGH);
 
digitalWrite(8,LOW);
 
}
 
 
long mesureS(){
 
  long lecture_echo;
 
  long cm1 = 0;
 
for (int k=0; k<10; k++)
 
{
 
digitalWrite(A4, HIGH);
 
delayMicroseconds(10);
 
digitalWrite(A4, LOW);
 
lecture_echo = pulseIn(A3, HIGH);
 
cm1 = cm1 + lecture_echo/58;
 
}
 
return (cm1/10);
 
}
 
 
// CIBLE 1
 
/*
 
void loop()
 
{
 
 
 
}
 
 
*/
 
void loop() {
 
 
//Obstacle = analogRead(A3);
 
  long cm;
 
  cm=mesureS();
 
Serial.print("Distancem : ");
 
Serial.println(cm);
 
//delay(1000);
 
if (cm<15)
 
{while (cm<24) {
 
  Serial.println("yeah je dois reculer");
 
  cm=mesureS();
 
  reculer();}
 
Serial.println("la voie est libre mon colonel !");
 
  beaucoupG();
 
  delay(500);}
 
 
   
 
   
else{
+
   if (etat==0)
 
 
   ToutDroit();}}
 
/*
 
Cible1= analogRead(A0); //TSOP 1
 
Cible2= analogRead(A1); //TSOP 2
 
Cible3= analogRead(A2); // TSOP 3
 
 
 
Rotation ()
 
 
 
if (Cible1 || Cible2 || Cible3) // Cible détectée ? {
 
 
 
  StopRotation
 
  Poursuite
 
  {
 
    if (Cible1)
 
    {
 
      90D();
 
    }
 
    else if (Cible1 and Cible2)
 
    {
 
      30D();
 
    }
 
    else if (Cible2)
 
    {
 
      ToutDroit();
 
    }
 
    else if (Cible2 and Cible3)
 
    {
 
      30G;
 
    }
 
    else if (reception_ir1.decode(&decode_ir1)) // TSOP 1 uniquement
 
  {
 
    beaucoupG();
 
    reception_ir.resume(); // reçoit le prochain code
 
     
 
    }
 
    else if (Cible1 and Cible2 and Cible3)
 
    {
 
      ToutDroit();
 
    }
 
  }
 
 
 
}
 
*/
 
/*if (millis() - previousRotation >= TimeRotation) {
 
 
 
previousRotation = millis();
 
StopRotation ;
 
ToutDroit() ; // Avance 3 secondes
 
 
 
}
 
 
 
}
 
 
 
*/
 
/*if (cm<5 ) {
 
 
 
beaucoupG(); 
 
 
 
} // put your main code here, to run repeatedly:
 
 
 
} */
 
 
 
 
 
 
 
 
 
 
 
______________________________________________________________________________________________________________________________________
 
 
 
// Pour utiliser millis
 
 
 
int broche_reception = A0; // broche A0 utilisée 'VCC1 utilisé en IR1)
 
int MotorG2 = A5;
 
int MotorG1 = 4;
 
int Stdby = 9;
 
int SpeedG = 10;
 
int MotorD1 = 8;
 
int MotorD2 = 7;
 
int SpeedD = 6;
 
int servo = 3;
 
int SonarEnvoi = A4;
 
int SonarRecept = A3;
 
 
 
int VitesseG, VitesseD;
 
 
 
unsigned long previousMillis = 0;
 
const long delaiTtDroit = 5000;
 
const long delaiRotate450 = 2500;
 
long previousMillis2;
 
 
 
 
 
 
 
 
 
void setup() {
 
 
 
pinMode(MotorG1, OUTPUT); // moteur gauche AVANT
 
pinMode(MotorG2, OUTPUT); // moteur gauche ARRIERE
 
pinMode(SpeedG, OUTPUT);//vitesse
 
 
 
pinMode(MotorD1,OUTPUT);// moteur droit AVANT
 
pinMode(MotorD2,OUTPUT); // ARRIERE
 
pinMode(SpeedD,OUTPUT); //vitesse
 
 
 
pinMode(Stdby, OUTPUT);//standby
 
 
 
pinMode(servo, OUTPUT); // Servo
 
 
 
pinMode(A0,INPUT);// Normalement VCC Infra gauche TSOP 1 mais IR1
 
pinMode(2, OUTPUT); // IR mais VCC
 
 
 
pinMode(A1, INPUT); // Infra TSOP 2 milieu  mais IR2
 
pinMode(2, OUTPUT); // IR mais VCC
 
 
 
pinMode(A2,INPUT); // Infra TSOP 3 droite mais IR3
 
pinMode(2, OUTPUT); // IR mais VCC
 
 
 
// Sonar
 
 
 
pinMode(SonarEnvoi, OUTPUT);// trig
 
pinMode(SonarRecept, INPUT);//echo
 
 
 
pinMode(A0, OUTPUT);// alimentation ??
 
// Pour utiliser le sonar
 
long lecture_echo;
 
long cm;
 
 
 
 
 
digitalWrite(Stdby,HIGH);
 
Serial.begin(9600);
 
 
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
void ToutDroit()
 
{
 
digitalWrite(MotorD1,HIGH);
 
digitalWrite(MotorD2,LOW);
 
analogWrite(SpeedD,150);
 
digitalWrite(MotorG1,HIGH);
 
digitalWrite(MotorG2,LOW);
 
analogWrite(SpeedG,142);
 
}
 
 
 
 
 
 
 
void reculer()
 
{
 
digitalWrite(MotorD2,HIGH);
 
digitalWrite(MotorD1,LOW);
 
analogWrite(SpeedD,100);
 
digitalWrite(MotorG2,HIGH);
 
digitalWrite(MotorG1,LOW);
 
analogWrite(SpeedG,100);
 
}
 
 
 
 
 
 
 
 
 
void beaucoupG()
 
{
 
// moteur droit tourne, gauche recule
 
digitalWrite(MotorG2,HIGH); // gauche
 
digitalWrite(MotorG1,LOW); // gauche
 
analogWrite(SpeedG,100); // vitesse gauche
 
digitalWrite(MotorD2,LOW); // droite
 
digitalWrite(MotorD1,HIGH); // droite
 
analogWrite(SpeedD,100);// vitesse droite
 
}
 
 
 
 
 
 
 
void beaucoupD()
 
{
 
// moteur gauche tourne, droit recule
 
digitalWrite(MotorG1,HIGH);// gauche
 
digitalWrite(MotorG2,LOW);//gauche
 
analogWrite(SpeedG,100); // vitesse gauche
 
digitalWrite(MotorD1,LOW);// droit
 
digitalWrite(MotorD2,HIGH);// droit
 
analogWrite(SpeedD,100);// vitesse droite
 
}
 
 
 
 
 
void trenteD()
 
{
 
// moteur gauche tourne plus vite que le gauche
 
digitalWrite(MotorG1,HIGH);// gauche
 
digitalWrite(MotorG2,LOW);//gauche
 
analogWrite(SpeedG,VitesseG); // vitesse gauche
 
digitalWrite(MotorD1,LOW);// droit
 
digitalWrite(MotorD2,HIGH);// droit
 
analogWrite(SpeedD,VitesseD);// vitesse droite
 
}
 
 
 
void trenteG()
 
{
 
// moteur droit tourne plus vite que le gauche
 
digitalWrite(MotorG1,HIGH);// gauche
 
digitalWrite(MotorG2,LOW);//gauche
 
analogWrite(SpeedG,VitesseG); // vitesse gauche
 
digitalWrite(MotorD1,LOW);// droit
 
digitalWrite(MotorD2,HIGH);// droit
 
analogWrite(SpeedD,VitesseD);// vitesse droite
 
}
 
 
 
void Rotation () {
 
// Tourne dans le sens des aiguilles d'une montre , moteur droit à l'arrêt, moteur gauche tourne
 
 
 
  beaucoupD();
 
 
 
}
 
 
 
 
 
long mesureSonar() //Mesure la distance avec le sonar
 
{
 
  long lecture_echo; //Receptionne le signal
 
  long cm = 0;
 
  for (int k=0; k<10; k++) //Prend 10 mesures pour les moyennées (éviter les fausses mesures)
 
  {
 
  digitalWrite(SonarEnvoi, HIGH); //Envoie signal
 
  delayMicroseconds(10);
 
  digitalWrite(SonarEnvoi, LOW); //Stop signal
 
  lecture_echo = pulseIn(SonarRecept, HIGH); // Receptionne
 
  cm = cm + lecture_echo/58; //Met à l'echelle
 
  }
 
return (cm/10); //Retourne la distance moyenne
 
}
 
 
 
int DetectObstacle()
 
{
 
long cm;
 
cm=mesureSonar();
 
Serial.print("Distancem : ");
 
Serial.println(cm);
 
if (cm<20)
 
  {
 
    return 1;
 
  }
 
else
 
{
 
    return 0;
 
}
 
}
 
 
 
 
 
int DectectCible()
 
{
 
  return 0;
 
}
 
 
 
void EviteObstacle(long temps)
 
 
    reculer();
 
    delay(400);
 
    while (millis() - (temps+400) <= 500)
 
    {
 
    beaucoupG();
 
    if (DetectObstacle() == 1 && DectectCible() == 0)
 
  {
 
    EviteObstacle(previousMillis = millis());
 
  }
 
 
 
    }
 
 
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
void loop()
 
{
 
  unsigned long currentMillis = millis(); //Donne le temps actuel
 
  previousMillis = currentMillis;
 
  while (DetectObstacle() == 0  && DectectCible() == 0)
 
  {
 
    if (millis() - previousMillis <= delaiTtDroit)
 
    {
 
      ToutDroit();
 
    }
 
    else
 
 
     {
 
     {
      Rotation();
 
      delay(500);
 
 
       previousMillis = millis();
 
       previousMillis = millis();
 +
      while (DetectObstacle() == 0 && etat==0)
 +
        {
 +
          if (Serial.available()>0)
 +
            {
 +
            int action=(int)Serial.read();
 +
            if (action == 253) etat=0; else etat=-1;
 +
            }
 +
          if (millis() - previousMillis <= delaiTtDroit) ToutDroit();
 +
          else
 +
            {
 +
              Rotation();
 +
              delay(500);
 +
              previousMillis = millis();
 +
            }
 +
        }
 +
       
 +
      if (DetectObstacle() == 1)
 +
        {
 +
          EviteObstacle();
 +
        }
 
     }
 
     }
    }
 
 
 
 
 
  if (DetectObstacle() == 1 && DectectCible() == 0)
 
  {
 
    EviteObstacle(previousMillis = millis());
 
    delay(100);
 
  }
 
}
 
  
/*
+
= Bilan : =
Cible1= analogRead(A0); //TSOP 1
+
Cible2= analogRead(A1); //TSOP 2
+
Si nous devions résumer ce BE, nous dirions que c'est d'abord des rencontres, des profs qui nous ont tendu la main,
Cible3= analogRead(A2); // TSOP 3
+
peut-être à un moment où nous ne pouvions pas, où nous étions seuls dans notre galère. Nous sommes fiers du résultat final. Ce BE nous a permis de gagner en autonomie et en confiance en soi grâce à la liberté que nous avons eu pour créer, que ce soit pour notre robot avec l'utilisation du Fabricarium, mais aussi de part le choix de se consacrer à la partie qui nous plait le plus (mécanique, électronique ou informatique). Ce BE a vraiment confirmé notre envie de continuer dans cette voie. Pour finir en beauté cette page wikipédia, voici quelques clichés de notre robot :
 
 
Rotation ()
 
 
 
if (Cible1 || Cible2 || Cible3) // Cible détectée ? {
 
 
 
  StopRotation
 
  Poursuite
 
  {
 
    if (Cible1)
 
    {
 
      90D();
 
    }
 
    else if (Cible1 and Cible2)
 
    {
 
      30D();
 
    }
 
    else if (Cible2)
 
    {
 
      ToutDroit();
 
    }
 
    else if (Cible2 and Cible3)
 
    {
 
      30G;
 
    }
 
    else if (reception_ir1.decode(&decode_ir1)) // TSOP 1 uniquement
 
  {
 
    beaucoupG();
 
    reception_ir.resume(); // reçoit le prochain code
 
     
 
    }
 
    else if (Cible1 and Cible2 and Cible3)  
 
    {
 
      ToutDroit();
 
    }
 
  }
 
 
 
}
 
*/
 
/*if (millis() - previousRotation >= TimeRotation) {
 
 
 
previousRotation = millis();
 
StopRotation ;
 
ToutDroit() ; // Avance 3 secondes
 
 
 
}
 
 
 
}
 
 
 
*/
 
/*if (cm<5 ) {
 
 
 
beaucoupG(); 
 
  
} // put your main code here, to run repeatedly:
+
[[Fichier:jk-face.jpg|200px|thumb|left|"Jean Kévin de face"]]
 +
[[Fichier:jk-dos.jpg|200px|thumb|left|"Jean Kévin de dos"]]
 +
[[Fichier:jk-gauche.jpg|200px|thumb|left|"Jean Kévin de son meilleur profil"]]
 +
[[Fichier:jk-droit.jpg|200px|thumb|left|"Jean Kévin de son autre meilleur profil"]]
 +
[[Fichier:jk-roue.jpg|200px|thumb|left|"Jean Kévin s'entraîne pour le cirque"]]
  
} */
+
Nous avons récupéré le robot avec les deux roues avec moteurs, la roue à bille, 6 piles avec le boitier et le sonar.

Version actuelle datée du 16 juillet 2018 à 18:17


Vidéo HD


Copyright Valérianne et Théo


Notre PROJEEEET:

"Parce que c'est notre projet"


Mission:

Créer un être robotoïde, à la fois autonome et sensible aux commandes par ondes electromagnétiques, capable de se hisser au plus haut rang de l'échelle alimentaire de son écosystème.

Nous nous lançons donc dans la conception d'un prédateur si puissant, dangereux, féroce ! Si bien que la Terre n'aura jamais rien connu de tel depuis la disparition des dinosaures mouahahah



Caractéristiques:

Nom: Jean Kevin

Espèce: Indeterminé mais dangereux

Taille: 10*15*5 (#cpaslataillequicompte)

Vitesse de pointe: 30km/h, soit 8,333 m/s''

Il sera doté d'intelligence artificielle, de 2 roues motrices indépendantes mais reliées par un même axe ainsi que de capteurs ultra son et infra rouge dans le but de détecter obstacles et proies. Il s'intégrera à son écosystème au moyen d'une led infrarouge, qui lui confèrera le titre de prédateur aux yeux de tous les autres robots en présence. Il pourra occasionnelement passer sous contrôle télécommandé grâce à une rapsberry intégrée dans son organisme.


Pour donner vie à Jean Kevin il nous fallait donc:

  • Créer le circuit imprimé, reliant le micro processeur aux différents actionneurs et capteurs.
  • Concevoir un algorythme de fonctionnement.
  • Programmer une "RapsberryPi" de façon à pouvoir contrôler notre robot à distance.
  • Imaginer et réaliser une base mécanique, capable de contenir les organes de Jean Kevin.


Etape 1: Création du circuit imprimé

Nous avons pris comme modèle la carte proposée dans le descriptif du projet
RobotPCB pcb.png
. Nous avons gardé que ce qui nous intéressait pour notre robot, à savoir un Servo moteur, deux Moteurs standars, trois Capteurs infrarouges, un Sonar et différentes leds de contrôle. Le 2nd Servo moteur et le détecteur de suivi de ligne ont donc été enlevé, et la carte réorganisée, pour un placement plus "propre" des trous de fixation ainsi que pour rapprocher une capacité servant à stabiliser le courant entrant dans la carte (en effet la distance entre l'alimentation et la capacité aurait pu créer des variations de courant).

Après avoir modifier le routage de la carte nous avions ceci:

Fritzing.jpg

Nous avons envoyé ce modèle à imprimer en Chine.

Circuit-vide.jpg

Vient ensuite le soudage des composants:

  • Les composants non traversants tels que les résistances, les capacités ou le processeur sont soudés au circuit à l'aide d'une pâte. Après un passage au four, cette pâte durcie et permet d'assurer le lien entre les composants et le circuit.
Soudurev2.jpg
"Four de soudure"


  • Les composants traversants quant à eux sont soudé au fer avec de l'étain.

Soudurev1.jpg

  • Il a fallu effectuer avec l'aide de Thierry des corrections sur certaines soudures à cause de la présence de ponts. On a donc eu recourt au fil à désouder ainsi qu'au décapeur thermique. Notre circuit était maintenant prêt pour ses premiers tests.


  • TEST 1:

Mise sous alimentation du circuit -> une led s'allume ✔

Test-alim.jpg


  • TEST 2:

Installation d'un boot loader à partir d'un Arduino Uno, ce boot permettra à notre circuit de ce comporter comme un arduino, en regardant à chaque démarrage si rien ne se trouve dans la partie USB. Si un programme s'y trouve, celui ci sera exécuté directement. -> installation réussie ✔

Test-arduino.jpg


  • TEST 3:

Programmation directe sur la carte -> ✗ ECHEC

En effet lors du téléversement de notre programme rien ne se passe, l'information n'est pas transmise. Après observation le problème provenait d'un pont présent entre les pâtes de la fiche USB, entre la masse et Rx. La localisation du pont le rendait compliqué à enlever, cependant, à l'aide d'un décapeur thermique, d'un fer à soudé, d'un clou et de Alexandre Boé (sourtout Alexandre Boé) celui ci fut détruit.

  • TEST 3.1:

Programmation directe sur la carte -> ✗ ECHEC encore

Cette fois on s'aperçoit grâce aux leds de contrôle que la communication fonctionne de l'USB au processeur mais pas du processeur à l'USB. Le problème venant probablement d'une mauvaise soudure entre ces deux points. Cette fois la solution fut donnée par Xavier Redon qui souda à nouveau le chemin entre ces deux points.

  • TEST 3.2:

Programmation directe sur la carte -> Le programme fonctionne ✔

Le cerveau de notre prédateur était donc prêt. Il restait à vérifier que ce cerveau communique bien avec ses différents membres (moteurs capteurs etc...)

  • TEST 4:
Test-sonar.jpg

Communication avec les composants:

    • Servo moteur: ✔
    • Moteur A et B: ✔
    • Sonar: ✔
    • Tsop: ✔

Au moment ou plus rien ne semblait pouvoir altérer la croissance de notre JeanKevin, une nouvelle analyse de Xavier Redon lui décela une malformation électronique : En effet lors du déplacement d'une capacité lors du rootage de la carte, une des sortie du FTDI (le 3.3v) fut relié directement à l'alimentation 9V. Fort heureusement l'erreur fut repérée avant la mise sous tension du circuit par la sortie en question, ce qui nous évita de voir notre FTDI griller.

Quelques coups de bistouri/soudeur plus tard notre circuit fut corrigé et intégralement fonctionnel ! Cependant nous avons ici un cerveau vide ou presque, il est temps de le remplir.

Etape 2: L'algorithme de fonctionnement

Jean Kévin, s'il n'est pas télécommandé, doit être autonome, capable d'éviter les obstacles, de rechercher et d'identifier un proie, de la poursuivre et pourquoi pas, d'anticiper sa trajectoire. Nous avons bâti un algorithme se subdivisant en différentes fonctions:

-La recherche d'une cible :

Notre robot s'il ne trouvait pas de proie, devait partir à leur recherche. Dans le but de ne pas toujours chercher dans la même zone, il effectuera donc une rotation de 420° autour de lui même. Sil détecte une proie durant sa rotation il s'arrête, sinon il continue. Une fois sa rotation terminée, le robot avance de 30cm et recommence jusqu'à ce qu'il trouve une cible. La rotation de 420° permet d'éviter d'effectuer des recherches en ligne droite.

Ce mode de recherche donne lieu à l'algorithme ci contre:

-Avancer Tout droit :

ToutDroit() 
digitalWrite(MotorD1,HIGH);
digitalWrite(MotorD2,LOW);
analogWrite(SpeedD,150);
digitalWrite(MotorG1,HIGH);
digitalWrite(MotorG2,LOW);
analogWrite(SpeedG,142);


-Rotation :

void Rotation () 
{
// Tourne dans le sens des aiguilles d'une montre , moteur droit à l'arrêt, moteur gauche tourne
beaucoupD();
}


-Les virages :

Dans un soucis d'efficacité nous avons doté notre robot de 2 modes de rotations: Le choix entre ces deux modes se fera en fonction de l'angle du virage à effectuer.

  • Pour un virage < 30°: On module la vitesse des moteurs pour faire des virages légers
  • Pour un virage > 30°, une des deux roues inversera son sens de rotation pendant que l'autre gardera le même, la rotation sera donc plus rapide et plus forte.

C'est à cette fin que nous avons créer les fonctions ci contre:

void beaucoupG() 
{
// moteur droit tourne, gauche recule
digitalWrite(MotorG2,HIGH); // gauche
digitalWrite(MotorG1,LOW); // gauche
analogWrite(SpeedG,100); // vitesse gauche
digitalWrite(MotorD2,LOW); // droite
digitalWrite(MotorD1,HIGH); // droite
analogWrite(SpeedD,100);// vitesse droite
}
void beaucoupD() 
{
// moteur gauche tourne, droit recule
digitalWrite(MotorG1,HIGH);// gauche
digitalWrite(MotorG2,LOW);//gauche
analogWrite(SpeedG,100); // vitesse gauche
digitalWrite(MotorD1,LOW);// droit
digitalWrite(MotorD2,HIGH);// droit
analogWrite(SpeedD,100);// vitesse droite
}
void trenteD() 
{
// moteur gauche tourne plus vite que le gauche
digitalWrite(MotorG1,HIGH);// gauche
digitalWrite(MotorG2,LOW);//gauche
analogWrite(SpeedG,VitesseG); // vitesse gauche
digitalWrite(MotorD1,LOW);// droit
digitalWrite(MotorD2,HIGH);// droit
analogWrite(SpeedD,VitesseD);// vitesse droite
}
void trenteG() 
{
// moteur droit tourne plus vite que le gauche
digitalWrite(MotorG1,HIGH);// gauche
digitalWrite(MotorG2,LOW);//gauche
analogWrite(SpeedG,VitesseG); // vitesse gauche
digitalWrite(MotorD1,LOW);// droit
digitalWrite(MotorD2,HIGH);// droit
analogWrite(SpeedD,VitesseD);// vitesse droite
}


-Les obstacles :

La détection des obstacles est également très importante, celle-ci s'effectue à l'aide du sonar et donne lieu à 2 fonctions, une fonction calculant la distance entre le sonar et les obstacles, une autre étant une procédure d'évitement des obstacles.

int DetectObstacle()
{
long cm;
cm=mesureSonar();
Serial.print("Distancem : ");
Serial.println(cm);
if (cm<20)
 {
   return 1;
 }
 else
 {
   return 0;
 }
}
void EviteObstacle(long temps)
{   
   reculer();
   delay(400);
   while (millis() - (temps+400) <= 500)
   {
   beaucoupG();
   if (DetectObstacle() == 1 && DectectCible() == 0)
{
   EviteObstacle(previousMillis = millis());
}
}
}

On utilise donc toute ces fonctions dans le loop qui permet au robot de fonctionner de façon autonome en faisant appel aux différentes fonctions. Pour identifier les différentes pin du micro processeur nous avons utiliser l'image ci-contre:

"Atmega"

Puis dans un soucis de lisibilité nous avons modifié dans le programme le numéro des pins par un nom plus explicite:

int broche_reception = A0; 
int MotorG2 = A5;
int MotorG1 = 4;
int Stdby = 9;
int SpeedG = 10;
int MotorD1 = 8;
int MotorD2 = 7;
int SpeedD = 6;
int servo = 3;
int SonarEnvoi = A4;
int SonarRecept = A3;


Etape 3: Conception Mécanique

Jean Kévin possède un cerveau et des organes, il est donc temps de lui donner une structure ! L'idéal est que cette structure s'adapte aux formes des différents composants pour éviter d'avoir trop de trous et fixations.

Nous avons donc eu plusieurs idées et versions de châssis
"Les prémices de Jean Kévin"
pour au final arriver à un châssis sur 2 étages pour permettre la fixation de la carte électronique, de la Rapsberry, d'une batterie et d'un bloc de piles.
"Etage 1"
"Etage 2"



Les composants du robots sont maintenus sur le châssis à l'aide d'un système de cales sur chacun de leurs côtés.

Conception: Les plans du châssis ont donc été créés sur le logiciel en ligne "Onshape". Ce logiciel nous a permis de paramétrer les distances entre les différents éléments du châssis ainsi que de stocker ces distances dans des variables pour rendre plus simple et plus rapide les éventuelles modifications de dimension que nous pouvions apporter à Jean Kévin. La découpe de ces éléments s'effectua à la découpeuse laser. Il a donc fallu exporter les plans de Onshape au logiciel "Inkscape". Le transfert de logiciel a, pour une raison inconnue, engendrer une modification de l'échelle du plan. Après avoir calculé le coefficient entre les dimensions réelles et les dimensions sur Inkscape nous avons pu corriger celles ci et lancer la découpe. Nos éléments découpés, nous n'avions plus qu'à assembler notre robot à l'aide des vis et des cales prévues à cet effet.

Et voilà ! Après plusieurs semaines/mois de gestation, notre Jean Kévin arriva physiquement parmi nous ! Prêt à détruire le monde.



Etape 4: La Rapsberry

Nous souhaitions pouvoir prendre le contrôle de Jean Kévin pour éviter tout débordement. Pour cela, nous l'avons doté d'une Raspberry Pi. Après avoir initialisé la Raspberry, nous avons commencé à concevoir la page html qui servira d'interface entre nous et Jean Kévin. Nous pouvons donc soit le contrôler à l'aide de deux curseurs, un qui gère la vitesse, et l'autre la rotation, soit avec une manette NES connectée en USB sur le PC. Pour prendre le contrôle, il faut se connecter au réseau "Pouloulou" et de se rendre à l'adresse: 192.168.100.1/serial.php

Détail des séances :

Séance du 15 janvier:

Découverte des objectifs et mise en place du cahier des charges. Nous souhaitons réaliser un robot "prédateur". Nous allons concevoir un robot simple car nous voulons nous concentrer sur la partie électronique et informatique. Nous allons réaliser notre circuit imprimé en nous basant sur celui qui nous est donné en exemple. Enfin, nous allons programmer le robot pour qu'il puisse se déplacer de manière autonome. Cependant, lorsqu'il captera un signal wifi avec sa raspberry pi, on pourra le commander depuis notre téléphone.

Séance du 16 janvier:

Nous avons réfléchi sur l'aspect esthétique de notre futur robot. Nous allons lui concevoir une coque pour que tous les éléments soient invisibles de l'extérieur. Nous avons analysé le circuit imprimé fourni par les professeurs sur le logiciel Fritzing pour ne garder que les éléments dont nous avions besoin. Nous avons donc enlevé le détecteur de ligne, un servo moteur. Nous avons passé du temps pour rétablir les connections compromises par la suppression de ces éléments. C'est très intéressant de travailler sur le circuit imprimé, et de voir les différentes vues proposées, qui permettent de bien se rendre compte de la forme de chaque fonction, et comment elles sont reliées entre elles.

Séance du 18 janvier:

Nous avons travaillé sur le routage de notre circuit imprimé pour qu'il soit le plus efficace possible. Nous avons modifié le placement de la capacité 4, qui était trop loin de l'alimentation. Elle ne remplissait pas sa fonction, qui est de lisser la tension dans les câbles. Notre circuit est prêt à être imprimé. Nous avons ensuite commencé le code de notre robot. La difficulté est de savoir dans quelle direction tourner en fonction de là où est la proie et de trouver la manière la plus efficace de tourner dans le but de rattraper la proie. Nous avons 3 capteurs infrarouge sur notre robot. La meilleure solution pour nous est de réduire le champs de balayage des capteurs pour avoir une plus grande information de l'emplacement de la proie. Par exemple, si le capteur de droite et du milieu détecte une présence, alors on fera tourner le robot vers la droite, à l'aide du servo-moteur qui va incliner l'axe des roues. S'il y a uniquement le capteur de droite qui détecte une proie, alors on fera tourner le robot en faisant tourner la roue gauche plus vite que l'autre.

Séance du 19 janvier:

Nous avons commencé le squelette du code. Cependant, nous avons beaucoup d'interrogations sur la façon dont va réagir notre robot. La difficulté est que nous ne pouvons pas tester notre code sur le robot pour le moment et que beaucoup de parties vont rester en suspens. Nous avons choisi d'utiliser la fonction milis(). Cette fonction permet d'effectuer plusieurs actions en même temps, ici tourner et repérer une proie, contrairement à la fonction delay().

Séance du 22 janvier:

Nous nous sommes familiarisés avec le logiciel Onshape. Nous ne sommes pas habitués à raisonner de manière mécanique, c'est-à-dire en étant efficace dans l'utilisation du logiciel comme par exemple en enregistrant les distances dans des variables. Il a été difficile de construire notre dôme en 3d que nous allons mettre à l'arrière du châssis. Il abritera le circuit imprimé et les piles.


Séance du 25 janvier:

Nous avons conçu la base de notre châssis. Nous avons choisi de faire des encoches pour fixer le dôme sur ce châssis. Il reste maintenant à réfléchir à l'emplacement des trous pour fixer le circuit imprimé et les autres éléments (moteurs, servo moteur, sonar et capteurs infrarouge) au châssis. Nous avons ensuite continué notre code en définissant les différentes fonctions principales de notre robot. Par exemple, avancer tout droit, tourner, détecter une cible...

Séance du 26 janvier:

Nous avons commencé à programmer la raspberry pi 3. Elle va nous permettre de commander notre robot depuis notre téléphone. Il faut d'abord lui installer un système d'exploitation, ici nous utilisons la dernière version de la distribution Linux pour Raspberry Pi, Raspbian Jessie Lite.

Séance du 29 janvier:

Nous avons commencé la configuration en point d'accès de la Raspberry. Puis nous avons fait l'inventaire des pièces dont nous avions besoin pour notre circuit imprimé.

Séance du 1 février:

Nous avons continué la configuration de notre raspberry. Nous avons initialisé le serveur web puis nous avons ajouté un nom de réseau pour la Raspberry Pi, nous l'avons appelé jeankevin.org. Enfin, nous avons établi une communication série. Cependant, pour que le serveur Web communique avec notre raspberry il faut passer par un serveur websocket. Ce type de processus est lancé au démarrage de la machine et accapare le port série. Nous ne pensions pas que la configuration de la raspberry nous prendrait autant de temps. Nous avons du mal à utiliser le terminal linux et nous ne connaissons pas les différentes commandes, ce qui ralentit notre progression.


Séance du 5 février:

Nous avons installé le fichier Jsserial et nous avons testé la page web. Le programme ne se lançait pas automatiquement car on ne l'avait pas mis au bon endroit. Les LEDs ne fonctionnaient pas non plus. Ce problème réglé, nous avons pu tester la page web avec l'allumage des LEDs.


Séance du 8 février:

Nous avons commencé la soudure des gros composants. Nous sommes allés en C203. Nous avons déposé une pâte sur les emplacements des composants. Puis nous avons posé les composants dessus. La difficulté est de savoir combien de pâte mettre et de mettre les bons composants aux bons endroits, sans les bouger en manipulant la carte. Ensuite, on passe la carte dans un four qui chauffe à 280 degrés pour faire fondre la pâte sur nos composants.


Séance du 12 février:

Nous avons continué la soudure de notre carte avec le même procédé que la séance d'avant.


Séance du 15 février:

Nous avons réfléchi sur la page Web que nous voulons faire pour contrôler notre robot à partir de notre téléphone grâce à la raspberry. Nous pensons mettre des flèches gauche, droite et tout droit, mais nous pensons aussi mettre des flèches en diagonales. en effet, nous avons prévu des virages à 90 degrés, mais aussi des virages à 30 degrés pour permettre une poursuite plus efficace.

En testant notre circuit, nous avons constaté un pont entre les pattes D+ et D- du connecteur USB. Après ce problème réglé, l'ordinateur détectait notre circuit. Nous l'avons testé avec le programme blink de l'arduino. Il nous a quand même fallu changer le nom du port pour que le programme arduino détecte notre circuit. Cependant, nous avons remarqué que la communication n'allait que dans un sens. C'était un problème de soudure que le professeur a remarqué. Après avoir ressoudé ce qui faisait la liaison entre Tx et Rx, tout fonctionnait normalement. Il nous reste à tester les moteurs, le sonar et les détecteurs infrarouge


Séance du 19 février:

Nous avons testé les moteurs A et B et le sonar à l'aide de petits programmes simples. Nous avons décidé de ne plus utiliser de servo moteur pour les virages de 30 degrés car nous pensons qu'il n'aura pas assez de force pour entraîner la rotation des roues. Nous utiliserons l'emplacement du servo moteur pour y mettre un buzzer pour que notre robot puisse faire un peu de musique.

Séance du 22 février:

Nous avons repris la conception mécanique du robot. Finalement, nous n'allons pas mettre de dôme car notre led infrarouge doit être à l'extérieur, pour pouvoir être captée des autres robots. De plus, il n'y aurait pas eu assez de places pour tous les éléments de notre robot. Nous partons donc sur un robot à deux étages pour avoir la place de mettre le circuit, les piles, la raspberry et la batterie pour la raspberry.

Séance du 5 mars:

Nous avons testé le fonctionnement de notre TSOP. Nous avons remarqué qu'il captait les signaux de la télécommande de très loin. Il faudra se documenter sur les TSOP pour comprendre comment récupérer le signal reçu et comment l'interpréter pour faire prendre une décision au robot (aller un peu à droite, aller beaucoup à gauche ...).

Séance du 8 mars :

Nous avons voulu tester tous les éléments en même temps. Cependant, nous avons remarqué que les moteurs ne tournaient plus. En effet, nous les avions testé avant les vacances, et avant la correction du court circuit par Xavier Redon. En étant uniquement branché sur le PC, les moteurs étaient alimentés par le microprocesseur alors qu'ils doivent uniquement être alimentés par les piles 9V. Une fois les piles branchées, tout fonctionnait correctement. Nous avons aussi continué le code en modifiant les noms des pins que l'ont avait mis aléatoirement par celles correspondantes en se référant à de la documentation.

Séance du 12 mars :

Nous avons fini le dessin de notre robot sur onshape avec toutes les encoches. Nous avons aussi continué le code en faisant des fonctions pour aller tout droit, un peu à droite, un peu à gauche, beaucoup à droite ... Nous avons aussi ressoudé les fils reliés au moteur.

Mardi 13 mars:

Nous sommes allés au Fabricarium pour découper dans du plexiglas le châssis de notre robot. Nous avons eu des problèmes sur l'échelle entre le fichier sur onshape et inkscape.

Séance du 15 mars:

Nous avons monté notre robot et nous avons effectué les premiers tests de mise en marche des moteurs et détection d'obstacles avec le sonar.

Séance du 19 mars:

Nous avons remarqué un défaut au niveau des moteurs : à une même vitesse donnée ils ne tournent pas à la même vitesse donc notre robot ne va pas exactement tout droit. Nous mettons un décalage de 10 entre la vitesse du moteur gauche et celui du moteur droit. Nous avons amélioré le code en utilisant la fonction millis() à la place de la fonction delay() pour permettre de continuer à détecter les cibles et obstacles pendant qu'il avance ou qu'il tourne. Nous avons aussi remarqué que le robot fonctionnait très bien en l'air quand on teste avec nos mains ses réactions, mais une fois au sol, il détecte des obstacles imaginaires. L'environnement est trop complexe pour le sonar qui a une faible précision.


Séance du 26 mars:

Nous avons découpé des morceaux de plexiglas pour mieux maintenir les piles et la raspberry. Puis nous avons essayé d'inclure la gestion des TSOPs dans notre code. Les 3 TSOPs envoient les informations sur le même pin donc nous les allumons un par un pour savoir d'où vient le signal reçu (TSOP de gauche ou TSOP de droite par exemple). Dans un code à part, les TSOPs fonctionnent. Sans TSOPS, le robot fonctionne normalement. Mais lorsqu'on intègre les TSOPs dans le code principal, le robot ne réagit plus normalement, il ne détecte plus les obstacles et ne tourne plus. On pense qu'il reste bloqué dans la boucle de détection d'IR, qui ne fait rien tant qu'il ne capte rien. Alors que s'il ne capte rien, il ne doit pas rentrer dans la boucle de détection d'IR. De plus, les TSOPs ont une trop grande zone de détection donc il est difficile de s'en servir pour se diriger. A cause du manque de temps, nous avons décidé de ne pas mettre les TSOPs sur notre robot. Il est donc capable de se déplacer tout seul mais il ne pourra pas capter les proies.


Séance du 9 avril:

Nous avons commencé la page html qui nous permettra de télécommander le robot. Au début, nous pensions faire quatre flèches dans chaque direction pour le diriger. Puis nous avons décidé de le commander à l'aide de deux curseurs, un qui gère la vitesse et un qui gère les virages. Cependant, les deux curseurs envoyaient en simultanée des informations donc nous avons essayé d'utiliser delay() et millis() dans le code pour réussir à discerner s'il s'agit de la vitesse ou du virage mais cette solution ne fonctionnait pas.

Séance du 16 avril:

Nous avons eu l'idée de faire varier le curseur qui gère la vitesse entre 0 et 125 et le curseur qui gère le virage entre 130 et 250. Si le curseur virage est à 130, il tourne à gauche à 90 degrés, s'il est à 250, il tourne à droite à 90 degrés, et à 190 le robot va tout droit. Nous avons modifié le code en conséquence. Enfin, nous voulons pouvoir choisir à partir de la page html si on prend le contrôle du robot ou si on le laisse en mode automatique. Nous avons eu quelques difficultés à faire en sorte que le mode automatique tourne en permanence tant qu'on ne reprend pas le contrôle.

Loop final

void loop() {

 if (Serial.available()>0)
 {
   int action=(int)Serial.read();
   if (action == 253) etat=0; else etat=-1; // INTELLIGENCE ARTIFICIELLE 
   if (action<125 && action != 0) vitesse = action*2;
   else if (action>=130 && action<190 && vitesse != 0)
     {
      gauche = (190-action)*2;
      droite=0;
     }
   else if (action>=190 && action<251 && vitesse != 0)
     {
      droite = (action-190)*2;
      gauche=0;
     }
   else if (action == 0)
     {vitesse=0; gauche=0; droite=0;}
   else if (action == 254) {arriere(vitesse); delay(1000);}
   

   droite1=vitesse-droite;
   gauche1=vitesse-gauche;
   if (droite1<0) droite1=0;
   if (gauche1<0) gauche1=0;
   ToutDroit3(droite1,gauche1);
 }


 if (etat==0)
   {
     previousMillis = millis();
     while (DetectObstacle() == 0 && etat==0)
       {
         if (Serial.available()>0)
           {
            int action=(int)Serial.read();
            if (action == 253) etat=0; else etat=-1;
           }
         if (millis() - previousMillis <= delaiTtDroit) ToutDroit();
         else
           {
             Rotation();
             delay(500);
             previousMillis = millis();
           }
       }
       
     if (DetectObstacle() == 1)
       {
         EviteObstacle();
       }
   }

Bilan :

Si nous devions résumer ce BE, nous dirions que c'est d'abord des rencontres, des profs qui nous ont tendu la main, peut-être à un moment où nous ne pouvions pas, où nous étions seuls dans notre galère. Nous sommes fiers du résultat final. Ce BE nous a permis de gagner en autonomie et en confiance en soi grâce à la liberté que nous avons eu pour créer, que ce soit pour notre robot avec l'utilisation du Fabricarium, mais aussi de part le choix de se consacrer à la partie qui nous plait le plus (mécanique, électronique ou informatique). Ce BE a vraiment confirmé notre envie de continuer dans cette voie. Pour finir en beauté cette page wikipédia, voici quelques clichés de notre robot :

"Jean Kévin de face"
"Jean Kévin de dos"
"Jean Kévin de son meilleur profil"
"Jean Kévin de son autre meilleur profil"
"Jean Kévin s'entraîne pour le cirque"

Nous avons récupéré le robot avec les deux roues avec moteurs, la roue à bille, 6 piles avec le boitier et le sonar.