Groupe A1 đź’ˇ
Membres du groupe : Maxime ARRESSEGUET Sophie NAVARRO Malick DIALLO Paul SPIRCKEL
SĂ©ance 1 : 23/01/2023 -----------------------------------------------------
Découverte et émergence d'idées
Il s’agissait de la première séance consacrée au projet FabLab. Nous avons tous les 4 commencé à chercher des idées pour notre projet. Celui-ci doit comporter au moins 1 capteur mesurant un ou plusieurs élément(s) dans l’environnement qui nous entoure (température, pression, humidité, luminosité…) Nous souhaitons concevoir un objet qui ait une utilité (pour les étudiants par exemple). Afin d’éveiller notre imagination, nous avons exploré la liste des capteurs proposés par SeeedStudio (Grove - Seeed Studio).
Notre première idée est de concevoir un appareil capable de réaliser plusieurs étapes dans la cuisson d’aliments comme des pâtes, de manière automatique. Plus précisément, il s’agirait d’un appareil posé sur une casserole pleine d’eau, dans lequel se trouve des pâtes par exemple, il est équipé d’une “trappe” qui s’ouvre dès que l’eau bout (ce qui est mesuré à l’aide du thermomètre de l’appareil), ce dernier possède aussi une petite cuillère en bois, qui remue constamment les pâtes lorsqu’elles sont dans l’eau. Enfin, notre appareil enverra une notification ou sonnera une minute avant la fin de la cuisson.
SĂ©ance 2 : 15/02/2023 -----------------------------------------------------
Prise en main du logiciel ARDUINO
La séance d'aujourd'hui constituait en la prise en main du logiciel ARDUINO.
Nous avons découvert la carte arduino UNO.
Une fois que le logiciel est installé, il est possible de télécharger des croquis (sketches) pour contrôler les capteurs sur Arduino. Lors de notre séance nous avons utilisé les capteurs d'humidité et de température.
Les croquis pour utiliser les capteurs sur Arduino peuvent être trouvés en ligne sur des sites tels que GitHub. Ci dessous voici par exemple les croquis d'un composant Grove LCD RGB.
Les croquis sont généralement écrits en langage C et sont téléchargés sur la carte Arduino via le port USB de l'ordinateur.
Pour utiliser les croquis, il est important de comprendre le fonctionnement des capteurs et de choisir le bon croquis pour chaque capteur. Les croquis peuvent être modifiés pour adapter les capteurs aux besoins spécifiques du projet.
La prise en main comprenait notamment le codage des capteurs à notre disposition. Par exemple avec un capteur de température et un écran nous devions prendre en main les codes en C afin d'afficher les valeurs relevées par le capteur sur l'écran.
Voici par exemple le bricolage de code (langage C) que nous avons réussi à réaliser en peu de temps d'après les programmes examples fournis avec les library attachées aux capteurs :
#include <Wire.h>
#include "rgb_lcd.h"
#include <Arduino.h>
#include <Wire.h>
#include "SHT31.h"
SHT31 sht31 = SHT31();
rgb_lcd lcd;
const int colorR = 200;
const int colorG = 100;
const int colorB = 100;
void setup()
{
// set up the LCD's number of columns and rows:
sht31.begin();
lcd.begin(16, 2);
lcd.setRGB(colorR, colorG, colorB);
delay(1000);
}
void loop()
{
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 0);
float temp = sht31.getTemperature();
lcd.print("Temp = ");
lcd.print(temp);
lcd.println(" C "); //The unit for Celsius because original arduino don't support speical symbols
lcd.println(" ");
lcd.setCursor(0, 1);
float hum = sht31.getHumidity();
lcd.print("Hum = ");
lcd.print(hum);
lcd.println(" % ");
}
Grâce auquel nous avons obtenu un résultat plutôt satisfaisant :
DĂ©couverte du M5Stack
La deuxième partie de la séance était consacrée à la prise en main d'une carte M5Stack (similaire à Arduino). Nous avons réalisé le même travail (affichage température et humidité en temps réel (pas d'images)).
SĂ©ance 3 : 17/02/2023 -----------------------------------------------------
Redéfinition du projet
Tout d'abord, nous avons redéfini notre projet pour cette UE. En effet, nous étions partis sur une idée de robot qui faciliterait la cuisson des pâtes ou du riz mais nous nous sommes assez vite rendus compte que ce dernier allait être trop compliqué à réaliser. Ainsi, notre nouvelle idée consiste à créer un robot qui fuit lorsqu'on s'approche de lui. Il sera équipé de capteurs de distance à l'avant, à l'arrière et sur les côtés qui lui permettront d'avancer lorsqu'il détecte quelque chose au niveau de ces capteurs. Il reculera lorsque quelque chose sera placé devant lui. Nous aimerions aussi pouvoir intégrer une fonction qui fera jouer de la musique à notre robot dès qu'il se déplace, pour "narguer" la personne qu'il fuit.
Découverte des outils de modélisation 2D & 3D
Lors de cette séance, nous avons appris à modéliser en 2D et en 3D à l'aide des logiciels Inkscape, FreeCad et OpenScad.
Sur OpenSCAD comme sur FreeCAD, un des exercices était de modéliser un cube troué sur chacune des faces. Ainsi nous avons pris en main plusieurs outils fondamentaux de ce type de logiciels : modéliser des formes simples, les déplacer dans l'espace, les recouper...
- Sur OpenSCAD (fichier cubetrous.scad) :
Code C++ :
$fn=100;
module trous(){
cylinder(51, 5, 5, center=true);
rotate([0,90,0])cylinder(51, 5, 5, center=true);
rotate([90,0,0])cylinder(51, 5, 5, center=true);
};
difference(){cube(50, center = true);
trous();
};
Rendu :
- Sur FreeSCAD (fichier cubetrous.FCStd) :
Rendu :
Projets personnels
A l'issue de cette séance, nous devons chacun modéliser un objet 2D (InkScape) et 3D (OpenSCAD ou FreeCAD) :
Maxime
Projet 2D (InkScape) :
Pour ce projet, j'ai décidé de modéliser sur un carré de 10 cm, la texture d'une jack-o-lantern. Pour cela, j'ai donc commencé par trouver mes sources, afin d'avoir des modèles à suivre :
Je connais maintenant les proportion a respecter, cependant cette texture est composée de 16 pixels de haut et de large. Ainsi pour me faciliter la tache, je modéliserais une citrouille de 16 cm avec des pixels de 1cm que je réduirais ensuite a 10 cm, en gardant les proportions.
J'ai donc commencé par créer ma base, un carré de 10cm de couleur rouge.
Ensuite, j'ai dessiné un segment de droite de longueur 1 cm puis en plaçant le carré initial aux coordonnées (0;0), je pouvais placer assez simplement ce segment pour suivre le contour des parties sombres. Je n'avais plus qu'a respecter la positon de chacun de ces segments sur mon dessin en rentrant sa coordonnée précise à la main. J'ai d'abord fait tout les segments horizontaux :
Enfin, j'ai pivoté le même segment d'exactement 90° et refait la manipulation pour tout les segments horizontaux. Pour finir, j'ai rempli les 3 parties avec l'outil "sceau", de la couleur noire puis le dessin final était prêt. Une fois passé a la graveuse laser, voici le résultat.
Voici le projet 2D final : Citrouille inkscape.svg
Modélisation 3D (Blender) :
Pour commencer, j'ai décidé de faire cette modélisation sur blender, car, même si plus complexe a prendre en main, il me semble plus complet et je vois ca comme l'occasion d'apprendre a maitriser un logiciel plus polyvalent.
J'ai décidé pour cette modélisation, de créer un "pot de fleur" capable de maintenir une rose en lego avec un certain angle. Comme pour la modélisation 2d la première étape a était de trouver un modèle a suivre, or cette fois ci j'ai du le créer moi-même, en prenant soin de mesurer la rose en lego et plus précisément sa tige.
J'ai ensuite construit la forme de base, un cercle, que j'ai étiré puis dans lequel j'ai crée des faces, pour obtenir une surface. Après avoir extrudé et modifié celle ci pour avoir le volume souhaité, je me retrouve avec ceci :
Apres cela, j'ai crée un cylindre penché, auquel j'ai supprimé les deux faces opposés. Ensuite, j'ai extrudé les différents points des deux cercles restant et j'ai enfin réduit la taille des cercles extrudés. Ainsi, en créant des faces entres les nouveaux cercles du haut et du bas, j'avais la forme générale qui allait tenir la tige:
Enfin, après avoir assemblé les deux pièces, je n'ai plus eu qu'a gérer les proportions et la taille générale de l'objet pour quelle corresponde à mes mesures initiales:
Voici donc l'objet final :Pot de fleur.stl
Malick
PROJET 2D (Inkscape) :
Pour mon projet 2D, j'ai décidé de faire une plaque en bois avec un numéro de porte dessus. Les numéros de porte étant écrits avec un style particulier mes compétences artistiques seront mises à rude épreuve. Pour rendre l'exercice plus intéressant il me fallait trouver un style de 4 particulier. J'ai eu 2 idées principales:
- un circuit de course style Mario Kart en forme de 4
- un 4 avec la calligraphie de Zelda BOTW
Je suis finalement parti pour le 4 avec une calligraphie hylienne. Je me suis basé sur ce modèle:
Et voilà mon projet 2D : Numéro porte 4
PROJET 3D (Freecad) :
Pour mon projet 3D, je suis parti pour modéliser un flocon de neige. La structure du flocon étant assez complexe, modéliser le flocon me permettra diverses fonctionnalités de l'outil Freecad.
Tout d'abord il me fallait un croquis que j'allais suivre dans la réalisation de mon flocon. Le voilà :
Pour réaliser la structure sur Freecad j'ai vu que la construction se ferait en deux parties :
- Modélisation de l'étoile centrale à 12 branches
- Modélisation du pourtour avec les 6 branches de givre
L'objectif de la première partie était pour moi de faire une belle étoile. Je l'écris car je m'y suis pris à plusieurs fois avant de réussir à en faire une satisfaisante. Le secret de ma réussite : l'outil '' SYMETRIE '' de Freecad:
Cet outil m'a vraiment sauvé la mise car je n'avais plus qu'à faire une partie de l'étoile puis faire une symétrie axiale pour chacune de mes branches.
Une fois l'étoile faite le vrai défi venait de commencer avec les 6 branches externes.
J'ai donc dû me diviser cette grande en une multitude de petite tâche que voici :
- Faire le ''premier rempart'' qui est l'hexagone avec des espaces
- Ajouter les ''premières routes''
- Faire les premiers arcs de cercles sur les fins de routes grâce à l'outil '' créer un arc ''
- Ensuite on refait la même chose comme une sorte de fractale avec un ''deuxième niveau de route'' et les deuxièmes arc de cercles
Finalement on obtient la givre voulu : Givre
Sophie
Modélisation 2D :
Pour ma modélisation 2D, j'ai utilisé le logiciel Inkscape pour dessiner une guitare. J'ai utilisé l'outil qui permet de tracer des courbes de Bézier et des Segments de droites pour dessiner son contour et ses détails. La forme particulière de la guitare m'a permis de réellement prendre en main cet outil.
La guitare : guitar..svg
Une fois imprimée, voici le résultat :
Un bug sur la découpeuse laser directement a empêché la réalisation d'un des petits trous sur la partie fine de la guitare. Je suis tout de même satisfaite du résultat.
Modélisation 3D :
Pour ma modélisation 3D, j'ai utilisé le logiciel FreeCAD pour créer un poisson. J'ai utilisé la section Sketcher dans un premier temps pour dessiner la forme de mon poisson et de ses nageoirs etout en leur ajoutant des contraintes de symétries, puis je suis passée par Part Design pour leur donner des dimensions ainsi que pour "creuser" les yeux.
Voici mon poisson : poisson.FCStd
Vous pouvez voir ici le résultat de l'impression 3D :
Paul
Modélisation 2D :
Pour ma modélisation 2D, je me suis inspiré de la technique de "wood layering" qui constiste en la superposition de couches de bois, découpées, afin de donner une sensation de profondeur à des objets plutôt en 2 dimensions.
J'ai designé un visage à partir de plusieurs pièces qui je vais pouvoir attacher et faire bouger à ma convenance :
(fichier frenchounet.svg)
Enfin, j'ai utilisé des attaches parisiennes afin d'accrocher mes différentes parties.
Modélisation 3D :
J'ai utilisé FreeCAD pour réaliser cette modélisation. Je voulais continuer à m'entrainer en manipulant les formes de base proposées par le logiciel. Pour mes prochaines modélisations, je souhaites passer par la section Part Design qui me semble beaucoup plus pratique, efficace et ouvre bien plus le champ des possibles.
Pour l'instant du moins, j'ai décidé de réaliser une maison en forme de champignon :
Fichier : Maison Champignon
La seule surprise que j'ai eu, qui résulte d'une erreur, était que le chapeau et le tronc étaient en fait séparés. Je n'avais pas fusionné les deux parties sur FreeCAD, n'ayant pas encore tout à fait bien saisi toutes les subtilités du logiciel. C'est une erreur que je n'ai pas reproduit sur mes modélisations suivantes. Etant donné qu'il y a avait un trou sous le chapeau dans lequel la base ne passait pas, j'ai du le boucher avec des pièces de carton et coller le tout.
De plus cette séance a été pour nous l'occasion de dépasser la partie "software" de cette UE et de voir concrètement ce qu'il été possible de fabriquer. En effet, nous avons assisté a la présentation des machines disponibles au FabLab ainsi qu'a leurs fonctionnements. Nous savons maintenant comment les manipuler en toute sécurité, quelles sont leurs limites, les différents matériaux qu'il est possible d'utiliser ainsi que plusieurs autres subtilités, qui nous ouvre a l'immense champ des possibles de cette UE.
Ainsi, il était venu l'heure des tests. A quelle point cette machine pour graver le bois au laser est elle précise? Combien de temps met-elle pour graver une pièce d'une dizaine de centimètre? Testons. Et quoi de mieux qu'un dessins de Pac-Man pour ce test?
Ainsi, nous avons eu réponse a nos interrogations, en environ 3 minutes, la machine avait finis de graver et découper cette pièce, nous bluffant par sa précision, son niveau de détail et sa simplicité d'utilisation.
SĂ©ance 4 : 21/02/2023 -----------------------------------------------------
Le but de cette séance était de réellement commencer à travailler sur notre projet pour cette UE. Nous avons dans un premier temps décidé de laisser de côté la partie Design de notre projet, car nous hésitons entre plusieurs choix (robot avec une coque en forme de cafard, de pacman ou de mouche), nous nous occuperons donc de l’impression 3D de la coque de notre robot une fois le robot lui même fini.
Test de capteurs
Aujourd’hui nous avons donc choisi les capteurs qui nous paraissaient les plus adaptés pour notre idée de faire un robot qui fuit lorsqu’on s’approche de lui. Nous sommes donc partis sur des capteurs de mouvement. Nous hésitions avec un capteur de distance mais l’idée est bien que notre robot capte un humain ou objet qui le poursuit, donc en mouvement, et non pas n’importe quel objet qui se trouve autour de lui (comme un mur par exemple).
Nous avons donc pu tester différents modèles de capteurs en les codant simplement sur Arduino :
Le premier que nous avons tester fonctionnait parfaitement bien (deux photos de droite). Cependant, nous n'avons pas réussi à trouver (même en fouillant tous les projets imagineables ayant utilisé ce modèle exact de capteur sur internet) comment régler la distance à laquelle le mouvement peut être détecté. En effet, il nous faudrait une distance de 0 à 3 m environ et ce capteur allait jusqu'à 6m.
Nous avons donc essayé un autre modèle (photos de gauche, mini PR Motion sensor) mais les tests ont été un peu plus compliqués dans la mesure où ce capteur était beaucoup trop sensible, en plus du fait que, même si cette fois-ci nous savons régler la distance (il détectait les mouvement jusqu'à 6m autour de lui, ce qui est trop pour nous), cela reviendrait à modifier la carte mère, il nous paraissait donc plus simple de commander un modèle de capteur avec une distance et un angle pré établis qui nous conviennent.
Cette séance nous a permis de nous familiariser avec la programmation de ce genre de capteurs, nous n'avons donc pas produit de programme pour notre projet mais nous avons pu manipuler le programme suivant (fourni sur le Wiki PIR Motion Sensor) :
#define PIR_MOTION_SENSOR 2//Use pin 2 to receive the signal from the module
void setup()
{
pinMode(PIR_MOTION_SENSOR, INPUT);
Serial.begin(9600);
}
void loop()
{
if(digitalRead(PIR_MOTION_SENSOR))//if it detects the moving people?
Serial.println("Hi,people is coming");
else
Serial.println("Watching");
delay(200);
}
Matériel nécessaire :
4x Grove PIR Motion Sensor : https://www.seeedstudio.com/Grove-PIR-Motion-Sensor.html
SĂ©ance 5 : 24/02/2023 -----------------------------------------------------
Cette séance, nous nous sommes fixés plusieurs objectifs :
- Faire la liste des éléments qui composent notre projet
- Prendre en main un relai et l'incorporer dans le circuit d'alimentation d'un moteur
- Prendre en main la commande de signal (programmer la sortie d'un signal de manière interne au M5) sur un M5Stack pour ensuite faire fonctionner un moteur et finalement le relai.
En ce qui concerne la "dissection" de notre projet, voici ce que nous en avons tiré :
- Châssis (à concevoir nous-mêmes)
- Moteurs
- Alimentation (par piles)
- Batterie externe pour alimenter la carte Arduino
- 4x Capteurs Grove PIR Motion Sensor
M5StackArduino UNO- Motor Shield
- Interrupteur manuel pour allumer éteindre complètement
Interrupteur à bascule (pour que le robot s'arrête dès qu'on le récupère et qu'on le met à la verticale)- LED indicatrice ON/OFF
- "Coque" / "Carapace pour fermer le tout et protéger l'électronique (à concevoir nous-mêmes)
- Vis, Ă©crous, tiges, engrenages...? (Ă concevoir nous-mĂŞmes ?)
- Cables Groves, Duponts...
Prise en main du relai :
Nous voulions utiliser un relai pour commander l'activation des moteurs. Nous avons donc fait des esais avec un relai Grove , qui ont été plutôt concluant. Cependant, nous n'avons pas garder cette idée une fois que nous avions utilisé le Motor Shield ARDUINO, qui possède une fonctionnalité similaire en interne.
Commande de signal :
Le but ici était de réussir à programmer la sortie d'un courant depuis le M5, qui servira ensuite à alimenter des relais, eux-même connectés aux moteurs. Nous avons utilisé le Module PLUS du M5 pour avoir une connexion GPIO. Pour l'instant sans succès avec un moteur, nous avons tout de même pu découvrir le vocabulaire nécessaire sur Arduino. Nous testerons à la prochaine séance avec une LED, voir s'il y a des différences.
#include <Arduino.h>
#include <M5Stack.h>
#define GPIO_PIN26 26
#define GPIO_PIN36 36
void setup() {
// put your setup code here, to run once:
M5.begin();
M5.Power.begin();
pinMode(26, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(26, HIGH);
delay(5000);
digitalWrite(26, LOW);
delay(5000);
}
SĂ©ance 6 : 07/03/2023 -----------------------------------------------------
Lors de cette séance, nous avons continué l'avancée du projet de notre robot en travaillant sur :
- Faire fonctionner le moteur avec le module du Motor Shield compatible avec la carte Arduino UNO
- Tester le module de détecteur de mouvement PIR Motion Sensor
- Le montage du robot
Shield Motor :
Nous avons décidé de ne plus utiliser le M5Stack et de nous concentrer sur la carte ARDUINO munie de plusieurs shields.
Pour monter de la bonne manière le moteur au Motor Shield nous avons trouvé une vidéo Youtube qui est très complète :
On y aborde la composition du shield, son fonctionnement, ses utilisations et surtout son application pour un robot, très bien expliqué et qui nous sera très utile dans la suite de notre projet.
Nous nous sommes donc essayés a contrôler un moteur à l'aide de la carte Arduino ainsi que du Shield Motor. Nous avons d'abord utilisé un programme example pour se familiariser avec la synthaxe propre au shield :
// Adafruit Motor shield library
// copyright Adafruit Industries LLC, 2009
// this code is public domain, enjoy!
#include <Arduino.h>
#include <AFMotor.h>
AF_DCMotor motor(1);
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Motor test!");
// turn on motor
motor.setSpeed(200);
motor.run(RELEASE);
}
void loop() {
uint8_t i;
Serial.print("tick");
motor.run(FORWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
motor.setSpeed(i);
delay(10);
}
Serial.print("tock");
motor.run(BACKWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
motor.setSpeed(i);
delay(10);
}
Serial.print("tech");
motor.run(RELEASE);
delay(1000);
}
Puis nous nous sommes attaqués au coeur du projet : commander les moteurs en grâce au détecteur de mouvement. Nous avons écrit un programme qui n'a pas fonctionné, mais qui s'approche fortement de ce que nous cherchons à réaliser :
#define PIR_MOTION_SENSOR 4
#include <Arduino.h>
#include <AFMotor.h>
AF_DCMotor motor(1);
void setup() {
pinMode(PIR_MOTION_SENSOR, INPUT);
Serial.begin(9600);
motor.setSpeed(200);
motor.run(RELEASE);
}
void loop()
{
uint8_t i;
if(digitalRead(PIR_MOTION_SENSOR)) {//if it detects the moving people?
Serial.println("hey dude");
motor.run(FORWARD);
delay(10);
delay(10);
}
else {
Serial.println("oh");
delay(10);
}
}
Et les montages qui nous avons fait :
PIR Motion Sensor :
Du côté du PIR Motion Sensor nous avons testé l'efficacité du détecteur de mouvement et nous avons codé sur Arduino le module. L'objectif était de lui faire afficher sur le moniteur du logiciel Arduino "Hi, People is coming" lorsqu'il détecte du mouvement et "Watching" sinon.
Pour ce faire nous avons trouvé la page wiki du PIR Motion Sensor sur Seeedstudio :
Et voici le code permettant de faire marcher le module :
/*macro definitions of PIR motion sensor pin and LED pin*/
#define PIR_MOTION_SENSOR 2//Use pin 2 to receive the signal from the module
void setup()
{
pinMode(PIR_MOTION_SENSOR, INPUT);
Serial.begin(9600);
}
void loop()
{
if(digitalRead(PIR_MOTION_SENSOR))//if it detects the moving people?
Serial.println("Hi,people is coming");
else
Serial.println("Watching");
delay(200);
}
Le module de détection de mouvement a une portée de détection de 3 mètres (comme prévu par le constructeur) et lorsqu'il y avait du mouvement, il affichait les informations sur le serial monitor du logiciel Arduino :
Ensuite nous nous sommes occupés du montage du robot que nous allions utiliser.
Châssis du robot :
Ce robot utilise le Magician chassis--DG007 que l'on peut trouver sur le site de Gotronic:
Et pour en arriver au résultat ci-dessus nous avons suivi le montage dont on peut trouver le déroulement ici: http://www.pyroelectro.com/tutorials/building_robot_chassis/hardware
SĂ©ance 7 : 14/03/2023 -----------------------------------------------------
Programmation
Dans la continuité de la séance dernière, le groupe de codage a continué à travailler sur le code pour que le moteur fonctionne AVEC le module PIR Motion Sensor. Le plus gros problème était que le code faisait fonctionner le moteur seul mais dès qu'on y incluait le module PIR le moteur s'arrêtait de fonctionner. Lorsqu'on incluait le PIR, la connection du PIR prenait le dessus et bloquait la communication entre la carte Arduino et le Motor Shield. Nous avons changé le port du PIR sur le GROVE de D4 à D3.
Nous avons programmé :
- Un premier code pour qu'un seul moteur fonctionne selon le comportement du PIR Motion Sensor :
#define PIR_MOTION_SENSOR 3
#include <Arduino.h>
#include <AFMotor.h>
int switchstate = 0;
AF_DCMotor motorA(1);
AF_DCMotor motorB(4);
void setup() {
motorA.run(RELEASE);
Serial.begin(9600);
pinMode(PIR_MOTION_SENSOR, INPUT);
}
void loop()
{
switchstate = digitalRead(PIR_MOTION_SENSOR);
if(switchstate == HIGH) {
Serial.println("forward");
motorA.run(FORWARD);
motorA.setSpeed(200);
motorB.run(FORWARD);
motorB.setSpeed(200);
delay(1);
}
else {
motorA.run(RELEASE);
motorB.run(RELEASE);
Serial.println("release");
delay(1);
}
delay(1);
}
- Un deuxième code pour tester la connexion entre 2 moteurs et 2 capteurs, en faisant 2 couples moteur/capteur :
#define PIR_MOTION_SENSOR_FRONT 3
#define PIR_MOTION_SENSOR_BACK 6
#include <Arduino.h>
#include <AFMotor.h>
int switchstate_front = 0;
int switchstate_back = 0;
AF_DCMotor motorA(1);
AF_DCMotor motorB(4);
void setup() {
motorA.run(RELEASE);
motorB.run(RELEASE);
Serial.begin(9600);
pinMode(PIR_MOTION_SENSOR_FRONT, INPUT);
pinMode(PIR_MOTION_SENSOR_BACK, INPUT);
}
void loop()
{
switchstate_front = digitalRead(PIR_MOTION_SENSOR_FRONT);
if(switchstate_front == HIGH) {
Serial.println("front");
motorA.run(FORWARD);
motorA.setSpeed(200);
delay(100);
}
else {
motorA.run(RELEASE);
Serial.println("frontrelease");
delay(100);
}
switchstate_back = digitalRead(PIR_MOTION_SENSOR_BACK);
if (switchstate_back == HIGH) {
Serial.println("back");
motorB.run(BACKWARD);
motorB.setSpeed(200);
delay(100);
}
else {
motorB.run(RELEASE);
Serial.println("backrelease");
delay(100);
}
delay(100);
}
- Un dernier code qui s'approche très fortement du code final, capable de réaliser les actions de déplacement (rotation, ligne droite, marche arrière...) en fonction du capteur actif :
#define PIR_MOTION_SENSOR_FRONT 3
#define PIR_MOTION_SENSOR_RIGHT 5
#define PIR_MOTION_SENSOR_LEFT 9
#define PIR_MOTION_SENSOR_BACK 6
#include <Arduino.h>
#include <AFMotor.h>
int switchstate_front = 0;
int switchstate_right = 0;
int switchstate_left = 0;
int switchstate_back = 0;
AF_DCMotor motorR(1);
AF_DCMotor motorL(4);
void setup() {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.begin(9600);
pinMode(PIR_MOTION_SENSOR_FRONT, INPUT);
pinMode(PIR_MOTION_SENSOR_RIGHT, INPUT);
pinMode(PIR_MOTION_SENSOR_LEFT, INPUT);
pinMode(PIR_MOTION_SENSOR_BACK, INPUT);
}
void loop()
{
//Capteur FRONT
switchstate_front = digitalRead(PIR_MOTION_SENSOR_FRONT);
if(switchstate_front == HIGH) {
Serial.println("front");
motorR.run(BACKWARD);
motorR.setSpeed(250);
motorL.run(BACKWARD);
motorL.setSpeed(250);
delay(3000);
}
else {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.println("frontrelease");
delay(100);
}
//Capteur RIGHT
switchstate_right = digitalRead(PIR_MOTION_SENSOR_RIGHT);
if(switchstate_right == HIGH) {
Serial.println("right");
motorR.run(FORWARD);
motorR.setSpeed(250);
motorL.run(RELEASE);
delay(1000);
}
else {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.println("rightrelease");
delay(100);
}
//Capteur LEFT
switchstate_left = digitalRead(PIR_MOTION_SENSOR_LEFT);
if(switchstate_right == HIGH) {
Serial.println("left");
motorL.run(FORWARD);
motorL.setSpeed(250);
motorR.run(RELEASE);
delay(1000);
}
else {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.println("leftrelease");
delay(100);
}
//Capteur BACK
switchstate_back = digitalRead(PIR_MOTION_SENSOR_BACK);
if (switchstate_back == HIGH) {
Serial.println("back");
motorR.run(BACKWARD);
motorR.setSpeed(250);
motorL.run(BACKWARD);
motorL.setSpeed(250);
delay(100);
}
else {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.println("backrelease");
delay(100);
}
delay(100);
}
(différence entre les modules, délai pour augmenter la sensibilité de détection)
Conception et réadaptation d'un châssis
Dans un deuxième temps nous nous sommes occupés du montage de notre robot et une difficulté est apparue : la taille des composants dont nous disposions n'étaient pas calibrée avec le châssis. En effet, les modules que nous voulions fixer au châssis étaient trop grand ou trop petit par rapport au châssis.
Pour pallier à ce problème, 2 choix s'offraient à nous :
- Recréer le châssis de zéro en y incluant des accroches pour les composants que nous allons y placer (moteurs, capteurs, batteries…)
- Garder le châssis de base et créer des accroches pour les composants que nous allons y placer (moteurs, capteurs, batteries…)
Nous sommes partis sur la 2e option et allons modéliser sur Freecad, 4 accroches pour les modules PIR que nous allons fixer.
Pour accrocher les capteurs, nous avons opté pour une accroche en forme de L plié. Les piles et le module Arduino possèdent des trous pour les visser directement. On fixera donc les piles en dessous du robot et l'Arduino au dessus. Les moteurs quant à eux, seront au milieu avec les accroches pré-fournies. Enfin, pour l'interrupteur et la LED, nous les placerons à côté des piles en fabriquant une accroche. Ainsi tous les composants seront placés et il ne restera plus qu'à modéliser une "coque" (le corps du robot).
Modèle 3D des supports pour PIR Motion Sensor (fichier Support capteurs.FCStd & Support capteurs - Inverse.FCStd) :
SĂ©ance 8 : 21/03/2023 -----------------------------------------------------
Impression des supports pour capteurs
Durant cette séance, nous avons fait des finitions sur le modèle 3D des supports pour les PIR Motion Sensor, puis nous en avons lancé deux en impression 3D pour être sûr de voir le résultat avant la fin de la séance. Les résultats final était très satisfaisant mais il nous a tout de même permis de repérer deux problèmes :
- Un problème de modélisation : erreur humaine. Le long trou du socle n'avait pas été perforé entièrement sur le fichier .stl, nous nous sommes donc retrouvés avec un socle bouché et trop épais pour pouvoir tenter de réparer le problème.
- Les trous prévus pour fixer les capteurs étaient trop proches d'environ 1 mm.
Nous avons en même temps démarré les impressions 3D et découpes laser pour terminer nos projets personnels (séance 3).
Soudures
Avant d'assembler le robot, nous devions nous charger de souder tous les fils : soit ensembls, soit avec des moteurs... Nous nous sommes initiés à la soudure, à la façon d'étaler de l'étain sur des fils, de placer des gaines thermorétractables. A la fin de la séance, il ne nous manquait plus que 4 soudures afin de rallonger certains fils.
DĂ©but de l'assemblage du robot
Nous avons surtout remonter ensemble les moteurs, le bloc de piles et la carte ARDUINO sur le chassis du robot.
SĂ©ance 9 : 28/03/2023 -----------------------------------------------------
RĂ©sultat final des supports de PIR Motion Sensor
Nous avons récupéré les supports pour les capteurs qui nous avions imprimé en 3D. Le résultat était très satisfaisant :
- Ils sont solides
- Ils sont peu encombrants
- L'espacement des trous pour les vis est exact pour bien faire tenir le capteur
- Le diamètre des trous de vis est parfait : suffisamment étroit pour ne pas avoir besoin d'écrou à l'arrière sans pour autant devoir forcer énormément lorsque qu'on visse.
(nous n'avons finalement pas utilisé le modèle ci-dessus mais la version où la fixation est positionnée sur le dessus, que l'on peut voir dans les images suivantes)
Fin de l'assemblage du robot
Avant de pouvoir nous pencher sur la programmation, il fallait finir d'assembler le robot. Nous avons commencé par quelques soudures afin de rallonger les fils reliés aux moteurs pour qu'ils atteignent les entrées du Motor Shield. Ensuite nous avons fait passer les fils à travers les trous du châssis, de manière à avoir un câblage clair et pratique. Nous les avons connecté aux bonnes entrées. On a aussi attaché les capteurs à l'avant et à l'arrière du robot.
L'assemblage final a été réalisé quelques jours plus tard, afin de s'occuper des détails : l'emplacement de la batterie pour la carte Arduino, fixer (solidement) l'interrupteur. Ceci a été fait avec des colliers de serrage car ils sont pratiques, faciles à poser et simple à retirer si on veut changer quoi que ce soit. Le robot, finalement, ressemble à ceci :
Echecs du code
Une fois que l’assemblage du robot était fini, il était temps de tester notre code final de la dernière séance, mais avec seulement deux capteurs (par défaut de commande, les deux derniers ne sont jamais arrivés). Placés à l’arrière du robot, avec un sur chaque côté, notre robot devrait capter tout ce qui arrive des deux côtés et derrière lui.
Nous avons donc remodifer le code : une détection à l’arrière gauche du robot le fait tourner à droite puis avancer et une détection à l’arrière droit le fait tourner à gauche puis avancer, en prenant soin d’arrêter les moteurs au bout d’un certain temps pour que le robot ne capte pas les murs ou le plafond qui sont en mouuvement par rapport à lui lorsqu’il bouge.
Lorsqu’on a lancé le code, le robot se mettait certes à tourner et à avancer lorsqu’on l’allumait, mais soit de manière très aléatoire, soit il arrêtait complètement de capter au bout d’un certain moment (malgré le fait qu’on avait mis des délais assez courts). En plus de tout ça, il avait l’air de ne capter que du côté gauche, car il ne tournait qu’à droite à chaque fois qu’on l’allumait.
Théories sur les différents problèmes qu’on a rencontré :
- comme à la séance 7, des branchements se gênerait entre eux
- un des capteurs était peut être défaillant
- les délais ne convenaient peut être pas au temps de réaction des capteurs
- les capteurs se marchaient l’un sur l’autre (quand l'un détecte un mouvement, l’autre aussi et les codes se confondent)
- une partie du code (le premier if du capteur gauche) aurait la priorité sur une autre (le if du deuxième capteur)
Après avoir essayé de modifier les délais, de changer les branchements, de tester les capteurs un par un, notre code ne fonctionnait toujours pas comme on le souhaitait. Les capteurs se gênaient donc entre eux et la première partie du code était prioritaire sur la deuxième, ce qui gênait la détection du capteur droit.
Il fallait donc que l’on trouve :
- soit une manière de mettre les deux conditions du code sur le même pied d’égalité
- soit une commande qui nous permettrait d’éteindre un capteur lorsque l’autre détecte du mouvement, afin qu’ils ne se gênent plus entre eux.
Voici notre code défectueux :
#define PIR_MOTION_SENSOR_RIGHT 6
#define PIR_MOTION_SENSOR_LEFT 3
#include <Arduino.h>
#include <AFMotor.h>
int switchstate_right = 0;
int switchstate_left = 0;
AF_DCMotor motorR(1);
AF_DCMotor motorL(4);
void setup() {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.begin(9600);
pinMode(PIR_MOTION_SENSOR_RIGHT, INPUT);
pinMode(PIR_MOTION_SENSOR_LEFT, INPUT);
}
void loop()
{
//Capteur RIGHT
switchstate_right = digitalRead(PIR_MOTION_SENSOR_RIGHT);
if(switchstate_right == HIGH) {
Serial.println("right");
motorR.run(FORWARD);
motorR.setSpeed(250);
motorL.run(BACKWARD);
delay(500);
motorR.run(FORWARD);
motorL.run(FORWARD);
delay(1000);
}
//Capteur LEFT
switchstate_left = digitalRead(PIR_MOTION_SENSOR_LEFT);
else if(switchstate_right == HIGH) {
Serial.println("right");
motorL.run(FORWARD);
motorR.setSpeed(250);
motorR.run(BACKWARD);
delay(500);
motorR.run(FORWARD);
motorL.run(FORWARD);
delay(1000);
}
else {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.println("release");
delay(1000);
}
}
Finition du code et test
C'est quelques jours plus tard que nous avons trouvé la solution. En se documentant, on se rend compte qu'il n'existe pas de synthaxe pour "éteindre" un capteur. En revanche une autre idée nous vient. Afin d'utiliser le signal transmis par le capteur, on doit déclarer au début de notre programme sur quelle entrée la capteur est connecté, et surtout le fait qu'il s'agisse d'une entrée.
pinMode(PIR_MOTION_SENSOR_RIGHT, INPUT);
Arduino s'attend alors à recevoir un signal. Or rien ne nous empêche de forcer le Pin du capteur à être une sortie. De cette façon, Arduino ne regarde que les signaux sortants (qui n'existent pas puisque ça n'aurait pas de sens) et ne fait plus attention aux signaux entrants : c'est une sorte de sens unique. On implémente alors deux lignes qui permettent en début de condition de mettre l'autre capteur en OUTPUT, suivit de toutes les commandes puis à la toute fin, une ligne pour faire passer de nouveau l'autre capteur en INPUT. Nous n'avions plus de problèmes de superposition de commandes.
Nous avons également ajouter du temps d'arrêt directement à la fin des commandes de mouvement et pas seulement avec une commande à part. Ceci évite au robot d'avoir un air hystérique en enchaînant immédiatement avec un autre mouvement.
if(switchstate_back == LOW) {
if(switchstate_front == LOW) {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.println("release");
delay(2000);
}
}
Enfin, nous avions utilisé une commande Else pour immobiliser le robot. Afin d'être certain que cette condition se réalise, nous avons préféré opter pour une imbrication de conditions : de cette façon on est sûr que le robot ne bouge pas quand les deux capteurs ne détectent rien. C'est ainsi que arrivons au programme final :
#define PIR_MOTION_SENSOR_FRONT 6
#define PIR_MOTION_SENSOR_BACK 3
#include <Arduino.h>
#include <AFMotor.h>
int switchstate_front = 0;
int switchstate_back = 0;
AF_DCMotor motorR(1);
AF_DCMotor motorL(4);
void setup() {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.begin(9600);
pinMode(PIR_MOTION_SENSOR_FRONT, INPUT);
pinMode(PIR_MOTION_SENSOR_BACK, INPUT);
}
void loop()
{
switchstate_front = digitalRead(PIR_MOTION_SENSOR_FRONT);
switchstate_back = digitalRead(PIR_MOTION_SENSOR_BACK);
if(switchstate_front == HIGH) { //Capteur FRONT
pinMode(PIR_MOTION_SENSOR_BACK, OUTPUT);
Serial.println("front");
motorR.run(FORWARD);
motorR.setSpeed(250);
motorL.run(BACKWARD);
motorL.setSpeed(250);
delay(200);
motorR.run(BACKWARD);
motorR.setSpeed(250);
motorL.run(BACKWARD);
motorL.setSpeed(250);
delay(3000);
motorR.run(RELEASE);
motorL.run(RELEASE);
delay(3500);
pinMode(PIR_MOTION_SENSOR_BACK, INPUT);
}
if(switchstate_back == HIGH) { //Capteur BACK
pinMode(PIR_MOTION_SENSOR_FRONT, OUTPUT);
Serial.println("back");
motorR.run(BACKWARD);
motorR.setSpeed(250);
motorL.run(FORWARD);
motorL.setSpeed(250);
delay(200);
motorR.run(FORWARD);
motorR.setSpeed(250);
motorL.run(FORWARD);
motorL.setSpeed(250);
delay(3000);
motorR.run(RELEASE);
motorL.run(RELEASE);
delay(3500);
pinMode(PIR_MOTION_SENSOR_FRONT, INPUT);
}
if(switchstate_back == LOW) {
if(switchstate_front == LOW) {
motorR.run(RELEASE);
motorL.run(RELEASE);
Serial.println("release");
delay(2000);
}
}
}
Célébration (avec un peu de chance)
Notre projet est alors terminé, ci-après quelques tests (plus ou moins convaincants) qui démontre du bon fonctionnement du programme et de l'électronique. Un léger "soucis" concerne l'inclinaison des capteurs sur leur support. Le robot étant au niveau du sol fait que le capteur de devant (respectivement de l'arrière) arrive à capter du côté opposé au sien. A part cela, nous sommes très satisfait.