Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
wiki:flossmanuals:boitier-interactif-01:accueil [2021/03/30 14:15] 127.0.0.1 modification externe |
wiki:flossmanuals:boitier-interactif-01:accueil [2021/10/31 15:23] (Version actuelle) lise [Boîtier Interactif : Apprendre la profondeur dans un tableau] |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
======= Boîtier Interactif : Apprendre la profondeur dans un tableau ======= | ======= Boîtier Interactif : Apprendre la profondeur dans un tableau ======= | ||
- | * Porteur(s) du projet : Lise Irmann (DNMADE DG2), Damien MUTI (Prof. de Numérique) | + | |
- | * Date : 03/2021 | + | |
- | * Contexte : projet " | + | |
- | * Fichiers : | + | |
- | * Lien : | + | |
- | * Capteurs/ | + | |
* 1 Capteur de distance Ultrasonic Grove (mettre le lien...) | * 1 Capteur de distance Ultrasonic Grove (mettre le lien...) | ||
* 2 Potentiomètres Grove | * 2 Potentiomètres Grove | ||
Ligne 14: | Ligne 14: | ||
---- | ---- | ||
- | |||
- | A remplir... | ||
====== Intentions : explication du projet et objectifs ====== | ====== Intentions : explication du projet et objectifs ====== | ||
+ | ==== Le Contexte ==== | ||
+ | Commande de malette pédagogique pour les enfants de 5-6 ans de la part du musée de Beaux Arts de Marseille. | ||
+ | Chaque élève propose des dispositifs qui pourraient s’insérer dans la malette, en se basant sur un ou plusieurs des tableaux proposés par le musée. | ||
+ | ==== Les Objectifs ==== | ||
+ | Permettre aux enfants d’appréhender la profondeur, la perspective, | ||
+ | ==== Le Dispositif ==== | ||
+ | Une tablette / un ordinateur tactile affiche le tableau d’Émile LOUBON. Elle est reliée à un boitier Arduino, avec des sliders, des potentiomètres et un capteur de distance. Ceux-ci permettent à l’utilisateur de déplacer un personnage dans le tableau. | ||
- | ====== Plans et schémas | + | Il peut le faire de deux différentes manières : |
+ | - de haut en bas : le personnage change de taille et de saturation | ||
+ | |||
+ | - de droite à gauche : le personnage ne change pas | ||
+ | |||
+ | Ainsi, le médiateur peut se servir du boitier pour démontrer la perspective aux enfants. | ||
+ | Ensuite, les enfants volontaires peuvent passer à tour de rôle pour s’en servir pendant que leurs camarades se servent du kit tampographique. | ||
+ | ====== Plans et schémas de fonctionnement ====== | ||
+ | {{ : | ||
====== Programmes ====== | ====== Programmes ====== | ||
+ | ===== Arduino ===== | ||
+ | Le montage Arduino et le programme associé a pour but de mesurer les valeurs de plusieurs potentiomètres et sliders, d'un bouton et d'un capteur de distance à ultrason et de les envoyer au programme Processing pour traitement. | ||
+ | Le code est le suivant : {{ : | ||
+ | < | ||
+ | |||
+ | #include " | ||
+ | |||
+ | Ultrasonic ultrasonic(7); | ||
+ | |||
+ | int Slider1 = 0; // Slider 1 : xPerso | ||
+ | byte Slider1Pin = A0; | ||
+ | byte Slider2Pin = A1; // Slider 2 : yPerso | ||
+ | int Potentiometre1 = 0; // Potentiomètre 1 : ChoixPerso | ||
+ | byte Potentiometre1Pin = A2; | ||
+ | int Potentiometre2 = 0; // Potentiomètre 2 : CouleurPerso | ||
+ | byte Potentiometre2Pin = A3; | ||
+ | int ChoixMesureDistance = 0; // Bouton poussoir - 0 : mesure de distance par slider 2 (yPerso). 1 : Mesure de distance par le capteur de distance | ||
+ | byte boutonPoussoirPin = 2; // broche de lecture du bouton poussoir | ||
+ | |||
+ | int Distance = 0; // distance lue sur le capteur de distance // Attention MeasureInCentimeters() renvoie un type " | ||
+ | int inByte = 0; // incoming serial byte | ||
+ | |||
+ | byte ledPin = 8; // broche de commande de la LED | ||
+ | |||
+ | |||
+ | byte etat_bouton = 0; //La variable « etat_bouton » mémorise l’état HIGH ou LOW de la pate d’entrée | ||
+ | byte old_etat_bouton = 0; //La variable « old_etat_bouton » mémorise l’ancien état de la variable « etat_bouton » | ||
+ | byte etat_led = 0; //La variable « etat_led » mémorise l’état 1 (allumée) ou 0 (éteinte) de la led. | ||
+ | |||
+ | boolean debug = false; | ||
+ | boolean debug_Com_Serial = false; | ||
+ | |||
+ | |||
+ | void setup() { | ||
+ | // start serial port at 9600 bps: | ||
+ | Serial.begin(9600); | ||
+ | while (!Serial) { | ||
+ | ; // wait for serial port to connect. Needed for native USB port only | ||
+ | } | ||
+ | |||
+ | pinMode(boutonPoussoirPin, | ||
+ | pinMode(ledPin, | ||
+ | if (!debug) { | ||
+ | establishContact(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | gestionBouton(); | ||
+ | |||
+ | // Si une donnée arrive dans le port série venant de processing = LIre les nouvelles valeurs des différents capteurs | ||
+ | if (!debug) { // mode normal | ||
+ | if (Serial.available() > 0) { | ||
+ | // lecture de la donnée sur le port série : lettre A | ||
+ | inByte = Serial.read(); | ||
+ | if (inByte == ' | ||
+ | // mesure sur les différents capteurs | ||
+ | gestionCapteurs(); | ||
+ | // Envoi des valeurs lues sur les différents capteurs vers Processing | ||
+ | | ||
+ | |||
+ | if (debug_Com_Serial) { ///// Debug | ||
+ | envoiMesureSurPortSerial(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | else { // mode debug | ||
+ | // mesure sur les différents capteurs | ||
+ | gestionCapteurs(); | ||
+ | // Envoi des valeurs lues sur les différents capteurs | ||
+ | envoiMesureSurPortSerial(); | ||
+ | delay(500); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void establishContact() { | ||
+ | while (Serial.available() <= 0) { | ||
+ | Serial.print(' | ||
+ | delay(300); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void gestionBouton() { | ||
+ | // mesure de l' | ||
+ | etat_bouton = digitalRead(boutonPoussoirPin); | ||
+ | |||
+ | if ((etat_bouton == LOW) && (old_etat_bouton == HIGH)) { | ||
+ | // si l’entrée 2 est à l’état LOW (bouton appuyé) et que juste précédemment le bouton est ouvert | ||
+ | etat_led = 1 - etat_led ; // inverse l’état de la led | ||
+ | delay(10); // patienter 10ms pour éviter les rebonds avant d’allumer la led | ||
+ | } | ||
+ | old_etat_bouton = etat_bouton; | ||
+ | ChoixMesureDistance = etat_led ; // choix du capteur de distance Ultrason ou du Slider | ||
+ | if (etat_led == 1) {//si la led doit être allumée | ||
+ | digitalWrite(ledPin, | ||
+ | } | ||
+ | else { // si la led est éteinte | ||
+ | digitalWrite(ledPin, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void gestionCapteurs() { | ||
+ | // lecture des données sur les différents capteurs. On divise par 4 pour ramener la valeur entre 0 et 255 | ||
+ | Potentiometre1 = map(analogRead(Potentiometre1Pin), | ||
+ | // delay 10ms to let the ADC recover: | ||
+ | delay(10); | ||
+ | |||
+ | Potentiometre2 = analogRead(Potentiometre2Pin) / 4; // | ||
+ | // delay 10ms to let the ADC recover: | ||
+ | delay(10); | ||
+ | |||
+ | Slider1 = analogRead(Slider1Pin) / 4; // xPerso | ||
+ | // delay 10ms to let the ADC recover: | ||
+ | delay(10); | ||
+ | |||
+ | // lecture de la distance avec le capteur ultrason ou le Slider 2 | ||
+ | if (ChoixMesureDistance == 1) { // Capteur de distance ultrason | ||
+ | Distance = map(ultrasonic.MeasureInCentimeters(), | ||
+ | } | ||
+ | else { | ||
+ | Distance = analogRead(Slider2Pin) / 4; //yPerso lu sur Slider 2 | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void envoiMesureVersProcessing() { | ||
+ | Serial.write(Potentiometre1); | ||
+ | Serial.write(Potentiometre2); | ||
+ | Serial.write(Slider1); | ||
+ | Serial.write(Distance);// | ||
+ | } | ||
+ | |||
+ | void envoiMesureSurPortSerial() { | ||
+ | Serial.println("" | ||
+ | Serial.print(" | ||
+ | Serial.print(etat_led); | ||
+ | Serial.print(" | ||
+ | Serial.print(Potentiometre1); | ||
+ | Serial.print(" | ||
+ | Serial.print(Potentiometre2); | ||
+ | Serial.print(" | ||
+ | Serial.print(Slider1); | ||
+ | Serial.print(" | ||
+ | Serial.print(Distance);// | ||
+ | Serial.println("" | ||
+ | } | ||
+ | </ | ||
+ | ===== Processing ===== | ||
+ | ==== Programme initial ==== | ||
+ | Le programme Processing a pour but de récupérer les différentes données envoyées par la carte Arduino. Chaque donnée constitue un paramètre d' | ||
+ | |||
+ | Le rendu est le suivant : | ||
+ | {{ : | ||
+ | |||
+ | Le programme est le suivant : {{ : | ||
+ | |||
+ | < | ||
+ | import processing.serial.*; | ||
+ | |||
+ | int bgcolor; | ||
+ | int fgcolor=255; | ||
+ | Serial myPort; | ||
+ | int NbData = 4; // nombre de données à récupérer de la carte Arduino | ||
+ | int[] serialInArray = new int[NbData]; | ||
+ | int serialCount = 0; // A count of how many bytes we receive | ||
+ | int ChoixPerso, CouleurPerso, | ||
+ | boolean firstContact = false; | ||
+ | float xPerso, yPerso, sPerso; | ||
+ | PImage loubon, bouvier, | ||
+ | color c =color(# | ||
+ | int r = 25, g = 42, b=118; | ||
+ | PImage imgMask; | ||
+ | |||
+ | void setup() { | ||
+ | size(1000, | ||
+ | noStroke(); | ||
+ | |||
+ | |||
+ | // Initialisation des variables | ||
+ | ChoixPerso=0; | ||
+ | CouleurPerso = 0; // | ||
+ | xPerso = 0.76*width; // Slider 1 | ||
+ | yPerso = 0.84*height; | ||
+ | sPerso = 2000; //Taille du personnage | ||
+ | SaturPerso = 255; | ||
+ | bouvier = loadImage(" | ||
+ | loubon= loadImage(" | ||
+ | img = createImage(bouvier.width, | ||
+ | image(loubon, | ||
+ | colorMode(HSB); | ||
+ | // Print a list of the serial ports, for debugging purposes: | ||
+ | printArray(Serial.list()); | ||
+ | imgMask = loadImage(" | ||
+ | imgMask = createImage(bouvier.width, | ||
+ | // I know that the first port in the serial list on my mac | ||
+ | // is always my FTDI adaptor, so I open Serial.list()[0]. | ||
+ | // On Windows machines, this generally opens COM1. | ||
+ | // Open whatever port is the one you're using. | ||
+ | String portName = Serial.list()[0]; | ||
+ | myPort = new Serial(this, | ||
+ | } | ||
+ | |||
+ | void draw() { /////////////////////////////////////// | ||
+ | |||
+ | imageMode(CENTER); | ||
+ | image(loubon, | ||
+ | if (ChoixPerso == 0) { // | ||
+ | bouvier = loadImage(" | ||
+ | img.mask(imgMask); | ||
+ | } | ||
+ | if (ChoixPerso == 1){ | ||
+ | | ||
+ | | ||
+ | } | ||
+ | if (ChoixPerso == 2){ | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | for (int i = 0; i < bouvier.pixels.length; | ||
+ | int r_i = (bouvier.pixels[i] >> 16) & 0xFF; // Faster way of getting red(argb) | ||
+ | int g_i = (bouvier.pixels[i] >> 8) & 0xFF; // Faster way of getting green(argb) | ||
+ | int b_i= bouvier.pixels[i] & 0xFF; // Faster way of getting blue(argb) | ||
+ | if (r_i == r && g_i == g && b_i == b) { | ||
+ | float h = CouleurPerso; | ||
+ | //float h = 128; | ||
+ | float s = SaturPerso; | ||
+ | float b =brightness(bouvier.pixels[i]); | ||
+ | |||
+ | // | ||
+ | |||
+ | img.pixels[i] = color(h, s, b); | ||
+ | } | ||
+ | |||
+ | img.updatePixels(); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | image(bouvier, | ||
+ | |||
+ | image(img, xPerso, yPerso, sPerso, sPerso); | ||
+ | |||
+ | } | ||
+ | //for (int i = 0; i < img.pixels.length; | ||
+ | // img.pixels[i] = color(0, 90, 102, i % img.width * 2); | ||
+ | //} | ||
+ | void serialEvent(Serial myPort) { // gestion des données envoyées par la carte | ||
+ | // read a byte from the serial port: | ||
+ | int inByte = myPort.read(); | ||
+ | // if this is the first byte received, and it's an A, | ||
+ | // clear the serial buffer and note that you've | ||
+ | // had first contact from the microcontroller. | ||
+ | // Otherwise, add the incoming byte to the array: | ||
+ | if (firstContact == false) { | ||
+ | if (inByte == ' | ||
+ | myPort.clear(); | ||
+ | firstContact = true; // you've had first contact from the microcontroller | ||
+ | myPort.write(' | ||
+ | } | ||
+ | } else { | ||
+ | // Add the latest byte from the serial port to array: | ||
+ | serialInArray[serialCount] = inByte; | ||
+ | serialCount++; | ||
+ | |||
+ | // If we have NbData bytes: | ||
+ | if (serialCount > NbData-1) { | ||
+ | ChoixPerso=serialInArray[0]; | ||
+ | CouleurPerso = serialInArray[1]; | ||
+ | xPerso =0.2*width +2*serialInArray[2]; | ||
+ | yPerso = 0.53*height + serialInArray[3]; | ||
+ | sPerso = 12*serialInArray[3]; | ||
+ | SaturPerso = serialInArray[3]; | ||
+ | | ||
+ | // print the values (for debugging purposes only): | ||
+ | println(ChoixPerso + " | ||
+ | | ||
+ | // Send a capital A to request new sensor readings: Envoie d'une letter " | ||
+ | myPort.write(' | ||
+ | // Reset serialCount: | ||
+ | serialCount = 0; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
====== Réalisation de la maquette ====== | ====== Réalisation de la maquette ====== | ||
vidéos, photos du making of... | vidéos, photos du making of... | ||