Kombotoris
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 |
Sommaire
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))