Cube de l'Au-delà

De fablabo



Connectez-vous aux esprits avec le Cube de l'Au-delà



Nous avons décidé de concevoir un cube interactif autour de la voyance et utiliser son potentiel humoristique. Nous voulions mettre en avant le côté “charlatan” souvent associé à cette pratique.

Moodboard.jpg

Grâce à nos recherches, nous en avons retiré des codes graphiques : surcharge, dorures, runes, horoscope, couleurs sombres, cartes de tarot… Nous avons également compris qu’il fallait montrer l’aspect “rituel” en créant une réelle expérience. L’idée de payer était aussi primordiale pour représenter notre idée de “voyante-escroc”. Ainsi, nous avons ajouté dans notre algorithme le fait que plus l’utilisateur paie, plus sa prédiction sera positive.

Description

Ainsi, nous avons créé le Cube de l’Au-Delà. Le rituel fonctionne ainsi : D’abord, tous les utilisateurs se connectent avec les esprits : chacun place son doigt sur les capteurs tout autour du cube. L’utilisateur peut décrocher le téléphone, composer le numéro de l’Au-delà et poser la question qu’il souhaite aux esprits. Il insère une pièce dans le cube (deux euros, c’est pas mal ;) ). Après quelques secondes, les lettres du cubes s’illuminent à la manière d’un ouija et l’utilisateur peut recevoir sa prédiction. A la fin de l’expérience, la page @Lecimetiere poste la prédiction émise par les esprits.

Vidéo de la création du Cube de l'Au-delà

Video-cube-montage.png
cube de l'au-dela


Matériel

Pour réaliser le cube de l’Au-Delà, nous avons utilisé : 6 faces de contreplaqué (0.4 mm), un vieux téléphone, une carte photon, un ruban led (26 leds pour les lettres de l’alphabet), un capteur de pression, un bouton, un moteur, des résistances, quatre boutons capacitifs, des fils, du vinyle, de la peinture dorée - bleue - noire

Avec ces outils : une découpe laser une découpe vinyle de l’huile de coude un fer à souder un pistolet à colle outils de bricolage : perceuse, scie...

Avec ces logiciels : Adobe Illustrator Particle.io InkScape

Schema fonctionnel.png
Schema precis.png

Tutoriel

Etape 1 : Création du cube

Découpe

Pour réaliser un cube de 20x20x20 cm, il faut tout d’abord découper les 6 faces à l’aide de la découpe laser. Pour cela nous avons dessiné les découpes sur le logiciel Adobe Illustrator sans oublier de prévoir l’épaisseur du matériaux, puis nous avons envoyés nos fichiers sur le logiciel Inkscape.

Cube-decoupe laser.png

Assemblage

Une fois la découpe terminée nous avons peint notre cube avec de la peinture acrylique. Puis nous avons collez les faces avec de la colle à bois.

Cube-decoupelaser.png

Vous trouverez ci-joint le fichier Illustrator : Télécharger le fichier source de la découpe laser

Sur la face du dessus, nous avons découpé les 26 lettres de l’alphabet avec une typographie à empattement et un trou pour les pièces. Pour chaque lettre contenant une boucle, nous avons dû modifier chaque lettre avec des ponts pour éviter qu’elle ne tombe à la découpe (heureusement, nous nous en sommes rendus compte rapidement). Nous avons fait un trou sur toutes les autres faces à l’emplacement des doigts. Sur la face du dessous il ne faut pas oublier de prévoir un trou pour passer le fil de la carte photon.

Décoration

Nous voulions graver des motifs sur les plaques, mais avec la peinture, ça ne se serait pas vu…

Nous avons donc décidé de créer un pochoir avec du vinyle. Pour cela nous avons créé nos formes sur Adobe Illustrator puis comme pour la découpe nous avons envoyé notre fichier sur Inkscape.

Pochoir vinyle.png

Une fois le fichier sorti de la découpe vinyle, il faut enlever les morceaux que l’on souhaite voir sur le cube. Puis avec du papier transfert, poser sur le cube le pochoir en vinyle. Attention à bien frotter pour que le pochoir se colle sur le cube. Il faut ensuite retirer le papier transfert délicatement puis bomber le cube. Nous avons laissé sécher toute un nuit.

Decoupe vinyle.png

Vous trouverez ci-joint le fichier Illustrator : Télécharger le fichier source de la découpe vinyle

Etape 2 : Installation des capteurs

Nous avons ensuite coupé le ruban led en plusieurs morceaux pour que les leds coïncident avec la découpe laser, puis nous les avons soudé ensemble.

Nous avions la chance d’avoir un vieux combiné de téléphone que nous voulions absolument utiliser. Nous l’avons démonté pour y insérer un bouton, au sein du mécanisme. Le bouton collé ainsi, il s’enclenche quand on décroche/raccroche le combiné.

Ensuite, nous avons ajouté quatre boutons capacitifs sur chaque face du cube grâce à du papier noir. Sur la face du haut, nous avons collé un compartiment à monnaie avec un capteur flexiforce (utilisé comme un capteur de poids).

Nous voulions ajouter du son mécanique pour montrer le contact avec les esprits. Nous avons percé un objet métallique pour le bloquer sur une planche en bois avec un moteur. Dès que le moteur tourne, un petit pic vient frotter l’objet métallique pour émettre un son un peu bizarre.

Etape 3 : Le code

Concernant le code, il est assez simple. Nous avons utilisé la librairie neopixel et également un système de switch/case avec 12 différents mots de 3 lettres à chaque fois. A la fin de la prédiction, on envoie une information à IFTTT (il faut avoir un compte lié à son photon et au compte twitter sur le site) qui publie sur Twitter.

TELECHARGER LE CODE DU CUBE (aussi disponible en bas de page)

L’étape la plus difficile : la mise en place !

Mise en scene-cube.png

Et le meilleur pour la fin… La scénographie. L’univers de la voyance et du spirituel nécessite une belle mise en scène, toujours dans l’exagération.

Mise en scene.png

Un grand merci à Pierre Commenge et Clément Gault mais également aux animateurs de la Plateforme C pour leur aide.

//Code pour PHOTON permettant de créer un cube façon OUIJA qui prédit des mots au hasard.

//bibliothèque pour les bandeaux led

  1. include <neopixel.h>


  1. define PIXEL_PIN D2 //pin du bandeau
  2. define PIXEL_COUNT 26 //nb de leds du bandeau
  3. define PIXEL_TYPE WS2812B

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);


long etat; // moment ou on appuie sur le bouton du téléphone

int mot; // variable du mot qui va sortir int pression = A4; //bouton pression à pour capter l'argent bool argent = false; bool boutonc = false; bool bouton_appuye = false; bool hold = true;

String prediction; //prédiction du cube

int broche_bouton1 = D0; //bouton du téléphone int bouton1 = D1; //boutons capacitifs autour du cube int bouton2 = D3; int bouton3 = D4; int bouton4 = D5; int cool ;

Servo servo; const int moteur = A1;


void setup() {

   Serial.begin(9600);
   strip.begin();
   strip.show();


   //initialisation des pins
   pinMode(broche_bouton1, INPUT);
   pinMode(pression, INPUT);
   pinMode(bouton1, INPUT);
   pinMode(bouton2, INPUT);
   pinMode(bouton3, INPUT);
   pinMode(bouton4, INPUT);
   strip.setBrightness(50);

}

void loop() {

   //on teste la valeur du bouton pression dès le début
   int valeurP = analogRead(pression);
   //si tous les utilisateurs posent leur doigt sur le cube
   if((digitalRead(bouton3) == 1)  &&  (digitalRead(bouton4) == 1) && (digitalRead(bouton2) == 1) && (digitalRead(bouton1) == 1) && (boutonc == false)){
       //on déclenche le moteur
       servo.attach(moteur);
       servo.write(0);
       delay(1000);
       servo.write(90);
       delay(1000);
       servo.detach();
       //on change la bool pour faire qu'une seule fois la boucle
       boutonc = true;
   }
   //si on met une piece
   if(analogRead(pression) != valeurP) {
   //on change la bool
   argent = true;
   }
   //si on appuie sur le bouton, que tous les boutons on été appuyé simultannément au moins une fois et qu'on a mis de l'argent (ou qu'on appuie sur le bouton D6 pour directement accéder aux mots)
   if ((digitalRead(broche_bouton1) == HIGH) && (bouton_appuye == false) && (argent) && (boutonc) || (digitalRead(D6) == 1)) {
       //on calcule la durée
       etat = millis();
       bouton_appuye = true;
       // grâce à la pin A0 on créé une variable random mot
       randomSeed(analogRead(A0));
       mot = int(random(12)+1);
   }
   //on lance les lettres au hasard entre le case 1 et 12
   if ((millis()-etat<5000) && (bouton_appuye) && (hold)){


       switch(mot){
           case 1 : // NON
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(11, strip.Color(255,  255, 255)); //1
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(11, strip.Color(255,  255, 255)); //3
               strip.setPixelColor(17, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(11, strip.Color(0,  0, 0)); //2
                   strip.setBrightness(50);
                   strip.setPixelColor(17, strip.Color(255,  255, 255));
                   }


           prediction = "non";


           break;
           case 2 :  // OUI
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(17, strip.Color(255,  255, 255)); //1
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(7, strip.Color(255,  255, 255)); //3
               strip.setPixelColor(12, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(17, strip.Color(0,  0, 0)); //2
                   strip.setBrightness(50);
                   strip.setPixelColor(12, strip.Color(255,  255, 255));
               }
           prediction = "oui";
           break;
           case 3 : //BOF
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(5, strip.Color(255,  255, 255)); //1
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(1, strip.Color(255,  255, 255)); //3
               strip.setPixelColor(17, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(5, strip.Color(0,  0, 0)); //2
                   strip.setBrightness(50);
                   strip.setPixelColor(17, strip.Color(255,  255, 255));
               }
           prediction = "bof";
           break;


           case 4 : //TKT
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(13, strip.Color(255,  255, 255)); //1
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(13, strip.Color(255,  255, 255)); //3
               strip.setPixelColor(8, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(13, strip.Color(0,  0, 0)); //2
                   strip.setBrightness(50);
                   strip.setPixelColor(8, strip.Color(255,  255, 255));
               }
           prediction = "tkt";
           break;
           case 5 : //OMG
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(17, strip.Color(255,  255, 255)); //1
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(0, strip.Color(255,  255, 255)); //3
               strip.setPixelColor(10, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(17, strip.Color(0,  0, 0)); //2
                   strip.setBrightness(50);
                   strip.setPixelColor(10, strip.Color(255,  255, 255));
               }
           prediction = "omg";
           break;
           case 6 : //NOP
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(11, strip.Color(255,  255, 255)); //1 N
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(16, strip.Color(255,  255, 255)); //3 P
               strip.setPixelColor(17, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(11, strip.Color(0,  0, 0)); //2 O
                   strip.setBrightness(50);
                   strip.setPixelColor(17, strip.Color(255,  255, 255));
               }
           prediction = "nop";
           break;


           case 7 : //LOL
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(9, strip.Color(255,  255, 255)); //1 L
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(9, strip.Color(255,  255, 255)); //3 L
               strip.setPixelColor(17, strip.Color(0,  0, 0));
                               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(9, strip.Color(0,  0, 0)); //2 O
                   strip.setBrightness(50);
                   strip.setPixelColor(17, strip.Color(255,  255, 255));
                   }
           prediction = "lol";
           break;


           case 8 : //LOL
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(9, strip.Color(255,  255, 255)); //1
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(9, strip.Color(255,  255, 255)); //3
               strip.setPixelColor(17, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(9, strip.Color(0,  0, 0)); //2
                   strip.setBrightness(50);
                   strip.setPixelColor(17, strip.Color(255,  255, 255));
               }
           prediction = "lol";
           break;
           case 9 : //OUF
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(17, strip.Color(255,  255, 255)); //1  O
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(1, strip.Color(255,  255, 255)); //3 F
               strip.setPixelColor(12, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(17, strip.Color(0,  0, 0)); //2  U
                   strip.setBrightness(50);
                   strip.setPixelColor(12, strip.Color(255,  255, 255));
               }
           prediction = "ouf";
           break;
           case 10 : //con
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(4, strip.Color(255,  255, 255)); //1  C
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(11, strip.Color(255,  255, 255)); //3 N
               strip.setPixelColor(17, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(4, strip.Color(0,  0, 0)); //2  O
                   strip.setBrightness(50);
                   strip.setPixelColor(17, strip.Color(255,  255, 255));
               }
           prediction = "con";
           break;
           case 11 : //dsl
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(3, strip.Color(255,  255, 255)); //1  D
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(9, strip.Color(255,  255, 255)); //3 l
               strip.setPixelColor(14, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(3, strip.Color(0,  0, 0)); //2  s
                   strip.setBrightness(50);
                   strip.setPixelColor(14, strip.Color(255,  255, 255));
               }
           prediction = "dsl";
           break;
           case 12 : //BOF
           if(millis()-etat<2000) {
               strip.setBrightness(50);
               strip.setPixelColor(5, strip.Color(255,  255, 255)); //1
           } else if(millis()-etat>3500) {
               strip.setBrightness(50);
               strip.setPixelColor(1, strip.Color(255,  255, 255)); //3
               strip.setPixelColor(17, strip.Color(0,  0, 0));
               delay(1500);
               hold = false;
           } else {
                   strip.setPixelColor(5, strip.Color(0,  0, 0)); //2
                   strip.setBrightness(50);
                   strip.setPixelColor(17, strip.Color(255,  255, 255));
               }
           prediction = "bof";
           break;


       }
       //on envoie grâce a IFTTT un message avec le contenu de la prédiction
       Particle.publish("prediction", "Les morts ont compris ta question, pour eux c'est... "+ prediction);
   }
   else {
       // on arrete la boucle
        bouton_appuye=false;
        strip.setBrightness(0);
   }
   strip.show();
   delay(300);

}