Kombotoris

Ce wiki a été archivé en 2018.

Le nouveau wiki se trouve à: ressources.labomedia.org

Les fonctionnalités sont désactivées: vous pouvez faire une recherche sur Google site:https://wiki.labomedia.org et découvrir La Labomedia.

De Centre de Ressources Numériques - Labomedia
Aller à : navigation, rechercher
Kombotoris
Fichier:SchemaKombo.pdf


Pour modifier la page utiliser l'onglet Modifier avec formulaire.

Résumé Rendre une sculpture interactive
Auteur(s) Camille et Virginie
Licence licencieux
Date de création 01 janvier 2017


Intentions / Contexte

Comment faire parler des objets? En leur adjoignant des capteurs pas chers

Principe de fonctionnement

Des photorésistances sont placées sur un objet. Les photorésistances entrent sur les entrées analogiques d'une arduino Mega. Le microcontrôleur détecte un changement sur les entrées et envoie une commande série à un lecteur de sons, qui sont stockés sur une carte SD. Le son lu est amplifié par un LM386 relié ensuite à un haut-parleur. Chaque capteur peut déclencher un son particulier. En revanche, il n'y a qu'une seule sortie possible (pas de multivoie, pas de multiphonie sauf si on dupliquait la sortie)

Besoins / Compétences

électronique et patience

Documentation

Code fonctionnel qui prend en compte l'éclairement ambiant :

///////////////// KOMBOTORIS ///////////////
//Variables globales//
const byte NEXT[8] = {0x7E, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xEF};
const byte BASSE_CONSO[8] = {0x7E, 0x0A, 0x00, 0x00, 0x00, 0xFF, 0xF6, 0xEF};
const byte ACTIF[8] = {0x7E, 0x09, 0x00, 0x00, 0x02, 0xFF, 0xF5, 0xEF};
const byte JOUER0[8] = {0x7E, 0x0D, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xEF};
const byte JOUER1[8] = {0x7E, 0x0D, 0x00, 0x00, 0x01, 0xFF, 0xF3, 0xEF};
const byte DEBUT = 0x7E, CMD_LEC = 0x03, Fb = 0x00, FIN = 0xEF;

boolean RELEVER_VALEURS = true;
byte PARAM1_LEC = 0x00, PARAM2_LEC = 0x01, CS1 = 0xFF, CS2 = 0x00; 
byte PISTE[8] = {DEBUT, CMD_LEC, Fb, PARAM1_LEC, PARAM2_LEC, CS1, CS2, FIN};
boolean MSG=true;
boolean MSG_EXT=false;
int factDiv=0,i=0, j=0;

int valCapteurs[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, valCapteursInit[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
//const int pin0 = 0;
//const int pin1 = 1;
//const int pin2 = 2;
const int TEMPO=8000, NB_CAPTEURS = 16;
////////////
//int SEUIL = 68;
float SEUIL = 0.09;
////////////


int etat, element = 0;

/// unsigned long et non pas float! ///
unsigned long temps_init=0, temps_courant=0, temps_ecoule=0;

/// !!! POUR DEBUG DU 10 MAI 2018///
int numPiste[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int n;
////////////////////////////////////


/////////////////////////////////////////////////////////////////
/////////////// INIT ////////////////////////////////////////////
/////////////////////////////////////////////////////////////////

void setup() {
  for(i=0; i<NB_CAPTEURS; i++){pinMode(i, INPUT);} 
  etat = 0;
  temps_init = 0; temps_init=0; temps_ecoule=0;
pinMode(13, OUTPUT);
Serial.begin(115200);
Serial1.begin(9600);
delay(1000);
cli(); //cesse les interruptions

//configuration du timer1
TCCR1A = 0; //mise à 0 du registre
TCCR1B = 0;
TCNT1 = 0; //initialisation du compteur à 0
//initialisation du registre comparateur pour obtenir une sous-fréquence à 20Hz
OCR1A = 3906; // correspond à (freqATMEL=16MHz)/(prescaler=1024*freq_voulue=20Hz) cette valeur doit être inférieure à 2exp16
TCCR1B |= (1<<WGM12); //mode CTC
TCCR1B |=(1<<CS12)|(1<CS10); //définition du prescaler. Correspond à 1024
TIMSK1 |= (1 <<OCIE1A);
sei(); //permet les interruptions
//// ET VOILÀ POUR LE TIMER. ////

for(j = 0; j<NB_CAPTEURS; j++) valCapteursInit[j] = analogRead(j);
delay(1000);
}

/// L'INTERRUPTION (PRIORITAIRE) NE FAIT QUE LEVER UN DRAPEAU (FLAG): ÉVITE DE BLOQUER LA BOUCLE ///
ISR(TIMER1_COMPA_vect){ RELEVER_VALEURS = true; }



////////////////////////////////////////////////////
void loop() {

///////////////////
//// AUTOMATE /////////
/////////////

//Serial.println(valCapteurs[0]);
  switch (etat) {
    case 0: 
       if(MSG) {
        print_all_values();
      }

//// LE DRAPEAU LEVÉ DANS L'INTERRUPTION EST UTILISÉ
////////////////////////// ICI! /////////////////////
/////////////////////////// |   /////////////////////
/////////////////////////// V   /////////////////////    
      if(RELEVER_VALEURS == true)
      {
        RELEVER_VALEURS = false;
        for(j = 0; j<NB_CAPTEURS; j++)
        {
          int valCapteur = analogRead(j);
          valCapteurs[j] = valCapteur; 
          if (valCapteursInit[j] > 10 && valCapteursInit[j] - valCapteur > SEUIL * valCapteursInit[j]){
                        digitalWrite(13, HIGH);
            element = j;
            Serial.print("élément détécté: "); Serial.println(element);Serial.print("valeur: "); Serial.println(valCapteursInit[j] - valCapteur);
            etat=1; MSG = 1; 
            n = element%6;
            ///////////// ENVOI COMMANDE //////////////////////////////////////////
            envoi_message_lecture_piste(numPiste[n]);
            //////////////////////////////////////////////////////////////////////
        
            if(MSG_EXT==true && MSG){
              debug_passage_etat();
            }

          
            break;
          }
        }
      }
      break;
      
      case 1:
       if(MSG){Serial.println("ETAT 1"); MSG = 0; temps_init = millis();} 
            temps_courant = millis();
            temps_ecoule = temps_courant-temps_init;
            if(temps_ecoule>TEMPO) {
              etat = 0; MSG=1;
              Serial.println("RETOUR ETAT 0. Temps ecoule:"); Serial.println(temps_ecoule); temps_ecoule = 0;
              digitalWrite(13, LOW);}     
      break;
      }
}

void envoi_message_lecture_piste(int n)
{
              PARAM2_LEC = byte(n); 
            Serial.println(n);
            //CALCUL DE LA PISTE!!!
            CS2 = 0xFF - (CMD_LEC + PARAM2_LEC) +1;
            PISTE[4] = PARAM2_LEC; PISTE[6] = CS2;
            ///////////// ENVOI COMMANDE //////////////////////////////////////////
            //Serial1.write(NEXT, 8);
            Serial1.write(PISTE, 8);
            //Serial1.write(NEXT, 8);
            //////////////////////////////////////////////////////////////////////
  }

void print_all_values() {
  Serial.println("ETAT INITIAL"); MSG = 0; 
  for (int i = 0; i < NB_CAPTEURS; i++) {
    Serial.print("valCapteurs [");
    Serial.print(i);
    Serial.print("]: ");
    Serial.println(valCapteurs[i]);

    Serial.print("valCapteursInit [");
    Serial.print(i);
    Serial.print("]: ");
    Serial.println(valCapteursInit[i]);
  }
}

void debug_passage_etat() {
                Serial.println("PASSAGE A ETAT 1"); Serial.print("entrée détectée: "); Serial.println(element);
                Serial.println(valCapteurs[element]); 
                Serial.print("commande envoyée: "); 
                Serial.print(PISTE[0], HEX); Serial.print(PISTE[1], HEX); Serial.print(PISTE[2], HEX);             
                Serial.print(PISTE[3], HEX);
                Serial.print(PISTE[4], HEX); Serial.print(PISTE[5], HEX); Serial.print(PISTE[6], HEX);       
                Serial.println(PISTE[7], HEX);
                return;
}

Code qui permet de tester la communication série entre arduino et lecteur de son (SOMOII):

///////////////// KOMBOTORIS ///////////////
//Variables globales//
const byte NEXT[8] = {0x7E, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xEF};
const byte BASSE_CONSO[8] = {0x7E, 0x0A, 0x00, 0x00, 0x00, 0xFF, 0xF6, 0xEF};
const byte ACTIF[8] = {0x7E, 0x09, 0x00, 0x00, 0x02, 0xFF, 0xF5, 0xEF};
const byte JOUER0[8] = {0x7E, 0x0D, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xEF};
const byte JOUER1[8] = {0x7E, 0x0D, 0x00, 0x00, 0x01, 0xFF, 0xF3, 0xEF};
const byte DEBUT = 0x7E, CMD_LEC = 0x03, Fb = 0x00, FIN = 0xEF;

byte PARAM1_LEC = 0x00, PARAM2_LEC = 0x01, CS1 = 0xFF, CS2 = 0x00; 
byte PISTE[8] = {DEBUT, CMD_LEC, Fb, PARAM1_LEC, PARAM2_LEC, CS1, CS2, FIN};
boolean MSG=true;
boolean MSG_EXT=false;
int factDiv=0,i=0, j=0;


const int TEMPO=8000, NB_CAPTEURS = 16, SEUIL = 50;
int indice, etat, element = 0;

/// unsigned long et non pas float! ///
unsigned long temps_init=0, temps_courant=0, temps_ecoule=0;

int numPiste[] = {1,3,4,6,12,14};
/////////////////////////////////////////////////////////////////
/////////////// INIT ////////////////////////////////////////////
/////////////////////////////////////////////////////////////////

void setup() {
  etat = 0;
  temps_init = 0; temps_init=0; temps_ecoule=0;
  indice = 1;
pinMode(13, OUTPUT);
Serial.begin(115200);
//communication avec le SOMO. Serial1: propre à l'arduino Mega
Serial1.begin(9600);
delay(500);
}




////////////////////////////////////////////////////
void loop() {

///////////////////
//// AUTOMATE /////////
/////////////

//Serial.println(valCapteurs[0]);
  switch (etat) {
    case 0: 
            digitalWrite(13, HIGH);
            indice = (indice + 1) %6; 
            etat=1; MSG = 1; 
            envoi_message_lecture_piste(numPiste[indice]);
      break;
      
      case 1:
       if(MSG){Serial.println("ETAT 1"); MSG = 0; temps_init = millis();} 
            digitalWrite(13, LOW);
            temps_courant = millis();
            temps_ecoule = temps_courant-temps_init;
            if(temps_ecoule>TEMPO) {
              etat = 0; MSG=1;
              Serial.println("RETOUR ETAT 0. Temps ecoule:"); Serial.println(temps_ecoule); temps_ecoule = 0;
              }     
      break;
      }
}

void envoi_message_lecture_piste(int n)
{
              PARAM2_LEC = byte(n); 
            Serial.println(n);
            //CALCUL DE LA PISTE!!!
            CS2 = 0xFF - (CMD_LEC + PARAM2_LEC) +1;
            PISTE[4] = PARAM2_LEC; PISTE[6] = CS2;
            ///////////// ENVOI COMMANDE //////////////////////////////////////////
            //Serial1.write(NEXT, 8);
            Serial1.write(PISTE, 8);
            //Serial1.write(NEXT, 8);
            //////////////////////////////////////////////////////////////////////
  }

À faire encore: -ajouter un potentiomètre pour régler le seuil -ajouter un bouton pour entrer en phase de configuration (pour prendre une nouvelle mesure de luminosité ambiante et initialiser les valeurs des capteurs)

Aujourd'hui 13 mai 2018 il faut échanger deux fils sur le potentiomètre entre le lecteur de son et l'ampli. (échanger fil vert (pour l'instant sur la sortie du SOMO) et fil orange (pour l'instant sur l'entrée du LM386))