Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
wiki:flossmanuals:capacitif-plante-son-video:accueil [2022/04/30 17:31] damien.muti [Plantes sonores et vidéos - Capteur capacitif interne à la carte Arduino] |
wiki:flossmanuals:capacitif-plante-son-video:accueil [2022/04/30 18:00] (Version actuelle) damien.muti [À Télécharger] |
||
---|---|---|---|
Ligne 15: | Ligne 15: | ||
{{: | {{: | ||
- | ===== Intentions | + | ===== 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. | 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 | + | ===== 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. | 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 | + | ===== 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, | 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, | ||
Ligne 37: | Ligne 37: | ||
{{ : | {{ : | ||
- | ===== À Télécharger | + | ===== À Télécharger |
- | {{ : | + | **Ensemble des programmes Processing et Arduino :** |
+ | * {{ : | ||
- | **Télécharger les librairies :** | + | **Télécharger |
- | * Vidéo | + | * [[https:// |
- | * Sound | + | * [[https:// |
- | * Serial | + | * [[https:// |
**Problèmes récurrents :** | **Problèmes récurrents :** | ||
Ligne 50: | Ligne 51: | ||
* Attention aux vidéos et musiques trop lourdes. | * Attention aux vidéos et musiques trop lourdes. | ||
* Et si le programme ne marche toujours pas, vérifiez l' | * Et si le programme ne marche toujours pas, vérifiez l' | ||
- | ===== Code: ===== | + | ===== Code ===== |
**1** => **Processing :** __test_7plantes_sonores > Gestion_interactivite.pde__ | **1** => **Processing :** __test_7plantes_sonores > Gestion_interactivite.pde__ | ||
Ligne 434: | Ligne 435: | ||
} | } | ||
</ | </ | ||
- | |||
- | |||
- | ====== Intentions : explication du projet et objectifs ====== | ||
- | Dans le cadre d'un projet avec le musée des Beaux Arts, l' | ||
- | ====== Plans et schémas de fonctionnement ====== | ||
- | |||
- | ====== 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 xPerso, yPerso, ChoixPerso, CouleurPerso, | ||
- | boolean firstContact = false; | ||
- | PImage loubon; | ||
- | PImage bouvier; | ||
- | |||
- | |||
- | void setup() { | ||
- | size(1000, | ||
- | noStroke(); | ||
- | colorMode(HSB); | ||
- | |||
- | // Initialisation des variables | ||
- | ChoixPerso=0; | ||
- | CouleurPerso = 0; // | ||
- | xPerso = width/2; // Slider 1 | ||
- | yPerso = height/2; // Slider 2 - Distance | ||
- | sPerso = 250; //Taille du personnage | ||
- | bouvier = loadImage(" | ||
- | loubon= loadImage(" | ||
- | |||
- | // Print a list of the serial ports, for debugging purposes: | ||
- | printArray(Serial.list()); | ||
- | |||
- | // 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() { /////////////////////////////////////// | ||
- | background(loubon); | ||
- | // | ||
- | // Draw the shape | ||
- | // | ||
- | |||
- | if (ChoixPerso == 0) { | ||
- | bouvier = loadImage(" | ||
- | } | ||
- | if (ChoixPerso == 1){ | ||
- | | ||
- | } | ||
- | if (ChoixPerso == 2){ | ||
- | | ||
- | } | ||
- | image(bouvier, | ||
- | |||
- | } | ||
- | //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 = serialInArray[2]*3-50; | ||
- | yPerso = serialInArray[3]+100; | ||
- | sPerso = serialInArray[3]*2+100; | ||
- | | ||
- | // 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; | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Programme de test de couleur sur des images en PNG ==== | ||
- | De manière connexe, des tests sur la manière de modifier la couleur d'un contour SVG/PNG ont été effectués. L' | ||
- | |||
- | Le rendu est le suivant : | ||
- | |||
- | {{ : | ||
- | |||
- | |||
- | Le programme Processing est le suivant : {{ : | ||
- | < | ||
- | /** | ||
- | * Create Image. | ||
- | | ||
- | * The createImage() function provides a fresh buffer of pixels to play with. | ||
- | * This example creates an image gradient. | ||
- | */ | ||
- | |||
- | PImage img, imgIntiale; | ||
- | color c =color(# | ||
- | int r = 25, g = 42, b=118; | ||
- | // Arbre : 2480*2480 | ||
- | void setup() { | ||
- | size(1000, 570); | ||
- | background(255); | ||
- | imgIntiale = loadImage(" | ||
- | img = createImage(imgIntiale.width, | ||
- | |||
- | colorMode(HSB); | ||
- | |||
- | //float a = map(i, 0, img.pixels.length, | ||
- | // | ||
- | } | ||
- | |||
- | void draw() { | ||
- | background(255); | ||
- | image(imgIntiale, | ||
- | |||
- | for (int i = 0; i < imgIntiale.pixels.length; | ||
- | int r_i = (imgIntiale.pixels[i] >> 16) & 0xFF; // Faster way of getting red(argb) | ||
- | int g_i = (imgIntiale.pixels[i] >> 8) & 0xFF; // Faster way of getting green(argb) | ||
- | int b_i= imgIntiale.pixels[i] & 0xFF; // Faster way of getting blue(argb) | ||
- | if (r_i == r && g_i == g && b_i == b) { | ||
- | float h = map(mouseX, 0, width, 0, 255); | ||
- | //float h = 128; | ||
- | float s = saturation(imgIntiale.pixels[i]); | ||
- | float b = brightness(imgIntiale.pixels[i]); | ||
- | |||
- | // | ||
- | |||
- | img.pixels[i] = color(h, s, b); | ||
- | } | ||
- | img.updatePixels(); | ||
- | } | ||
- | |||
- | |||
- | image(img, 260, 260, 250, 250); | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | ====== Réalisation de la maquette ====== | ||
- | vidéos, photos du making of... | ||
- |