Binome2017-2
Copyright Valérianne et Théo
Sommaire
- 1 Notre PROJEEEET:
- 2 Séance du 15 janvier:
- 3 Séance du 16 janvier:
- 4 Séance du 18 janvier:
- 5 Séance du 19 janvier:
- 6 Séance du 22 janvier:
- 7 Séance du 25 janvier:
- 8 Séance du 26 janvier:
- 9 Séance du 29 janvier:
- 10 Séance du 1 février:
- 11 Séance du 5 février:
- 12 Séance du 8 février:
- 13 Séance du 12 février:
- 14 Séance du 15 février:
- 15 Nos codes de test:
- 16 CODE
Notre PROJEEEET:
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é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.
Pour donner vie à Jean Kevin il nous fallait donc: -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.
Etape 1: Création du circuit imprimé
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 envoyer ce modèle à imprimer en Chine.
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. 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.
TEST 1: Mise sous alimentation du circuit -> une led s'allume ✔
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 co sera exécuter directement. -> installation réussi ✔
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 (...). 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: 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 4: Communication avec les composants: Servo moteur: ✔ Moteur A et B: ✔ 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. (Sreen) 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
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:
-La recherche d'une proie :
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.
Ce mode de recherche donne lieu à l'algorythme ci contre:
-L'évitement d'obstacle :
-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°, c'est l'axe sur lequel sont fixés les roues qui tournera grâce à un Servo moteur. 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.
C'est à cette fin que nous avons créer l'algorythme ci contre:
Etape 3: Conception Mécanique
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:
Etape 4: La Rapsberry
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 son raspberry pi, on pourra le commander depuis notre téléphone.
Matériel nécessaire pour la partie mécanique: - Châssis à partir de plexiglas - Roues motorisées - Roue libre (bille) - Servo-moteurs - Boîtier Piles
✓
✓
✓
✓
✓
✓
✓
Composants électroniques nécessaires:
- Carte électronique - Micro-contrôleur ATMega328p - Adaptateur FTDI (USB-UART) et port USB - Contrôleur-moteur - 3 Capteurs infrarouge - Capteur Ultrasons - Régulateur 5V - Quartz 16 MHz - 2 capacités 10microF - 6 capacités 100nF - 1 capacité 1mF - 1 résistance 1kOhm - 1 résistance 220Ohm - 1 Diode
✓
✓
✓
✓
✓
✓
✓
✓
✓
✓
✓
✓
✓
✓
Matériel informatique:
- Carte Raspberry Pi 3 - Caméra - Batterie Raspberry
Séance du 16 janvier:
Nous avons réfléchi sur l'aspect esthétique de notre futur robot. (Image ?) 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.
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é 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:
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...
Notre code:
- include <Servo.h>
Servo myServo; unsigned long previousRotation = 0; unsigned long TimeRotaion = 5000
void setup() {
pinMode(1, OUTPUT); // moteur gauche 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() {
digitalWrite(1,HIGH); digitalWrite(2,HIGH); //delay
}
int StopRotation() {
digitalWrite(1,LOW); digitalWrite(2,LOW); //delay
}
int 90D()
{
digitalWrite(1,HIGH); digitalWrite(2,LOW); // delay
}
int 90G() {
digitalWrite(1,LOW); digitalWrite(2,HIGH); //delay
}
int 30D() {
AngleDir = analogRead(A4); digitalWrite(3,AngleDir-30); // ou +30 en fonction du servo //delay
}
int 30G() {
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); Cible1= analogRead(A1); Cible2= analogRead(A2); Cible3= analogRead(A3);
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 (Cible3) { 90G; } else if (Cible1 and Cible2 and Cible3) { ToutDroit(); } } } if (millis() - previousRotation >= TimeRotation) { previousRotation = millis(); StopRotation ; toutdroit() ; // Avance 3 secondes }
}
if (DistanceObstacle < 10) { 90G(); } // put your main code here, to run repeatedly:
}
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é. (Image ?)
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.
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
Nos codes de test:
http://www.chicoree.fr/w/images/9/95/ATmega328P_vs_Arduino_pin_mapping.png
Test Moteur A et B simultanéments:
void setup() {
// 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
}
void loop() {
// 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:
void setup() {
// put your setup code here, to run once: pinMode(8,OUTPUT); pinMode(7,OUTPUT); pinMode(6,OUTPUT); //vitesse pinMode(9,OUTPUT); // standby
}
void loop() {
// put your main code here, to run repeatedly: analogWrite(6, 1000); digitalWrite(7,HIGH); digitalWrite(8,LOW); digitalWrite(9,HIGH); delay(2000); analogWrite(6, 500); digitalWrite(7,LOW); digitalWrite(8,HIGH); digitalWrite(9,HIGH); delay(2000);
}
Test moteur B:
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));
}
CODE
include <Servo.h>
Servo myServo; unsigned long previousRotation = 0; unsigned long TimeRotaion = 5000
void setup() {
pinMode(4, OUTPUT); // moteur gauche AVANT pinMode(A5, 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
pinMode(3, OUTPUT); // Servo
pinMode(A0,OUTPUT);// VCC Infra gauche TSOP 1 pinMode(2, INPUT); // IR
pinMode(A1, OUTPUT); // Infra TSOP 2 milieu pinMode(2, INPUT); // IR
pinMode(A2, OUTPUT); // Infra TSOP 3 droite pinMode(2, INPUT); // IR
// Sonar
pinMode(A4, OUTPUT);// trig
//digitalWrite(trig, LOW);
pinMode(A3, INPUT);//echo
//Serial.begin(9600);
pinMode(A0, OUTPUT);// alimentation ??
}
int ToutDroit() {
digitalWrite(8,HIGH); digitalWrite(7,LOW); digitalWrite(4,HIGH); digitalWrite(A5,LOW); //delay
}
int StopRotation() {
// moteur gauche se met aussi à l'arrêt
digitalWrite(4,LOW); digitalWrite(A5,LOW);
//delay
}
int 90D() {
// moteur gauche tourne, droit à l'arrêt digitalWrite(4,HIGH); // gauche digitalWrite(A5,LOW); // gauche digitalWrite(7,LOW); // droite digitalWrite(8,LOW); // droite // delay
}
int 90G() {
// moteur droit tourne, gauche à l'arrêt digitalWrite(4,LOW);// gauche digitalWrite(A5,LOW);//gauche digitalWrite(7,LOW);// droit digitalWrite(8,HIGH);// droit //delay
}
int 30D() {
AngleDir = analogRead(A4); digitalWrite(3,AngleDir-30); // ou +30 en fonction du servo //delay
}
int 30G() {
AngleDir = analogRead(A4); digitalWrite(3,AngleDir+30); // ou - 30 en focntion du servo //delay
}
int Rotation () {
// Tourne dans le sens des aiguilles d'une montre , moteur droit à l'arrêt, moteur gauche tourne
digitalWrite(4,HIGH); digitalWrite(A5,LOW); }
void loop() {
Obstacle = analogRead(A0); Cible1= analogRead(2); //TSOP 3 Cible2= analogRead(2); //TSOP 2 Cible3= analogRead(2); // TSOP 1
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 (Cible3) { 90G; } else if (Cible1 and Cible2 and Cible3) { ToutDroit(); } }
}
if (millis() - previousRotation >= TimeRotation) {
previousRotation = millis(); StopRotation ; toutdroit() ; // Avance 3 secondes
}
}
if (DistanceObstacle < 10) {
90G();
} // put your main code here, to run repeatedly:
}