Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente | |||
wiki:flossmanuals:capacitif_pante_son_video:accueil [2021/07/14 23:21] justine |
— (Version actuelle) | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ====== Plantes Sonores : ====== | ||
- | ====== Planta-Phonique====== | ||
- | ===== Des plantes interfaces ===== | ||
- | |||
- | {{: | ||
- | {{: | ||
- | |||
- | ===== Intentions : ===== | ||
- | |||
- | Dans le cadre de mon Macro-projet qui s’articule autour du jardin numérique mon intention a été de concevoir un cabinet de curiosité dans lequel le spectateur serait confronté à plusieurs expérimentations autour de la thématique de la plante digitalisée. L’expérimentation dont je vais vous expliciter s’intitule « Planta-phonique ». Cette expérimentation a germée tout d’abord avec cette envie de rendre visible l’invisible comme par exemple entendre le son d’une rose qui pousse. | ||
- | |||
- | ===== Objectifs : ===== | ||
- | |||
- | L’objectif de mon expérimentation est d’intégrer la part du vivant dans mes réalisations quelle soit humaine ou végétale. Pour ce faire, j’ai souhaité confectionner une table de mixage qui produit du son et envoie de la vidéo par des interactions avec la main. Cette table de mixage est entièrement composée de plantes dont chacune, un son et une vidéo peut lui être associés. Cette installation rend audible et visible le chant des plantes. Les plantes agissent ici comme une interface. | ||
- | |||
- | ===== Références : ===== | ||
- | |||
- | Pour ce projet je me suis inspirée de Jean Thoby un pépiniériste qui voue une véritable passion pour le monde végétale. Jean Thoby avec l’aide d’ingénieurs, | ||
- | |||
- | ===== Protocole pour 8 plantes: ===== | ||
- | {{: | ||
- | |||
- | ===== Installation: | ||
- | {{: | ||
- | Une fois les câbles bien branchés sur la BreadBoard, insérer les trois autres fils dans les plantes. Vérifiez bien que la terre est assez humide pour que les plantes puissent être conductrices. | ||
- | {{: | ||
- | |||
- | {{ : | ||
- | |||
- | ===== À Télécharger : ===== | ||
- | {{ : | ||
- | |||
- | **Télécharger les librairies :** | ||
- | * Vidéo | ||
- | * Sound | ||
- | * Serial | ||
- | |||
- | **Problèmes récurrents :** | ||
- | * Vérifier si c'est bien le bon port série. | ||
- | * Si vous utilisez un mac laissez charger le programme pendant plusieurs minutes. | ||
- | * Attention aux vidéos et musiques trop lourdes. | ||
- | * Et si le programme ne marche toujours pas, vérifiez l' | ||
- | ===== Code: ===== | ||
- | **1** => **Processing :** __test_7plantes_sonores > Gestion_interactivite.pde__ | ||
- | |||
- | < | ||
- | /** Plante sonore - Justine Gendreau | ||
- | | ||
- | /// librairies | ||
- | import processing.sound.*; | ||
- | import processing.video.*; | ||
- | import processing.serial.*; | ||
- | |||
- | |||
- | |||
- | // variables globales | ||
- | PImage im; // une image | ||
- | SoundFile[] son; // un son - un seul lecteur CD audio | ||
- | Movie vid; // une vidéo - un seul lecteur DVD vidéo | ||
- | |||
- | // bouton image active ? // est-ce que l' | ||
- | boolean animation_active = false; // true ou false (2 valleurs possibles) => 1 bit (0 ou 1) | ||
- | |||
- | // bouton son actif ? | ||
- | boolean son_actif = false; | ||
- | float tempsDebutSon = 0; // temps du début de la musique a été joué | ||
- | |||
- | // bouton videos active ? | ||
- | boolean video_active[]; | ||
- | |||
- | /// dialogue avec la carte Arduino | ||
- | Serial myPort; | ||
- | int inBuffer; | ||
- | int donneePortSerie; | ||
- | |||
- | // seuil de détection | ||
- | float seuil = 300; | ||
- | |||
- | // port serie | ||
- | int nPlantes = 8;///////////////////// | ||
- | int[] serialInArray = new int[nPlantes]; | ||
- | int serialCount = 0; // A count of how many bytes we receive | ||
- | int[] plante; | ||
- | boolean firstContact = false; | ||
- | |||
- | // média associés aux plantes | ||
- | String[] nomSonPlante; | ||
- | String[] nomvideosPlante; | ||
- | |||
- | |||
- | void setup() { // initialisation des paramètres d' | ||
- | size(1300, 860); | ||
- | noStroke(); | ||
- | background(0); | ||
- | |||
- | // initialisation des variables globale | ||
- | im = loadImage(" | ||
- | |||
- | // création et initialisation de tableau de valeur " | ||
- | plante = new int[nPlantes]; | ||
- | for (int i=0; i< | ||
- | plante[i] = 0; | ||
- | } | ||
- | |||
- | // son des plantes | ||
- | nomSonPlante = new String[nPlantes]; | ||
- | //for (int i = 0; i< | ||
- | // nomSonPlante[0] = " | ||
- | //} | ||
- | nomSonPlante[0]= " | ||
- | nomSonPlante[1]= " | ||
- | nomSonPlante[2]= " | ||
- | nomSonPlante[3]= " | ||
- | nomSonPlante[4]= " | ||
- | nomSonPlante[5]= " | ||
- | nomSonPlante[6]= " | ||
- | nomSonPlante[7]= " | ||
- | |||
- | // chargement des sons | ||
- | son =new SoundFile[nPlantes]; | ||
- | for (int i=0; i< | ||
- | son[i] = new SoundFile(this, | ||
- | } | ||
- | |||
- | // videos des plantes | ||
- | nomvideosPlante = new String[nPlantes]; | ||
- | nomvideosPlante[0]= " | ||
- | nomvideosPlante[1]= " | ||
- | nomvideosPlante[2]= " | ||
- | nomvideosPlante[3]= " | ||
- | nomvideosPlante[4]= " | ||
- | nomvideosPlante[5]= " | ||
- | nomvideosPlante[6]= " | ||
- | nomvideosPlante[7]= " | ||
- | | ||
- | video_active = new boolean[nPlantes]; | ||
- | for (int i=0; i< | ||
- | video_active[i]=false; | ||
- | } | ||
- | |||
- | |||
- | |||
- | // | ||
- | |||
- | // chargement de la videos | ||
- | vid = new Movie(this, " | ||
- | |||
- | /// Port série | ||
- | // Print a list of the serial ports, for debugging purposes: | ||
- | printArray(Serial.list()); | ||
- | |||
- | String portName = Serial.list()[2]; | ||
- | myPort = new Serial(this, | ||
- | } | ||
- | |||
- | void draw() { | ||
- | |||
- | |||
- | // print the values (for debugging purposes only): | ||
- | println(" | ||
- | + " | ||
- | + " | ||
- | |||
- | // | ||
- | // | ||
- | |||
- | ///////////////////////// | ||
- | for (int i=0; i< | ||
- | gestionSonPlante(i); | ||
- | gestionVideoPlante(i, | ||
- | } | ||
- | |||
- | //// affichage de la vidéo si la vidéo i est active //////////////////////////////////////// | ||
- | boolean une_video_active=false; | ||
- | for (int i=0; i< | ||
- | une_video_active = (une_video_active || video_active[i]); | ||
- | } | ||
- | |||
- | if (une_video_active) { | ||
- | image(vid, 0, 0, width, height); | ||
- | } else { | ||
- | background(0); | ||
- | } | ||
- | |||
- | |||
- | |||
- | |||
- | // affichage de l' | ||
- | //if (animation_active) { | ||
- | // lancerAnimation(); | ||
- | //} | ||
- | } | ||
- | </ | ||
- | |||
- | **2** => **Processing :** __ test_7plantes_sonores > test_7plantes_sonores.pde__ | ||
- | < | ||
- | ///////////////////////////////// | ||
- | void gestionSonPlante(int i){ | ||
- | | ||
- | if (plante[i]==255 | ||
- | // lancer le son associé à la plante i en boucle | ||
- | son[i].loop(); | ||
- | } | ||
- | else if (plante[i]== 0 && son[i].isPlaying()){ | ||
- | son[i].stop(); | ||
- | } | ||
- | // animation de la plante i | ||
- | | ||
- | } | ||
- | |||
- | //////////////////////////////////////////////// | ||
- | void gestionVideoPlante(int i, String nomVideo) { | ||
- | if (plante[i]==255 | ||
- | // jouer le son SSI la distance est inférieur à un seuil, strictement supérieure à 0 et si la vidéo ne joue pas déjà | ||
- | // lancement du son | ||
- | lancerVideo(i, | ||
- | } else if (plante[i]==0 && video_active[i]) { //si la distance est supérieure au seuil ET que la video joue : arrêter la video | ||
- | vid.stop(); | ||
- | clear(); | ||
- | video_active[i] = false; | ||
- | } | ||
- | } | ||
- | void lancerVideo(int i, String nomVideo) { | ||
- | if (video_active[i] == false) { // la vidéo 1 ne tourne pas | ||
- | // chargement de la video 1 | ||
- | vid = new Movie(this, nomVideo ); | ||
- | vid.loop(); | ||
- | video_active[i] = true; | ||
- | } | ||
- | } | ||
- | //////////////////////////////////////////////// | ||
- | void gestionAnimation() { | ||
- | if (donneePortSerie > 100) { // on appuie sur la touche " | ||
- | animation_active = true; | ||
- | } else { | ||
- | animation_active = false; | ||
- | } | ||
- | } | ||
- | void lancerAnimation() { | ||
- | float x = 30 + random(-20, 20); // random sur la position | ||
- | float y = 30 + random(-20, 20); | ||
- | image(im, x, y, 200, 200); | ||
- | } | ||
- | |||
- | |||
- | |||
- | ////////////////////////////////////// | ||
- | void movieEvent(Movie movie) { //// gestion de la vidéo | ||
- | vid.read(); | ||
- | } | ||
- | </ | ||
- | **3** => **Processing :** __test_7plantes_sonores > SerialEvent.pde__ | ||
- | < | ||
- | void serialEvent(Serial myPort) { | ||
- | // 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 3 bytes: | ||
- | if (serialCount > nPlantes-1 ) { | ||
- | for (int i=0; i< | ||
- | plante[i] = serialInArray[i]; | ||
- | } | ||
- | //plante[0] = serialInArray[0]; | ||
- | //plante[1] = serialInArray[1]; | ||
- | //plante[2] = serialInArray[2]; | ||
- | //plante[3] = serialInArray[3]; | ||
- | //plante[4] = serialInArray[4]; | ||
- | //plante[5] = serialInArray[5]; | ||
- | //plante[6] = serialInArray[6]; | ||
- | //plante[7] = serialInArray[7]; | ||
- | |||
- | // print the values (for debugging purposes only): | ||
- | // | ||
- | |||
- | // Send a capital A to request new sensor readings: | ||
- | myPort.write(' | ||
- | // Reset serialCount: | ||
- | serialCount = 0; | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | </ | ||
- | |||
- | **4** => **Arduino** : test_7plantes_sonores.ino.ino | ||
- | < | ||
- | |||
- | //Import a library from the Arduino folder | ||
- | #include < | ||
- | /////////////////////////////// | ||
- | byte Ncapteurs = 8; | ||
- | |||
- | //Select the two pins that will act as a capacitor | ||
- | CapacitiveSensor | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | }; | ||
- | long* capSensorVal ; // mémorise la valeur lue sur chaque capteurs | ||
- | |||
- | //Insert the minimum value provided by the sensor to detect the touch | ||
- | int seuilDetection = 500; // seuil de détection sur la valeur donné par le capteur capacitif | ||
- | const int ledPin = 13; | ||
- | |||
- | int* plante ; | ||
- | |||
- | // port série | ||
- | int inByte = 0; | ||
- | |||
- | ///////////////////// | ||
- | boolean debug1 = false, debug2 = 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 | ||
- | } | ||
- | |||
- | // création des tableaux | ||
- | capSensorVal = malloc(Ncapteurs * sizeof(long)); | ||
- | plante = malloc(Ncapteurs * sizeof(int)); | ||
- | // initialisation des tableaux | ||
- | for (int i = 0; i < Ncapteurs; i++) { | ||
- | capSensorVal[i] = 0; | ||
- | plante[i] = 0; | ||
- | } | ||
- | |||
- | pinMode(ledPin, | ||
- | // init des capteurs capacitifs | ||
- | cs_2[0].set_CS_AutocaL_Millis(0xFFFFFFFF); | ||
- | |||
- | establishContact(); | ||
- | } | ||
- | |||
- | void loop() { | ||
- | // if we get a valid byte, read analog ins: | ||
- | if (Serial.available() > 0) { | ||
- | // get incoming byte: | ||
- | inByte = Serial.read(); | ||
- | |||
- | long start = millis(); | ||
- | for (int i = 0; i < Ncapteurs; i++) { | ||
- | capSensorVal[i] = cs_2[i].capacitiveSensor(30); | ||
- | } | ||
- | |||
- | if (debug1) { | ||
- | Serial.print(millis() - start); | ||
- | Serial.print(" | ||
- | |||
- | for (int i = 0; i < Ncapteurs; i++) { | ||
- | Serial.print(capSensorVal[i]); | ||
- | Serial.print(" | ||
- | } | ||
- | Serial.println("" | ||
- | } | ||
- | |||
- | |||
- | |||
- | // test des valeurs des capteurs | ||
- | for (int i = 0; i < Ncapteurs; i++) { | ||
- | plante[i] = testCapteur(capSensorVal[i], | ||
- | } | ||
- | if (debug2) { | ||
- | for (int i = 0; i < Ncapteurs; i++) { | ||
- | Serial.print(plante[i]); | ||
- | Serial.print(" | ||
- | } | ||
- | Serial.println("" | ||
- | } | ||
- | else { | ||
- | // send sensor values: on envoie à Processing l' | ||
- | for (int i = 0; i < Ncapteurs; i++) { | ||
- | Serial.write(plante[i]); | ||
- | } | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | void establishContact() { | ||
- | while (Serial.available() <= 0) { | ||
- | Serial.print(' | ||
- | delay(300); | ||
- | } | ||
- | } | ||
- | |||
- | int testCapteur(long sensorVal, long seuilDetection) { | ||
- | // sensorVal : valeur du capteur | ||
- | // seuilDetection : seuil de détection | ||
- | |||
- | if (sensorVal > seuilDetection ) { | ||
- | //Turn on the led | ||
- | digitalWrite(ledPin, | ||
- | // plante i activée | ||
- | return 255; | ||
- | } | ||
- | //Touch undetected | ||
- | else { | ||
- | //Turn off the led | ||
- | digitalWrite(ledPin, | ||
- | // plante i inactivée | ||
- | return 0; | ||
- | } | ||
- | |||
- | } | ||
- | </ | ||
- | |||