Kubbotchi

De fablabo



Un jeu où il faut nourrir un robot en colère avec des engrenages

Kubbotchi.png

Statut du projet

Fonctionnel

Statut de la publication

Publié

License

CC-by-sa-3.0 - Creative Commons Attribution CC-by-sa-3.0 France

Inspiration

Furby, Wall-E

Fichiers source

Conception-kubbotchi.zip

Lien




Du 26 au 30 mars 2018, nous avons eu la chance de pouvoir travailler à la Plateforme C de Nantes. Le but de ce workshop était de créer un cube qui interagit avec nous, interactions à la fois directes et indirectes.

Présentation de Kubbotchi à l'issue du Workshop Cube 2018

Concept

Nous avons créé un jeu où il faut nourrir un petit robot nommé Kubbotchi, qui signifie câlin en japonais. La seule difficulté est de bien viser, car, en colère contre l'humanité, il va bouger dans tous les sens. Les engrenages doivent être lancés dans sa poche avant et lorsque le robot les a tous avalés, l'utilisateur va s'éloigner de lui et le robot va se calmer.

Schéma de l'aspect général du robot

Conception du cube interactif

Fabrication du robot-cube

Pour la conception de notre robot en forme de cube, nous avons utilisé du plastique noir de 20x20cm. Par dessus, aussi en plastique, nous avons placé sa tête. Pour ses bras, nous avons utilisé du polystyrène peint avec de l’acrylique noire et des fils de cuivre enroulés pour les antennes. Le corps est composé d’une poche avant, pour pouvoir y glisser des engrenages en carton. Pour rendre le robot plus attractif, nous avons collé des roues sur ses cotés et créé des autocollants en forme de bouche, d'engrenages, de squelette et pour écrire son nom en japonais. Ses autocollants ont été découpé à l'aide de la découpe laser et collés sur le robot. Tous les matériaux, excepté les planches de plastique et les roues, ont été trouvés dans la réserve du Fablab.

Antennes réalisées avec l'intérieur de câbles électriques entortillés
Antennes réalisées avec l'intérieur de câbles électriques entortillés

Capteurs

Nous avons utilisé différents capteurs reliés à une page HTML et deux cartes Photon. La liste des capteurs utilisés est la suivante : - 2 écrans OLED (pour animer les yeux) - 2 capteurs piezo (pour détecter les engrenages et faire du son) - 1 servomoteur (pour faire tourner le robot sur lui-même) - 1 capteur ultrasons (pour capter la distance entre le robot et le joueur) Les capteurs et les cartes sont installés à l’intérieur de notre robot. En effet les écrans OLED apparaissent dans la tête, les capteurs piezo sont placés dans la poche et dans le cube, et le servomoteur est relié à une deuxième carte Photon implantée dans un plateau permettant au robot de tourner sur lui-même (à la manière d'un plateau de fromage).

Capteurs et cartes utilisés pour les interactions et cachés à l'intérieur du cube

Partie Technique

Voici le code nécessaire pour le fonctionnement des cartes Photon a partir du site Particule Build :

/* // This #include statement was automatically added by the Particle IDE.

  1. include <Grove_OLED_128x64.h>

// SONG BUZZER //

/* SparkFun Inventor's Kit for Photon

   Experiment 5 - Part 1: Music Time
   This sketch was written by SparkFun Electronics
   August 31, 2015
   https://github.com/sparkfun/Inventors_Kit_For_Photon_Experiments
   This application plays Rick Astley - Never Gonna Give You Up song
   Development environment specifics:
   Particle Build environment (https://www.particle.io/build)
   Particle Photon RedBoard
   Released under the MIT License (http://opensource.org/licenses/MIT)
  • /

const int speakerPin = A4;

// We'll set up an array with the notes we want to play // change these values to make different songs!

// Length must equal the total number of notes and spaces

const int songLength = 18;

// Notes is an array of text characters corresponding to the notes // in your song. A space represents a rest (no tone)

char notes[] = "cccd e d cedd c fda ag cdfdg gf "; // a space represents a rest

// Beats is an array of values for each note and rest. // A "1" represents a quarter-note, 2 a half-note, etc. // Don't forget that the rests (spaces) need a length as well.

int beats[] = {2,2,2,3,4,3,2,2,2,3,4,1,1,1,4,4,2};

// The tempo is how fast to play the song. // To make the song play faster, decrease this value.

int tempo = 150;


////

//SENSER BASE

int sensorPin = A0; // entrée analogique du capteur int ledPin = 7; // led intégrée int THRESHOLD = 15;


  1. if defined (SPARK)

// Nothing to include if Spark

  1. else
  2. include <Wire.h>
  3. include <avr/pgmspace.h>
  4. endif

// préparer l'image! static unsigned char image[] PROGMEM ={ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };


int compteur = 0; long start;

////////////////////////// AFFICHER IMAGE ////////////////////



  1. define CLK 2
  2. define DIO 3



void setup() {



 //SOUND DETECT


// OLED IMAGE {

 Wire.begin();
 SeeedOled.init();  //initialze SEEED OLED display
 SeeedOled.clearDisplay();               // clear the screen and set start position to top left corner
 SeeedOled.drawBitmap(image,1024);   // 1024 = 128 Pixels * 64 Pixels / 8
 
 SeeedOled.setNormalDisplay();      //Set display to normal mode (i.e non-inverse mode)
 //SeeedOled.setPageMode();           //Set addressing mode to Page Mode
 //SeeedOled.setTextXY(0,0);          //Set the cursor to Xth Page, Yth Column
 //SeeedOled.putString("Hello World!"); //Print the String

} pinMode(speakerPin, OUTPUT);

 // We only want to play the song once, so we'll put it in the setup loop
 int i, duration;
 for (i = 0; i < songLength; i++) // step through the song arrays
 {
   duration = beats[i] * tempo;  // length of note/rest in ms
   if (notes[i] == ' ')          // is this a rest? 
   {
     delay(duration);            // then pause for a moment
   }
   else                          // otherwise, play the note
   {
     tone(speakerPin, frequency(notes[i]), duration);
     delay(duration);            // wait for tone to finish
   }
   delay(tempo/20);              // brief pause between notes
 }

}


void loop() {



  int val = analogRead(sensorPin);
 if (val >= THRESHOLD)  {
  Wire.begin();
 SeeedOled.init();  //initialze SEEED OLED display
 SeeedOled.clearDisplay();               // clear the screen and set start position to top left corner
 SeeedOled.drawBitmap(image,1024);   // 1024 = 128 Pixels * 64 Pixels / 8
 
 SeeedOled.setNormalDisplay();      //Set display to normal mode (i.e non-inverse mode)
 //SeeedOled.setPageMode();           //Set addressing mode to Page Mode
 //SeeedOled.setTextXY(0,0);          //Set the cursor to Xth Page, Yth Column
 //SeeedOled.putString("Hello World!"); //Print the String
 }
else{
    
}

}




int frequency(char note) {

 // This function takes a note character (a-g), and returns the
 // corresponding frequency in Hz for the tone() function.
 int i;
 const int numNotes = 8;  // number of notes we're storing
 // The following arrays hold the note characters and their
 // corresponding frequencies. The last "C" note is uppercase
 // to separate it from the first lowercase "c". If you want to
 // add more notes, you'll need to use unique characters.
 // For the "char" (character) type, we put single characters
 // in single quotes.
 char names[] = { 'a', 'd', 'b', 'e', 'g', 'a', 'b', 'C' };
 int frequencies[] = {300, 400, 500, 600, 700, 600, 500, 600};
 // Now we'll search through the letters in the array, and if
 // we find it, we'll return the frequency for that note.
 for (i = 0; i < numNotes; i++)  // Step through the notes
 {
   if (names[i] == note)         // Is this the one?
   {
     return(frequencies[i]);     // Yes! Return the frequency
   }
 }
 return(0);  // We looked through everything and didn't find it,
             // but we still need to return a value, so return 0.

}

  • /