Groupe A2 : testeur de réflexe
Prima BARCIET, Jules LAMARE, Milo BERTRAND, Coline CHEVALLIER
Journal de bord :
-
Activités d'introduction :
30/01/2024 : découverte du Fablab
-
Objectifs du FabLab :
Le premier FabLab fut créé au MIT par Neil Gershenfeld en lien avec son cours "How to make (almost) anything". "Fab" correspond à fabrication numérique et "Lab" à laboratoire de prototypage. Son objectif était de proposer aux étudiants un espace ouvert leur permettant de donner vie à leurs projets scientifiques. Depuis, un réseau international dans le monde entier à été développé, le FabLab de Sorbonne Université en faisant partie. Pour prendre part à ce réseau, plusieurs conditions doivent être respectées, notamment la présence de certaines machines.
-
Outils et machines :
On retrouve ainsi au FabLab parmi tant d'autres machines:
- des imprimantes 3D
- des découpeuses laser (pour le plastique et bois) et à eau (pour le métal)
- des fraiseuses électroniques, ...
Il y a aussi des salles réservées à l'électronique (soudure) ou encore le travail du bois, un espace bibliothèque, un espace pédagogique, et des tables et tableaux blancs disponibles pour travailler en groupe. Des outils et composants électroniques sont également à disposition.
-
Documentation :
Une des valeurs principales du FabLab est le partage, c'est pourquoi il est recommandé de travailler en groupe mais surtout il est important de veiller à la reproductibilité des projets et expériences réalisés par tous, via la documentation sur la plateforme Wiki. Il est obligatoire de fournir un résumé de nos travaux. On retrouve ainsi sur le site des tutoriels pour la prise en main des machines et les archives de tous projets, personnels et pédagogiques, réalisés par les étudiants et personnels du FabLab.
06/02/2024 : introduction à la CAO
Lors de cette séance, nous avons pu découvrir le Computer-Aided Design, Conception Assistée par Ordinateur (CAO) en Français, qui est une partie importante de l'apprentissage de la FabAcademy. Nous utiliserons des logiciels gratuits, en accord avec les valeurs de partage du FabLab.
-
Design 2D :
Le design 2D, pour les découpeuses laser, se fait sur ordinateur via le logiciel Inkscape au FabLab. Ce logiciel permet d'obtenir des fichiers vectoriels au format SVG sans pixellisation ou problèmes de résolution, en créant les images avec des formes géométriques.
Des conventions doivent être absolument respectées pour que les découpeuses laser marchent correctement :
- utiliser des lignes d'1 pixel d'épaisseur
- utiliser des lignes rouges (#FF0000) pour la découpe
- le bleu correspond au marquage (juste des traits)
- utiliser des lignes noires pour la gravure (qui correspond à une puissance plus faible du laser)
Certaines commandes peuvent être utiles également : Ctrl + Maj + F pour déterminer la largeur des traits, clic sur l'objet + Maj + couleur pour changer la couleur du trait par exemple. Il est utile de regarder les tutos disponible sur ce wiki pour s'approprier d'avantage le logiciel.
Nous nous sommes entraînés au dessin 2D en suivant le modèle donné par l'enseignant :
Il nous faudra d'ici quelques semaines, dans le cadre de l'UE, faire un dessin 2D sur Inkscape sur une planche 30cm*30cm pour essayer les découpeuses laser par nous même.
-
Design 3D :
Nous pouvons utiliser 2 logiciels différents pour le design 3D nécessaire à l'impression 3D : OpenSCAD et FreeCAD. Ces logiciels nous donnent des fichiers 3D au format STL en générant du G-code, correspondant aux déplacements selon x, y et z de la pointe de l'imprimante.
Les éléments suivants peuvent être utiles sur les logiciels :
- sur OpenSCAD : il faut fermer chaque ligne de code par des points virgules, la fonction F5 pour avoir un aperçu de l’objet généra par le code, F6 pour avoir l’objet final,
- sur FreeScad : si le logiciel bug, c’est sûrement qu’une tâche en cour n'a pas été terminée/fermée, on peut utiliser la section “Part” pour générer des objets 3D directement et “Sketcher” pour travailler en 2D avant de transformer le dessin en objet 3D.
Nous pouvons chercher sur Internet “nom du logiciel + cheatsheet” pour de l’aide sur les commandes
Nous nous sommes aussi entraînés au dessin 3D en suivant les modèles donnés par l'enseignant :
Il nous faudra d'ici quelques semaines, dans le cadre de l'UE, faire une modélisation 3D sur un de ces deux logiciels dans des dimensions 15cm*15cm*15cm pour essayer les imprimantes 3D par nous même.
-
Démonstration imprimantes 3D et découpeuses laser :
Avant d’utiliser une machine/un ordinateur des salles de découpe et impression 3D, il faut noter que l’on s’est connecté sur les carnets de log in.
On utilise du matériau PLA dans les imprimantes 3D, il est disponible en plusieurs couleurs. 2 types d’imprimantes sont disponibles : Pro2 et Pro2Plus. Nous devons choisir la densité de remplissage et la hauteur des couches. Plus les couches sont fines, plus l’impression est longue : c’est pourquoi il nous est conseillé d’utiliser des épaisseurs de 0.4mm et un remplissage de 15 ou 20%.
Différents rendus des épaisseurs de couches des imprimantes 3D
Les fichiers 3D doivent être ouverts sur IdeaMaker, un autre logiciel, avant d'imprimer sur les machines. Cela nous permet notamment de visualiser les supports automatiquement créés, ainsi que l’aide à l’adhérence et les différentes remplissages grâce à un code couleur. Si l’aperçu nous convient, on télécharge le fichier sur l’imprimante en réseau ou on “exporte sur le disque local” (clé USB) avant de la connecter sur la machine. Il est important de rester pendant les 20 premières minutes de l'impression, car la majorité des problèmes ont lieu au début (fil mal équipé, plateau pas droit, ...). A la fin de l’impression, il faut décoller l’objet du plateau avec une raclette.
Au Green FabLab est aussi disponible une imprimante 3D à base de résine liquide qui est ensuite solidifiée, ce qui permet des rendus plus lisses.
Quant aux découpes laser, il ne faut pas monopoliser les machines pendant plus de 30mn, la découpe en soit ne dure que quelques secondes. Si nous sommes les premiers de la journée à utiliser la machine, il faut l'allumer et la laisser se remettre en place avec le capot fermé. Il faut toujours tester sur des chutes au préalable, pour vérifier si c’est la bonne épaisseur de matériau notamment (surtout lorsqu’on découpe des encoches). Nous devons rester pendant tout l'usinage pour prévenir des potentiels départs de feu. Il ne faut pas utiliser son propre matériau à moins d’en connaître précisément la constitution : par exemple, le PVC contient du chlore qui, en brûlant sous le laser, dégage des vapeurs similaires au gaz moutarde. Il faut placer la plaque de matériau à la distance focale de la lentille de la découpeuse à l’aide d’un calpige sur les Speedy100, et placer l’origine du laser sur le dessin (en haut à gauche préférablement). Avant de commencer la découpe, on vérifie que l’on a sélectionné la bonne machine (comme une impression classique sur papier) et le bon matériau dans le logiciel.
Différents rendus de la découpeuse laser sur les différents matériaux disponibles
Les autres découpeuses sont réglées automatiquement sur la bonne distance focale, et le logiciel sur lequel le dessin 2D ne s’ouvre pas sur Inkscape mais Trotec.
Dans tous les cas, les explications et tutoriels sur l’utilisation des machines sont disponibles en salles d’impression et de découpage, mais aussi sur le Wiki.
13/02/2024 : capteurs et cartes Arduino
Nous nous sommes concentrés sur l'utilisation de capteurs et la programmation de cartes Arduino.
Dans Arduino IDE, en branchant le circuit Arduino à l'ordinateur, nous pouvons entrer du code et effectuer des actions. Un exemple de code bien connu est le blink, qui permet de faire clignoter une LED à court intervalle de temps, et nous avons eu l'occasion de le tester. Premièrement, directement sur la LED de la carte Arduino avec le code suivant :
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
#include <Arduino.h>
#include <Wire.h>
#include "SHT31.h"
SHT31 sht31 = SHT31();
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("begin...");
sht31.begin();
}
void loop() {
float temp = sht31.getTemperature();
float hum = sht31.getHumidity();
Serial.print("Temp = ");
Serial.print(temp);
Serial.println(" C"); //The unit for Celsius because original arduino don't support speical symbols
Serial.print("Hum = ");
Serial.print(hum);
Serial.println("%");
Serial.println();
delay(1000);
}
Sur le site internet GoTronic qui est le fournisseur des capteurs du FabLab, nous pouvons retrouver la majorité des capteurs disponibles ici pour nos projets finaux.
Nous avons ensuite eu l'occasion de brainstorm sur notre projet. Nous avons penser à faire une machine interactive pour calculer le temps de réaction d'une personne. Il faudra nous assurer d'avoir un protocole précis pour calculer une grandeur cohérente avec incertitudes. Par exemple, quel type de personne utilise la machine : sportif ou non, entraîné ou non, femme/hommes, debout ou assis; pour faire des prédictions et tracer des graphiques de données. Nous utiliserons des capteurs sensoriels, des led colorées piur indiquer le moment où appuyer, et des fonctions permettant de calculer le temps et la moyenne de temps entre les actions.
Projets personnels
Prima
Objet 2d à la découpeuse laser
Pour mon projet 2D j'ai d'abord voulu utilisé un dessin que j'avais réalisé moi même
Or, en vectorisant l'image via inskape je me suis rendu compte que les contrastes n'étaient pas assez apparents, j'ai donc préféré changer d'image.
J'ai donc choisi la vague de Kanagawa comme dessin à imprimer avec la découpeuse laser.
J'ai choisi une version de la vague en noir et blanc pour que les contrastes soient cette fois bien visibles.
J'ai incorporé cette image dans inskape et j'ai ensuite effectué un clique droit afin de sélectionner l'action "vectoriser l'image". j'ai ensuite supprimer le premier calque del 'image originale. On obtient donc notre image en 2D sous format .svg que l'on peut transférer dans l'ordinateur de la découpeuse laser trotec speedy 360.
j'ai choisi une plaque de chute de peuplier 3mm et j'ai ajouté autour de mon dessin un rectangle rouge afin que la découpeuse laser puisse graver le dessin mais aussi en découper le pourtour.
Le résultat de cette gravure est visible ci dessous :
je suis satisfaite du résultat à l'exception d'un endroit sur les cotés de la gravure au niveau de a signe du milieu ou la découpeuse a semblé surchauffé puisque le bois a légèrement brulé.
Objet 3D à l'imprimante 3D
Nous avions la possibilité d'utiliser les logiciels freecad et openscad, or , je n'ai pas réussi à les prendre en main et j'ai eu du mal à dédier du temps à ce projet personnel en raison du projet de groupe qui a subi de nombreux pas en arrière dus à des difficultés techniques.
J'ai donc essayé de créer moi même un cylindre sur freecad dans l'optique d'imprimer un pot a crayon mais impossible de prendre en main le logiciel sur Mac, je n'ai donc pu me consacrer à ce projet qu'au fablabs et j'avoue n'avoir jamais réussi à créer un cylindre car je bloquais systématiquement à l'étape de relier le cercle du haut et le cercle du bas.
J'ai finalement choisi d'utiliser une banque de modèle d'objet 3D et j'ai choisi ce modèle-ci.
Pour des raisons de timing nous avons décidé avec Jules et milo de lancer nos 3 impressions dans la même imprimante. Le temps d'impression était de 18h nous avons donc lancé l'impression le jeudi 2 mai vers 16h et mol est revenu récupérer les impressions le vendredi. Il a été informé par un fablabs manager que l'impression n'avait pas marchée en raison d'un problème avec l'extruder. Comme nous étions déjà le vendredi 3 mai et que nous ne pouvions pas lancer une nouvelle impression en raison de la deadline du 4 mai pour finir nos projet personnels nous n'avons finalement pas pu obtenir nos objets 3D.
Cependant, nous avions réussi à utiliser les imprimantes 3D pour notre projet de groupe afin de créer des demi-sphères en PLA Translucide placées au dessus des LED afin de diffuser la lumière.
Le résultat de ces impressions est le suivant :
Milo
Objet 2D à la découpeuse laser
Pour mon objet en 2d, j'ai eu l'idée d'utiliser une photo issu de mon téléphone.
C'est un tableau de Claude Monet exposé au Musée d'Orsay. J'ai pensé que gravé sur du bois l'effet impressionniste pourrait être joli. J'ai donc importé l'image sur Inkscape.
Afin de le graver, il suffit de cliquer droit sur l'image et sélectionner l'option vectoriser un objet matriciel. Pour ensuite enlever le calque "image1", On obtient ceci :
Maintenant que j'avais mon image en format .svg, je l'ai importé sur l'ordinateur de la découpeuse laser trotec speedy 360. J'ai choisi une chute de bois naturel 3mm car il ne restait plus de peuplier 3mm. Ensuite sur le logiciel de la découpeuse laser, g tracer un carré "rouge" autour de mon dessin pour le découper, en effet le rouge est assigné à la découpe et le noir à la gravure. J'ai pu lancer ma découpe
La découpe s'est bien passé, j'ai pu obtenir mon tableau gravé sur du bois :
Je suis content du rendu, la gravure marche très bien sur ce genre de style de peinture.
Objet 3D à l'imprimante 3D
Pour la conception de mon objet, j'ai eu vraiment du mal car je n'arrive pas du tout à assimiler soit openscad soit freecad. De plus, notre projet de groupe a été chronophage, j'ai totalement oublié l'existence de cette tâche. Il fallait que je sois efficace sur la conception car on approchait de la date limite et que les imprimantes 3D sont très souvent occupés, le temps d'impression est long et il est possible que l'impression échoue. J'ai donc décidé de prendre un fichier stl déjà crée sur internet et de l'imprimer. Je cherchais quelque chose de plutôt petit pour que l'impression soit rapide, j'ai eu l'idée de faire des recherches de porte-clefs à l'imprimante 3D. En tapant "keychain 3d print" je suis tombé sur le site printables où j'ai pu faire mes recherches. J'ai trouvé ce porte-clefs que je trouvais joli et qui correspondait à mes attentes :
J'ai lancé une première impression de cet objet, je suis revenu le lendemain et je n'ai pas trouver mon impression. Je n'ai pas pu savoir pourquoi elle n'était pas la. L'impression n'a pas marché ? Il y avait un souci sur le modèle ? Quelqu'un l'a pris ? Impossible de savoir. J'ai donc relancé une autre impression dans l'espoir de le retrouver le lendemain. Sur la même plaque, avec Jules et Prima, on a tous mis nos projets personnels pour simplifier la logistique mais aussi pour gagner du temps. L'impression durait 18h elle imposait de revenir le lendemain et nous avons utilisé du PLA noir. Lorsque je suis revenu chercher nos projets, un membre du fablab m'a informé qu'il y a eu un souci avec l'extruder et que l'impression avait seulement commencé les premières couches. Or cette impression a été lancé jeudi 2 mai, je suis revenu le vendredi, comme la date limite est le week end du 4 mai au 5, il n'a pas été possible de lancer une autre impression. De plus aucune des imprimantes n'était disponible en raison du nombre de personnes présentes au fablab.
Coline
-
Objets 2D à la découpeuse laser :
Je vais faire une médaille pour le chien de ma sœur, elle la veut de dimensions 5cm sur 3 cm environ, avec le nom du chien sur le recto, et son numéro de téléphone ainsi que ses coordonnées Instagram sur le verso. Pour pouvoir imprimer le resto et le verso, je prendrai un matériaux opaques (un des bois disponibles au FabLab).
J'ai fait plusieurs croquis au brouillon sur papier au crayon, elle a sélectionné son préféré, que j'ai alors scanné sur mon téléphone avec l'application CamScanner et importé via mon ordinateur sur Inkscape.
J'ai baisser l'opacité du calque de l'image puis créer un autre calque par dessus, sur lequel j'ai retracé au propre l'image en transparence en faisant quelques modifications. Les lettres sont en noir car elles seront gravées. J'ai utilisé l'outil plume (au milieu à gauche) en mode séquence de segments de lignes droites (en haut à gauche) pour faire des formes, puis l'outil nœud (en haut à gauche) pour modifier les coins des lettres qui ne me convenaient pas.
J'ai ensuite tracé le contour de la médaille avec une ligne de 1px en rouge car il devra être découpé. Je me suis aidé de lignes (tracées en vert sur l'image, je l'ai ai ensuite supprimée) pour essayer d'avoir un contour le plus symétrique possible. En retournant verticalement l'image comme dans un miroir, on voit que ce n'est pas totalement symétrique mais ça ne ne voit pas à l'œil nu donc j'ai gardé cette forme.
A plusieurs reprises, j'ai modifié la taille du dessin, ce qui a aussi modifié l'épaisseur des lignes ce qui était très énervant.
J'ai ensuite rajouter l'attache de la médaille en créant deux cercles. J'ai reproduit à l'échelle le dessin sur du papier pour m'assurer que les dimensions étaient bonne, notamment que l'on peut faire passer une attache de porte clé dedans, puisque c'est comme ça qu'elle sera attaché au collier du chien. Pour que l'intersection entre le demi cercle et les lignes droites rouges du reste de contour soit bien nette, j'ai ajouté des rectangles blancs (qui ne se voient donc pas sur le fond blanc).
J'ai ensuite créer un carré autour en bleu (1px, marquage) qui me servira de repère pour que le verso soit bien superposé au recto. J'ai ensuite copié le contour rouge et le carré bleu puis l'ai retourné. En bleu, avec l'outil texte, j'ai noté le numéro de téléphone (pas celui sur la photo évidemment, c'est juste un exemple) ainsi que le compte Instagram (allez vous abonner).
Le plus important lors de la découpe sera que les lettres stylisées du devant soient bien dans le cadre rouge, c'est pas très grave si les textes derrière ne sont pas très bien centrés et qu'il y ai un petit décalage. Il faudrait donc d'abord que je découpe le grand carré autour et que je marque les numéro et l'Instagram, puis que retourne le carré et que je fasse gravé les lettres et découpe le contour rouge de la médaille. Le contour rouge ne devra être découpé qu'une fois par la machine pour être sure que la découpe soit nette. J'ai donc supprimé la version retournée du contour rouge autour du numéro de téléphone et est mis le grand carré en rouge à la place. Il faut maintenant que je fasse deux fichiers différents tout en gardant les mêmes dimensions pour le recto et le verso pour que la machine fasse l'un après l'autre. J'ai donc simplement fait un couper coller du recto sur un autre fichier, en m'assurant que les dimensions et épaisseur des lignes n'est pas étaient modifiées.
Parmi les bois disponibles à l'impression , j'ai pris un chute de peuplier 3mm. J'ai commencé par le verso (marquage du numéro) qui a été très rapide (moins d'1mn). Mais pour le resto, j'ai du changer mon fichier Inkscape car les rectangles blancs n'apparaissaient pas donc l'attache aurait été découpée du reste de la médaille. J'ai réutilise l'outil plume en commençant à gauche de l'attache, puis en faisant le tour du contour et en finissant à droite de l'attache. De près, les finissions/l'intersection entre l'arc de cercle et les lignes rouges n'est pas très nette mais cela sera suffisant pour la découpeuse laser.
Sur l'ordinateur de la découpeuse, le dessin ne voulait être déplacer jusque dans le coin de la planche, j'ai donc décalé la planche du coin de quelques centimètre et ai essayer de replacer le cadre bleu pour que cela correspond au rectangle de la planche, avant de placer le curseur sur une des lignes rouges.
Le cadrage n'était pas exact, ce qui a décentré les écritures du verso par rapport à l'avant mais la découpe a réussi. Voici le résultat final :
(il est pas très à son avantage soyez indulgents)
Comme nous devions faire un objet sur une planche de maximum 30cm sur 30cm et que la médaille était petite, j'ai décidé en plus de graver une image que j'ai pris sur internet. Je l'ai importée sur Inkscape puis je l'ai redimensionné environ au format A5 (21cm sur 14cm au lieu de 14.8cm pour ne pas déformer ou couper l'image). Elle est issue d'un manga donc elle est déjà en noir et blanc mais il fallait tout de même vectorisé l'image. J'ai adapté le seuil de luminosité de la vectorisation pour conserver le maximum de détails mais certains détails ne me convenait pas donc j'ai utiliser les outils gomme et calligraphie pour corriger certaines imperfections. J'ai également rajouter une ligne rouge de 1px tout autour pour la découpe (rectangle de même dimension et même position en X et Y que l'image pour que ça suive bien les bords).
J'ai pris une chute de CP peuplier 3mm. Voici le résultat, parfaitement réalisé :
- Objet 3D à l'imprimante 3D : porte-clé
J'ai décidé de faire un lanceur de paintball en 3D pour en faire un porte-clé. J'utiliserai OpenSCAD. Voici une des images que j'ai utilisée comme référence :
J'ai commencé par réalisé le canon et le corps du lanceur avec des cylindre et pavé. J'ai utiliser la fonction rotate pour les orientations de la manière dont je voulais mais j'ai fait en sorte que toute mes formes restent au centre avec une coordonnée en y de 0 pour faciliter le placement (je changerai donc uniquement les coordonnées des x et z en utilisant la fonction translate). J'ai ajusté plusieurs fois la taille des composants jusqu'à ce que cela me convienne.
J'ai aussi augmenté au fur et à mesure la fonction $fn= pour lisser les cylindres et par la suite les sphères.
Ensuite, j'ai généré des sphères et d'autres cylindres/cônes pour la bouteille d'air comprimé et le loader.
Pour la gâchette, j'ai utilisé la fonction difference() entre deux cylindres pour faire une forme de croissant de lune.
En remontant au début du code, j'ai à nouveau utilisé la fonction difference() entre deux cylindres pour faire le creux du canon.
Les détails des vis en dessous du loader et sur le air source adaptater ont été faits avec 3 cylindres simples.
Enfin, j'ai ajouté l'attache du porte clé au bout de la bouteille d air comprimé en faisant une difference() entre deux cercles , et j'ai également ajouté un couvercle au loader en faisant une différence entre un disque et la sphère du loader pour avoir une surface plane sur la sphère, puis en ajoutant un disque :
Voici le modèle 3d final :
Nous verrons à l'impression si les détails ne sont pas trop petits pour avoir un bon rendu. Avant de le mettre sur l'ordinateur de la salle des imprimantes 3D, il faut convertir le fichier en STL, et avant ça render avec F6 pour avoir l'aperçu final. Un warning c'est affiché me disant que les objets 2D ne pouvaient être combinés avec les objets 3D et certains des objets ont disparu de l'aperçu, j'ai du donc remplacer tous les cercles par des cylindres.
Voici le code final, certaines modifications pourraient être apportées pour qu'il soit optimisé :
$fn=100;
rotate([0,90,0])
{
difference(){
cylinder(h=30,r=0.8);
translate([0,0,25]){
cylinder(h=6,r=0.5);}}
cube([3,3,13],center=true);
translate([0,0,6])
cylinder(6,1.5,0.9);
}
rotate([0,190,0])
translate([0,0,5])
cube([4,2,10],center=true);
rotate([0,180,0])
translate([-9,0,0])
cylinder(h=9,r=1.1);
translate([1,0,-10])
rotate([0,-90,0])
cylinder(h=10,r=1);
translate([-2,0,0]){
translate([-10,0,-10])
sphere(4);
translate([-16,0,-10])
sphere(4);
rotate([0,90,0])
translate([10,0,-16])
cylinder(h=6,r=4);}
cylinder(h=6,r=1.2);
rotate([0,-5,0])
translate([-2,0,8.5])
rotate([0,110,0])
cylinder(8,5,1.9);
difference(){
rotate([0,-5,0]){
translate([-3.1,0,8.9])
sphere(5.06);}
rotate([0,-47,0]){
translate([3.5,0,12.8])
cylinder(h=2,r=3);}}
difference(){
rotate ([0,90,0]){
translate([3,0,3])
cube([5,1.5,5], center=true);}
rotate ([0,90,0]){
translate([3,0,3])
cube([4.5,2,4.5], center=true);
}}
difference(){
rotate([90,0,0]){
translate([2.9,-2.8,0]){
cylinder(h=1,r=1.7,center=true);}}
rotate([90,0,0]){
translate([3.5,-2.9,0]){
cylinder(h=2,r=1.5,center=true);}}};
translate([-7,0,-11.5])
cylinder(h=3,r=0.6);
translate([-7,0,-12.1])
cylinder(h=0.7,r=1);
translate([-0.5,0,3])
cylinder(h=1, r=1.8, center=true);
translate([-23,0,-10]){
rotate([90,0,0])
difference(){
circle(h=1, r=2,center=true);
circle(h=1, r=1.3, center=true);}}
rotate([0,-47,0])
translate([3.6,0,12.6])
cylinder(h=0.5, r=3);
A la première simulation, le temps d'impression était estimée à 56mn pour une échelle de 8cm de long. Comme le lanceur est "debout" (pas couché à plat), les supports étaient plutôt nombreux. J'ai donc décidé de créé un autre fichier avec le lanceur à plat (rotate sur l'ensemble de mon code), pour voir si je peux avoir un temps moins long. J'ai pu resimuler et l'impression dure 49mn. J'ai utiliser le PLA noir qui était déjà dans la machine. L'impression a été un succès.
Jules
Présentation du projet individuel de fablab :
OBJET 2D :
pour mon projet 2D j’ai eu l’idée d’utiliser une photo de mon téléphone et de la graver pour ensuite l’utiliser comme décoration.
J’ai donc choisit cette photo : une photo prise avec deux de mes amis et coéquipiers en équipe de France pendant les championnats d’Europe à Padoue en Août 2023.
Il fallait utiliser le logiciel inkscape. Sur le logiciel il fallait copier coller la photo et ensuite la vectoriser pour obtenir seulement les contours. Aller dans calques pour retirer l’image de base et n’avoir plus que les contours de l’image.
Après avoir fait ça et enregistrer le fichier sur une clé il fallait le mettre sur l’ordinateur de la machine. J’avais déjà réalisé cette action à plusieurs reprises pendant la fabrication de notre projet de groupe donc ça n’a pas été très compliqué pour moi. Après avoir fait le calibrage de la machine le laser commence à gravure et j’ai obtenu le résultat suivant :
OBJET 3D :
La consigne pour la réalisation de l’objet 3d était de imprimer à l’imprimante 3D un objet de maximum 15cm par 15cm.
Le projet de groupe ayant prit énormément de temps et comme je n’étais pas très alaise sur le logiciel Freecad je n’ai pu le réaliser moi même. J’ai donc trouver un fichier de porte clé sur internet.
Après avoir trouver et télécharger le fichier sur une clé j’ai du le configurer sur l’ordinateur et l’envoyer à la machine. Tout comme la gravure de l’objet en 2D le projet de groupe m’a permis de réaliser la manipulation assez rapidement car je l’avais déjà fait plusieurs fois. J’ai donc lancer l’impression.
En revenant chercher mon objet il était cassé. Les bras et le bec étant trop à l’horizontal le plastique n’a pas pu se solidifier de la bonne manière et a donc coulé.
J’ai donc relancer une impression en ajoutant des supports en dessous des bras et du bec pour que le plastique puisse se solidifier de la bonne façon.
Comme les imprimantes étaient toutes utilisées nous avons avec Milo et Prima mit nos 3 objets en même temps. L’impression a été un échec mais comme nous étions vendredi nous n’avons pas pu réimprimer nos objets.
Projet : testeur de réflexes / machine qui calcule le temps de réaction d'une personne :
27/02/2024 : 1ère séance dédiée au projet, réflexion sur la conception et premier test
Lors de cette séance, nous avons testé différents capteurs afin de réaliser notre projet. Le capteur qui nous semble le plus adapté est un capteur de vibration : Grove-Vibration Sensor (SW-420). Nous avons donc essayé de tester le seuil de vibration du capteur pour essayer dans un premier temps de comprendre comment il fonctionne. Pour y parvenir, nous avons donc utiliser et modifier le code ci-dessous. Ce code permet de voir si le capteur marche en nous indiquant si les vibrations captées sont basses ou hautes (code exemple de base que l'on trouve sur internet). Il n'y a besoin d'installer aucune library.
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int buzzer = 3; // the number of the buzzer pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(buzzer, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
Serial.println("niveau haut");
delay(500);
} else {
// turn LED off:
Serial.println("niveau bas");
delay(500);
}
}
Nous avons modifier le code pour ne pas utiliser de buzzer : le serial monitor affiche bien le niveau haut ou bas du capteur.
Pour le reste de notre montage, nous souhaitons avoir 5 "boutons"/plaques deux placés au niveau des épaules, deux placés au niveau des hanches et un au niveau du buste.
05/03/2024 : 2ème séance du projet et test de l'accéléromètre
Aujourd'hui, nous allons essayer d'autres capteurs pour voir lequel nous semble le plus adapté à notre projet, ayant eu un peu de mal à utiliser le capteur de vibration la semaine dernière. Nous avons pensé au capteur de gestes et à l'accéléromètre.
Pour l'accéléromètre, on doit le brancher à la port I2C de la carte Arduino et il faut installer la library suivante : https://github.com/Seeed-Studio/Seeed_Arduino_LIS3DHTR/archive/master.zip
Nous avons copier l'exemple de code suivant, en mettant le serial monitor en 115200 baud sinon on n'a pas de chiffres affichés en coordonnées mais des symboles illisibles.
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
void setup()
{
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE,0x19); //IIC init
//LIS.begin(0x19);
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
}
void loop()
{
if (!LIS)
{
Serial.println("LIS3DHTR didn't connect.");
while (1)
;
return;
}
//3 axis
Serial.print("x:"); Serial.print(LIS.getAccelerationX()); Serial.print(" ");
Serial.print("y:"); Serial.print(LIS.getAccelerationY()); Serial.print(" ");
Serial.print("z:"); Serial.println(LIS.getAccelerationZ());
delay(1000);
//ADC
// Serial.print("adc1:"); Serial.println(LIS.readbitADC1());
// Serial.print("adc2:"); Serial.println(LIS.readbitADC2());
// Serial.print("adc3:"); Serial.println(LIS.readbitADC3());
}
On ouvre le serial plotter pour afficher le graphique en temps réel.
Nous avons fait un prototype avec une petite plaque en bois trouvée dans la salle de découpe et des ressorts en scotchant l'accéléromètre à la plaque.
Lorsqu'on laisse le capteur en position repos horizontale sur la plaque, puis qu'on appuie sur la plaque, on voir bien une modification très soudaine des coordonnées, surtout de z (la hauteur). Nous allons donc pouvoir fixer un seuil en dessous de la valeur normale (1) mais suffisamment basse pour que les plus faibles perturbations passe au dessus de ce seuil : -1.2 semble correspondre. Nous utiliserons cette valeur lors des prochaines séances pour le calibrage du capteur.
Pour les prochaines séances, nous devons réfléchir à un moyen de différentier les plaques et indiquer à l'utilisateur sur laquelle appuyer. Utiliser une LED pour chacune des plaques semble trop encombrant. Nous pourrions utiliser une LED RBG au centre entre les plaques qui s'allumerai de différentes aléatoirement parmi celles formatées, et chaque plaque serait associée à une couleur de la LED.
12/03/2024 : 3ème séance du projet, LED RGB et plaques
Nous avons tenter de programmer la LED RGB pour la faire s'allumer de 4 couluers différentes aléatoirement. Il faut télécharger sa library avec ce lien : https://github.com/pjpmarques/ChainableLED/releases
Nous avons utiliser le code d'exemple suivant disponible sur internet bien que nous n'utilisons qu'une LED et pas 5. La ligne 11 indique qu'il faut la brancher au port D7 de la carte Arduino.
/*
* Example of using the ChainableRGB library for controlling a Grove RGB.
* This code cycles through all the colors in an uniform way. This is accomplished using a HSL color space.
*/
#include <ChainableLED.h>
#define NUM_LEDS 5
ChainableLED leds(7, 8, NUM_LEDS);
void setup()
{
leds.init();
}
float hue = 0.0;
boolean up = true;
void loop()
{
for (byte i=0; i<NUM_LEDS; i++)
leds.setColorHSL(i, hue, 1.0, 0.5);
delay(50);
if (up)
hue+= 0.025;
else
hue-= 0.025;
if (hue>=1.0 && up)
up = false;
else if (hue<=0.0 && !up)
up = true;
}
Le code suivant ne marche pas mais nous l'avons garder en ébauche pour la séance suivante. Nous avons tenter d'introduire les fonctions millis pour mesurer le temps puis faire la différence pour avoir le temps de réaction puis en calculer la moyenne, ainsi que programmer la LED pour qu'elle s'allume aléatoirement parmi 4 couleurs différentes définies par la variable hue.
/*
* Example of using the ChainableRGB library for controlling a Grove RGB.
* This code cycles through all the colors in an uniform way. This is accomplished using a HSL color space.
*/
#include <ChainableLED.h>
#define NUM_LEDS 5
ChainableLED leds(7, 8, NUM_LEDS); //brancher au port D7
void setup()
{
leds.init();
int Moyenne (int pp,int mes) { // sur 4 mesures
int total;
for (byte i=0; i<4; i++) {
total += mes;
delay(pp);
}
return (total/4) ;
}
byte Ldr;
}
float hue = 0.0;
boolean go = true;
long num; //variable numéro pour choisir chiffre aléatoire
byte i=0; // initialise sa valeur à 0
void loop()
{
for (byte i=0; i<NUM_LEDS; i++)
leds.setColorHSL(i, hue, 1.0, 0.5);
delay(50);
long f;
byte i = 0;
long d;
byte i = 0;
if (go)
unsigned long f=millis(); //mesure du temps (correspond à la fin/quand la plaque est touchée)
int num = random(4); // definir la couleur en choisissant un nombre de 0 à 4
int hue = num / 5; //lui associer une couleur entre 0 et 1 pour la LED
unsigned long d=millis(); //mesure le temps au début
int t = 0;
t = f - d; // t le temps de réaction
Ldr = Moyenne(10, analogRead(A0)); //... if (Ldr > MaxLight) ...
}
Pour le code de l'accéléromètre, nous avons tenter de rajouter le seuil à z=-1.2 mentionné plus haut en reprenant le code de la séance précédente.
bool go = false; //à mettre avant void setup
//à la fin
if(LIS.getAccelerationZ()<-1.2); //valeur normale à -1 car capteur retourné
go = true;
delay (1000);
go = false;
Pendant ce temps, nous avons aussi découper les 4 plaques à la découpeuse 3D, des carrés de 12cm de coté qui nous semblait être une dimension adaptée.
Durant la prochaine séance, nous devrons corriger le code de la LED qui ne marche pas et trouver une manière de différencier les différents ports I2C, pour différencier les accéléromètre comme chacun des 4 capteurs sera brancher sur 1 des 4 ports I2C de la carte.
19/03/2024 : 4ème séance du projet, code combinant tous les capteurs
Durant cette séance, nous nous sommes concentrée sur le code, car si il ne marche pas rien d'autre ne marchera dans notre projet. Nous avons repris les codes des 2 dernières séances et après avoir corriger de nombreuses erreurs pendant un long moment, voici un code sans erreur que nous obtenons.
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
#include <ChainableLED.h>
#define NUM_LEDS 1
ChainableLED leds(7, 8, NUM_LEDS); //brancher au port D7
void setup() {
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE,0x19); //IIC init
//LIS.begin(0x19);
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
}
float hue = 0.0;
unsigned long d;
unsigned long f;
long t = 0;
void loop() {
leds.init();
Serial.print("z:"); Serial.println(LIS.getAccelerationZ());
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, hue, 1.0, 0.5);
hue = 0.7;
d=millis(); //mesure le temps au début
}
delay(100);
// Check accelerometers for Z-axis value below -1.2
if(LIS.getAccelerationZ()<-1.2); { //valeur normale à -1 car capteur retourné
f=millis(); //mesure du temps (correspond à la fin/quand la plaque est touchée)
delay(100);
t = f - d; // t le temps de réaction
Serial.print("le temps de réaction est de : "); Serial.print(t); Serial.println(" ");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0.2, 1.0, 0.5);
}
}
delay(3000);
}
Le serial monitor affiche un temps de réaction de 101ms ce qui correspond au delay ligne 54. Nous voyons qu'il y a donc 1ms de décalage lorsque que l'on utilise les fonctions millis, ce qu'il pourra être intéressant de prendre en compte dans notre calcul de temps de réaction final. Nous avons donc corriger cette erreur en rajoutant les accolades de la fonction if ligne 57 (le temps f se calculait tout le temps est pas seulement lorsque la condition du if était vérifiée).
Il nous a était conseillé d'utiliser la condition while plutôt que if
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
#include <ChainableLED.h>
#define NUM_LEDS 1
ChainableLED leds(7, 8, NUM_LEDS); //brancher au port D7
void setup() {
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE,0x19); //IIC init
//LIS.begin(0x19);
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
}
float hue = 0.0;
unsigned long d;
unsigned long f;
long t = 0;
void loop() {
leds.init();
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, hue, 1.0, 0.5);
hue = 0.7; //bleu violet
d=millis(); //mesure le temps au début
}
// Check accelerometers for Z-axis value below -1.2
while(LIS.getAccelerationZ()>-1.2);{ //valeur normale à -1 car capteur retourné
Serial.print("z:"); Serial.println(LIS.getAccelerationZ());
Serial.println("Attente ");
delay(100);
}
f=millis(); //mesure du temps (correspond à la fin/quand la plaque est touchée)
delay(100);
t = f - d; // t le temps de réaction
Serial.print("le temps de réaction est de : "); Serial.print(t); Serial.println("ms");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0.2, 1.0, 0.5); //jaune
}
delay(3000);
}
Nous avons un problème avec la chaine while qui s'enclenche que quand on secoue l'accéléromètre, il semblerait qu'il faille inverser la condition., ce que nous ferons la prochaine fois.
Nous n'avons pas non plus trouver de manière de différencier les adresses des accéléromètres qui sont tous branchés sur les ports I2C. Le professeur nous a proposé d'utiliser un multiplexeur en nous avertissant que cela n'était pas facile, alors de par notre manque de compétences en codage, nous avons préférer associer un seul accéléromètre par carte pour les prochaines séances.
26/03/2024 : 5ème séance, mesure du temps de réaction sur une seule carte
Nous avons finalisé le code de la séance précédente qui nous permet d'allumer la LED RGB, de calculer le temps de réaction lorsque l'on bouge l'accéléromètre et d'éteindre la LED pendant 3s avant de la rallumer et de répéter l'opération :
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
#include <ChainableLED.h>
#define NUM_LEDS 1
ChainableLED leds(7, 8, NUM_LEDS); //brancher au port D7
void setup() {
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE,0x19); //IIC init
//LIS.begin(0x19);
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
}
float hue = 0.0;
unsigned long d;
unsigned long f;
long t = 0;
byte power = 0;
float z;
void loop() {
leds.init();
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, hue, 1.0, 0.5);
hue = 0.7; //bleu violet
d=millis(); //mesure le temps au début
}
z = LIS.getAccelerationZ();
Serial.print("z avant:"); Serial.println(z);
// Check accelerometers for Z-axis value below -1.1
while(z>(-1.1))
{ //valeur normale à -1 car capteur retourné
z = LIS.getAccelerationZ();
Serial.print("Attente, z boucle :"); Serial.println(z);
delay(50);
}
f=millis(); //mesure du temps (correspond à la fin/quand la plaque est touchée)
delay(100);
t = f - d; // t le temps de réaction
Serial.print("le temps de réaction est de : "); Serial.print(t); Serial.println("ms");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0, 255-power, 0); //éteindre
}
delay(3000);
}
Il nous reste désormais à faire un code pour la carte centrale qui va permettre d'allumer aléatoirement la LED d'une des 4 cartes, ainsi que récupérer les temps de réaction de chacune des 4 cartes et en calculer la moyenne/faire un graphique des différentes valeurs. Pour cela, nous avons essayer d'utiliser la fonction analogRead() :
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
#include <ChainableLED.h>
#define NUM_LEDS 1
ChainableLED leds(7, 8, NUM_LEDS); //brancher au port D7
#define POEPIN A0
void setup() {
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE,0x19); //IIC init
//LIS.begin(0x19);
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
}
float hue = 0.0;
unsigned long d;
unsigned long f;
long t = 0;
byte power = 0;
float z;
void loop() {
leds.init();
int val;
// lecture de la tension sur la broche A0 -> brancher la carte centrale sur A0
val = analogRead(POEPIN);
// affichage de la tension sur le moniteur serie
Serial.println(val);
if (val<500) {
val = analogRead(POEPIN);
Serial.println(val);
}
else {
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, hue, 1.0, 0.5);
hue = 0.7; //bleu violet
d=millis(); //mesure le temps au début
}
z = LIS.getAccelerationZ();
Serial.print("z avant:"); Serial.println(z);
// Check accelerometers for Z-axis value below -1.1
while(z>(-1.1))
{ //valeur normale à -1 car capteur retourné
z = LIS.getAccelerationZ();
Serial.print("Attente, z boucle :"); Serial.println(z);
delay(5000);
}
f=millis(); //mesure du temps (correspond à la fin/quand la plaque est touchée)
delay(100);
t = f - d; // t le temps de réaction
Serial.print("le temps de réaction est de : "); Serial.print(t); Serial.println("ms");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0, 255-power, 0); //éteindre
}
delay(3000);
}
}
Pour la partie montage, nous avons découper à la scie la grand planche qui nous servira de support pour notre installation, que l'on a ensuite poncée et limée pour éliminer les échardes.
Avancement pendant les vacances
J'ai essayé de faire le code de la "carte mère", soit celle qui envoie des signaux aléatoirement aux autres cartes (qui elles sont connectées aux LEDs et accéléromètres) pour leur indiquer que c'est à leur tour de fonctionner. Pour cela, j'ai utilisé les niveaux des pins des différentes ports digitaux (un associé à chaque carte périphérique) en output et input. Pour cela, j'ai utilisé les différentes liens suivant :
- https://www.youtube.com/watch?v=qh5gOgeqzZo
- https://www.arduino.cc/reference/en/language/functions/random-numbers/random/
- https://docs.arduino.cc/learn/microcontrollers/digital-pins/
- https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/
- https://www.arduino.cc/reference/en/language/variables/constants/highlow/
- https://docs.arduino.cc/retired/hacking/software/PortManipulation/
- https://www.instructables.com/Arduino-and-Port-Manipulation/
J'ai réussi à réaliser ce code après avoir corrigé certaines erreurs :
const int carte_1 = 2; // Digital 2 pour la plaque 1
const int carte_2 = 3; // Digital 3 pour la plaque 2
const int carte_3 = 4; // Digital 4 pour la plaque 3
const int carte_4 = 5; // Digital 5 pour la plaque 4
long carte; //fonction random marche que avec des variables long
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
DDRD = B00111100; // set PORTD (digital 2~5) to outputs (0 and 1 must not be changed)
PORTD = B00000000; // all on LOW
Serial.println(" "); Serial.println("lets go"); Serial.println(" ");
}
void loop() {
// put your main code here, to run repeatedly:
carte=random(2,6);
Serial.print("Le port sélectionné est le port D"); Serial.println(carte);
if (carte=2) {
digitalWrite(carte_1, HIGH); // tension envoyée sur D2 carte 1
delay(10);
pinMode(carte_1,INPUT); //port D2 changée en entrée pour attendre retoru de l'autre carte périphérique
int read = digitalRead(carte_1);
Serial.print("Première mesure, read= "); Serial.println(read);
while (read=0) //tant que le port D2 ne reçoit pas de tension
{ read = digitalRead(carte_1); //continue de lire la tension
Serial.print("En attente, read= "); Serial.print(read);
delay(10);
}
Serial.println("Tension reçue donc plaque touchée"); Serial.println(" ");
delay(10);
pinMode(carte_1,OUTPUT);
delay(4000);
}
}
Je lis ça sur le Serial Monitor, infiniment toutes les 4 secondes grâce au delay(4000), avec le nom du port qui change grâce à la fonction random :
On voit que cela indique que le niveau est haut sur les ports lorsqu'ils sont en mode input alors que aucune tensions n'est délivrée sur les ports. C'est normal que les pins renvoient des valeurs non cohérentes lorsqu'elles ne sont connectées à rien.
Je dois maintenant recopier le code pour les autres valeurs de la variable carte, soient pour les 3 autres cartes avec LEDs et accéléromètres, ainsi que vérifier si le signal sur les ports est détecté comme haut que lorsque une tension est reçu sur le port connecté. Il faut donc que j'ajoute une partie sur l'envoi de tension dans le code des autres cartes également.
J'ai changé la variable carte en port pour plus de clarté et j'ai ajouté des précision dans les Serial.print pour savoir grâce au Serial Monitor quelle partie du code est en cours, notamment quelle carte/port est censé.e être activée/lu à quel moment :
const int carte_1 = 2; // Digital 2 pour la plaque 1
const int carte_2 = 3; // Digital 3 pour la plaque 2
const int carte_3 = 4; // Digital 4 pour la plaque 3
const int carte_4 = 5; // Digital 5 pour la plaque 4
long port; //fonction random marche que avec des variables long
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
DDRD = B00111100; // set PORTD (digital 2~5) to outputs (0 and 1 must not be changed)
PORTD = B00000000; // all on LOW
Serial.println(" "); Serial.println("lets go"); Serial.println(" ");
}
void loop() {
// put your main code here, to run repeatedly:
port=random(2,6);
Serial.print("Le port sélectionné est le port D"); Serial.println(port);
if (port=2) {
digitalWrite(carte_1, HIGH); // tension envoyée sur D2 carte 1
delay(10);
pinMode(carte_1,INPUT); //port D2 changé en entrée pour attendre retoru de l'autre carte périphérique
int read = digitalRead(carte_1);
Serial.print("Première mesure sur carte 1, read= "); Serial.println(read);
while (read=0) //tant que le port D2 ne reçoit pas de tension
{ read = digitalRead(carte_1); //continue de lire la tension
Serial.print("En attente carte 1, read= "); Serial.print(read);
delay(10);
}
Serial.println("Tension reçue sur carte 1 donc plaque touchée"); Serial.println(" ");
delay(10);
pinMode(carte_1,OUTPUT);
delay(4000);
}
else {
if (port=3){
digitalWrite(carte_2, HIGH); // tension envoyée sur D3 carte 2
delay(10);
pinMode(carte_2,INPUT); //port D3 changé en entrée pour attendre retoru de l'autre carte périphérique
int read = digitalRead(carte_2);
Serial.print("Première mesure sur carte 2, read= "); Serial.println(read);
while (read=0) //tant que le port D3 ne reçoit pas de tension
{ read = digitalRead(carte_2); //continue de lire la tension
Serial.print("En attente carte 2, read= "); Serial.print(read);
delay(10);
}
Serial.println("Tension reçue carte 2 donc plaque touchée"); Serial.println(" ");
delay(10);
pinMode(carte_2,OUTPUT);
delay(4000);
}
else {
if (port=4){
digitalWrite(carte_3, HIGH); // tension envoyée sur D4 carte 3
delay(10);
pinMode(carte_3,INPUT); //port D4 changé en entrée pour attendre retoru de l'autre carte périphérique
int read = digitalRead(carte_3);
Serial.print("Première mesure sur carte 3, read= "); Serial.println(read);
while (read=0) //tant que le port D4 ne reçoit pas de tension
{ read = digitalRead(carte_3); //continue de lire la tension
Serial.print("En attente carte 3, read= "); Serial.print(read);
delay(10);
}
Serial.println("Tension reçue carte 3 donc plaque touchée"); Serial.println(" ");
delay(10);
pinMode(carte_3,OUTPUT);
delay(4000);
}
else { // donc carte=5 si aucun des autres
digitalWrite(carte_4, HIGH); // tension envoyée sur D5 carte 4
delay(10);
pinMode(carte_4,INPUT); //port D5 changé en entrée pour attendre retoru de l'autre carte périphérique
int read = digitalRead(carte_4);
Serial.print("Première mesure sur carte 4, read= "); Serial.println(read);
while (read=0) //tant que le port D5 ne reçoit pas de tension
{ read = digitalRead(carte_4); //continue de lire la tension
Serial.print("En attente carte 4, read= "); Serial.print(read);
delay(10);
}
Serial.println("Tension reçue carte 4 donc plaque touchée"); Serial.println(" ");
delay(10);
pinMode(carte_4,OUTPUT);
delay(4000);
}
}
}
}
Le Serial Monitor m'indique que peu importe le numéro du port choisi avec random, c'est la boucle if de la carte_1 (port=2) qui est réalisée...
Comme cela ne marche pas, nous avons décider de faire les 4 plaques avec 4 cartes différentes reliées à 4 ordis qui renvoient les valeurs, plutôt que d'essayer de connectées les cartes entres elles. Chaque cartes réaliseraient le code que nous avons écrit avant les vacances et qui marche.
23/04/2024 : dernière séance avant les présentations
Le code principal fonctionne, nous devons maintenant créer une fonction qui stocke/calcule la moyenne sur les mesures effectuées. Comme nous ne savons pas faire de moyenne glissante au fur et à mesure que les mesures sont prises, on doit fixer un nombre spécifique de mesures à l'avance puis diviser la somme de toutes les mesures de temps de réaction par ce nombre. Nous avons essayer de créer une fonction qui nous permettrais de choisir le nombre de mesures réalisées sur chaque plaque parmi différents modes prédéfinis.
int total; // à mettre dans le void loop
int donnee;
while (Serial.available() !=0) {
donnee = Serial.read(); //chargemùent des données
Serial.print("Le mode choisi est le mode ");
Serial.println(donnee); //affichage de la donnée
total = 0;
delay(2000);
}
while (total=0){
if (donnee = 1) {
total = 10;
Serial.println(total); Serial.print(" mesures du temps de récation seront effectuées");
} else {
if (donnee = 2) {
total = 25;
Serial.println(total); Serial.print(" mesures du temps de récation seront effectuées");}
else {
if (donnee = 3){
total = 40;
Serial.println(total); Serial.print(" mesures du temps de récation seront effectuées");}
else {
total = 0;
Serial.println("Mode indéfini, veuillez reessayer"); }
}
}
}
Le code ne marchait pas donc on a abandonné car il nous reste que peut de temps avant la présentation. chaque carte réalisera ainsi 10 mesures uniquement. Comme on a 4 plaques, cela fait un total de 40mesures par personne, ce qui semble un chiffre raisonnable pour être fiable. Nous avons donc ajouter des variables moyenne et somme, ainsi qu'un compteur c et des Serial.print() qui nous indique dans le Serial Monitor quelle étape est effectuée quand.
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
#include <ChainableLED.h>
#define NUM_LEDS 1
ChainableLED leds(7, 8, NUM_LEDS); //brancher au port D7
void setup() {
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE,0x19); //IIC init
//LIS.begin(0x19);
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
}
float hue = 0.0;
unsigned long d;
unsigned long f;
long t = 0;
byte power = 0;
float z;
float c; //compteur
float moy; //moyenne
float mesures; // nombre de mesures à réaliser
float somme; //somme des t pour après faire la moyenne
void loop() {
leds.init();
mesures = 10; // nb de mesures qui seront réalisées (jsp si on met un fonction ici pour pouvoir changer)
Serial.println(" "); Serial.print("nous effectuerons "); Serial.print(mesures); Serial.println(" mesures"); Serial.println(" ");
c = 0;
somme = 0;
moy = 0;
unsigned long temps;
while (c<mesures) {
temps = random(500, 5000);
Serial.print("le temps d'attente avant d'allumer la LED est de "); Serial.print(temps); Serial.print(" ms");
delay(temps);
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, hue, 1.0, 0.5);
hue = 0.7; //bleu violet
d=millis(); //mesure le temps au début
}
z = LIS.getAccelerationZ();
Serial.print("z avant:"); Serial.println(z);
// Check accelerometers for Z-axis value below -1.1
while(z>(-1.1))
{ //valeur normale à -1 car capteur retourné
z = LIS.getAccelerationZ();
Serial.print("Attente, z boucle :"); Serial.println(z);
delay(50);
}
f=millis(); //mesure du temps (correspond à la fin/quand la plaque est touchée)
delay(100);
t = f - d; // t le temps de réaction
Serial.println(" "); Serial.print("le temps de réaction instantané est de : "); Serial.print(t); Serial.println("ms");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0, 255-power, 0); //éteindre
}
c = c+1;
somme = somme+t;
Serial.print(c); Serial.println("mesure(s) on était effectuées"); Serial.println("______________________________________________");
delay(500);
}
moy = somme/c;
Serial.println(" "); Serial.print("le temps de réaction moyen sur "); Serial.print(c); Serial.print(" mesures est de "); Serial.print(moy); Serial.println("ms"); Serial.println(" "); Serial.println("______________________________________________");
delay(5000);
}
Nous avons également collé des rebord en bois sur notre plaque principale, ainsi que coller certains ressort avec de la colle à bois car le pistolet à colle n'adhérer pas. C'est un processus très long car nous devons maintenir appuyer les deux éléments qui doivent être collés sans bouger pendant plusieurs minutes. Nous avons également découper à la découpeuse laser un trou dans les plaques pour y coller les dômes transparents imprimés en 2D par dessus.
26/04/2024 : après-midi au FabLab pour avancer
Nous avons apporter les dernière touches au code ainsi que avancer la structure, notamment en continuant à coller les ressorts/plaques.
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
#include <ChainableLED.h>
#define NUM_LEDS 1
ChainableLED leds(7, 8, NUM_LEDS); //brancher au port D7
void setup() {
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE,0x19); //IIC init
//LIS.begin(0x19);
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
}
float hue = 0.0;
unsigned long d;
unsigned long f;
long t = 0;
byte power = 0;
float z;
float c; //compteur
float moy; //moyenne
float mesures; // nombre de mesures à réaliser
float somme; //somme des t pour après faire la moyenne
void loop() {
leds.init();
Serial.println("Attente de 30sec avant de commencer pour mettre en place");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0.2, 1.0, 0.5); }// jaune
delay(30000);
mesures = 10; // nb de mesures qui seront réalisées (jsp si on met un fonction ici pour pouvoir changer)
Serial.println(" "); Serial.print("nous effectuerons "); Serial.print(mesures); Serial.println(" mesures"); Serial.println(" ");
c = 0;
somme = 0;
moy = 0;
unsigned long temps;
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0, 255-power, 0); } //éteindre
while (c<mesures) {
temps = random(499, 10002);
Serial.print("le temps d'attente avant d'allumer la LED est de "); Serial.print(temps); Serial.print(" ms");
delay(temps);
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0.7, 1.0, 0.5); //bleu violet
d=millis(); //mesure le temps au début
}
z = LIS.getAccelerationZ();
Serial.print("z avant:"); Serial.println(z);
// Check accelerometers for Z-axis value below -1.1
while(z>(-1.1))
{ //valeur normale à -1 car capteur retourné
z = LIS.getAccelerationZ();
Serial.print("Attente, z boucle :"); Serial.println(z);
delay(50);
}
f=millis(); //mesure du temps (correspond à la fin/quand la plaque est touchée)
delay(100);
t = f - d; // t le temps de réaction
Serial.println(" "); Serial.print("le temps de réaction instantané est de : "); Serial.print(t); Serial.println("ms");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0, 255-power, 0); //éteindre
}
c = c+1;
somme = somme+t;
Serial.print(c); Serial.println("mesure(s) on était effectuées"); Serial.println("______________________________________________");
delay(500);
}
moy = somme/c;
Serial.println(" "); Serial.print("le temps de réaction moyen sur "); Serial.print(c); Serial.print(" mesures est de "); Serial.print(moy); Serial.println("ms"); Serial.println(" "); Serial.println("______________________________________________");
for (byte i=0; i<NUM_LEDS; i++) {
leds.setColorHSL(i, 0.4, 1.0, 0.5); }// vert
Serial.println(" "); Serial.println("Fin, attente d'une minute"); Serial.println(" ");
delay(60000);
}
La fonction random() qui choisit entre 0.5s et 10s pour que la LED s'allume renvoie toujours les mêmes valeurs à chaque fois, ce qui perd tous son interêt, surtout si l'on souhaite que les 4 LEDs des 4 plaques ne s'allument pas en même temps. Nous avons donc 4 fichiers différentes pour chaque LED en changeant les bornes de 500ms à 10000ms de quelques ms (i.e 495 à 10001).
Nous voulions aussi tenter d'exporter les données de temps de réaction dans un tableur pour que la moyenne soit calculer automatiquement et non manuellement en s'inspirant d'un code trouver sur internet mais nous n'avons pas réussi.
https://forum.arduino.cc/t/comment-transferer-des-donnees-dans-un-tableur/1129755
Brancher 2 cartes Arduino sur un même ordinateur marche, en ouvrant deux onglets différents on peut afficher les 2 Serial Monitor séparément et ainsi lire les mesures réalisées des différentes plaques. Milo dispose d'un adaptateur pour avoir 4 ports USB sur un seul ordinateur ce qui nous permettrait de relier toutes les cartes à un seul ordi. C'est pourquoi j'ai ajouté un temps d'attente au début, le temps qu'on mette en place le code sur chaque carte (surtout si on a 4 fichiers différents)/ Durant l'attente au début, les LEDs sont allumées en jaune et lorsque les 10 mesures ont été faites, les LEDs s'allument en vert pendant 1mn avant d'effectuer le programme à nouveau.
Comme nous avions fait dans une des premières séances, nous avons coller scotcher l'accéléromètre et les LEDs sur les 2 plaques qui étaient prêtes pour faire un essai avant de coller définitivement. Le seuil de l'accéléromètre semble être adapté car les LEDs s'éteignent bien quand on tape sur la plaque, la longueur des ressorts est correctes. Si on appuie trop fort, la plaque entière bouge ce qui pourrait aussi éteindre les autres LEDs, nous devons être vigilants sur ce problème.
Préparation du plan pour la présentation finale :
- l'idée qu'on a eu (exemple d'appareil qui existe déjà),
- processus :
tester plein de capteurs/lequel choisir
tester la LED
code
structure (bois/3D)
tentative de centraliser avec une seule LED qui traite les données/fait les calculs
produit final
- ce qu'on voulait faire de base :
- problèmes qu'on a rencontré : peut pas envoyer des données numériques autres que tensions entre carte, la colle fait que se décoller, court circuit que j'ai fait, random qui renvoit les mêmes trucs
- protocole qui mesure le temps de réaction, fiabilité :
debout/assis, droitier/gaucher, que avec une main ou 2 mains, sportif ou pas, homme/femme -> comparer avec valeurs usuelles
fiabilité -> vérifier les delay() pour voir si on a pas qql millisecondes qui s'ajoutent au temps moyen obtenus
- ce qu'on peut améliorer : mettre les valeurs de temps de réaction dans un tableur qui calcule la moyenne des 4 plaques, fonction qui choisit le nombre de mesures prises (plutôt que forcément 10 ou autre nombre fixe), résultat plus propre (pas de scotch, cacher les cartes et les fils derrière les plaques, ...), fixer au mur, écarter plus les plaques
29/04/2024 : matinée au FabLab, veille de la présentation
Nous avons dédié ces 3h à brancher et finaliser la construction de notre appareil de mesure du temps de réaction. Nous avons continuer de coller certains ressort et dômes en PLA, nous en avons scotcher d'autres. Il nous manque toujours un dôme car il n'y a plus de PLA transparent, ce qui n'empêche pas le fonctionnement de notre appareil bien que cela ne soit pas esthétique. Avec le quadruple embout USB de Milo, nous pouvons relié les 4 cartes à 1 seul ordi. Cela n'est pas idéal car afficher les 4 Serial Monitor sur un même écran et y lire les valeurs renvoyées est quelque peu contraignants mais c'est la solution la plus pratique que nous ayons trouvée. Parfois, le code ne veut pas s'uploader sur une des 4 cartes, ou alors les ports n'apparaissent pas lorsqu'on doit choisir la carte sur le Arduino IDE. On ne connaît pas la raison, mais c'est sûrement car l'ordinateur bug de devoir communiqué avec 4 cartes en même temps. Nous avons tout de même réussi à faire 2 mesures avec le temps qu'il nous restait. Voici le résultat final :
(le dessous de chaque plaque)
Pour le code, j'ai réduit la longueur d'attente du début à 15sec plutôt que 30s qui était vraiment trop long quand on voulait faire des essais.
30/04/2024 : présentation finale du projet
Pendant les 45minutes précédent les présentations de chaque groupe, nous avons finalisé notre diaporama (disponible en pièce jointe de cette page) qui résume tout notre projet avec des schémas, ainsi que fait plusieurs mesures pour vérifier le bon fonctionnement/la fiabilité de notre appareil. Les valeurs obtenues sont cohérentes, bien que nous n'ayons pas eu le temps de tester tous les paramètres que nous avions lister dans notre protocole (voir diapo).
C'est un projet qui était très intéressant à réaliser pour ma part et qui m'en a appris pas mal sur le codage en C++, m'étant chargée du code dans son intégralité pendant toutes les séances alors que je n'en avait jamais fait. Nous sommes très satisfaits du résultat bien que beaucoup d'améliorations pourraient encore être apportées. Il y a une semaine encore l'appareil ne marchait pas du tout donc c'est un vrai soulagement que nous ayons trouvé des solutions.
J'espère que la documentation était suffisamment claire/détaillée pour que les personnes souhaitant s'inspirer de notre travail disposent de suffisamment de ressources pour ne pas peiner autant que nous !