Outils pour utilisateurs

Outils du site


ateliermobile

Porteurs du projet : Guillaume BERTRAND, Mélodie SOUTY, Flora WIERZBICKI
Date : 09/2016
Licence : Libre
Contexte : Ateliers Mobiles
Logiciels : Arduino 1.6.6

Contexte
Le projet suivant s'inscrit dans le cadre du projet “Ateliers Mobiles” initié par Juste Ici, collectif bisontin invitant des artistes à intervenir dans le quotidien de la ville. Nous avons été amenés à imaginer l'un des ateliers, axé sur la sensibilisation au numérique.

Les Ateliers Mobiles se déplacent à l'aide d'un triporteur. Ils peuvent se dérouler dans différents lieux de la ville de Besançon mais aussi lors d'invitations à des événements externes. Partagés avec le public, les projets présentés doivent être accessibles à tous.

Contraintes
- Facilité d'usage
- Facilité de transport (boîtes de 30x40x60, 40x60x60, volume maximum de 80x120x60)
- Solide, à l'épreuve des enfants

Projet
Initiation à la programmation. Le projet se déroule en deux parties :
- Jeu de carte permettant de “programmer son copain”
- Robot à deux roues programmable via un système de cartes à trous

Le jeu de cartes est composé de pictogrammes représentant des actions très basiques : avancer, tourner à gauche, tourner à droite, sauter, s'accroupir, se relever.
Le but du jeu est de faire accomplir une série d'actions à un tiers : très vite, on s'aperçoit de la présence de “bugs”.
Ce système permet alors d'adapter sa réflexion en fonction de la logique de la machine : programmation en amont des actions, et leur exécution rigoureuse, sans interprétation.


Il faudra ensuite programmer le robot de façon à se qu'il puisse se déplacer au sein d'un labyrinthe préalablement construit.
Il faut donc dans un premier temps construire le labyrinthe à partir des pièces modulaires mises à disposition (murs, joints, plateaux).
Puis, dans un second temps, programmer le robot : les actions à exécuter (tourner à droite, tourner à gauche, avancer) correspondent à une case trouée. Le participant doit préparer sa carte à trous en amont avant de la passer devant le système de lecture infrarouge du robot. Il n'a plus qu'à appuyer sur un bouton pour exécuter le programme.
La logique intégrée grâce au jeu de cartes est ainsi appliquée pour la résolution du labyrinthe. Les ordres (avancer, tourner) sont projetés dans un langage-machine extrêmement basique : celui de la carte à trous.


JEU DE CARTES
Lien jeu de cartes ?

LABYRINTHE
Design

Pièces médium 3mm
photo


ROBOT
Electronique
Composants

  • Une carte Arduino
  • Un double pont en H L298N
  • Deux moteurs à courant continu 360°
  • Trois capteurs infrarouges IRNY70
  • Trois résistances de 47KΩ
  • Trois résistances de 220Ω
  • Un bouton
  • Une batterie 5V 4000mA.h


Mesures des composants

Programme
Mode d'emploi Le programme a été pensé de manière à ce qu'au passage de la carte, les actions à effectuer se stockent dans une liste. Une fois la carte passée et que 4 secondes se sont écoulées sans qu'un capteur n'ai reçu d'informations, la liste d'actions sera effectuée après l'appui sur le bouton. Une fois la liste exécutée, un appui de 2s sur le bouton l'effacera. Le robot sera alors prêt à lire et stocker les instructions dictées par une nouvelle carte à trous.


Améliorations possibles :

  • Inclure des LEDs pour indiquer si on peux : passer une carte à trous, appuyer sur le bouton pour exécuter la liste, appuyer sur le bouton pour effacer la liste.


Code

 //entrées capteurs infrarouges/bouton
int capt = 2;
int capt2 = 4;
int capt3 = 5;
int bouton = 8;

//valeurs capteurs :
int val;
int val2;
int val3;
int PreviousVal;
int PreviousVal2;
int PreviousVal3;

#define MAX_Liste 100
int Liste[MAX_Liste]; //création de la liste
int frame = 0; //compteur d'étapes 

#define STATE_PROG 0
#define STATE_EXEC 1
#define STATE_DONE 2
int State = STATE_PROG;

int temps_defini = 2000; //définition du temps de maintient du bouton désiré en ms
long debut_appui1; //variable de stockage du temps 

//sorties moteurs :
int pinI1 = 9; 
int pinI2 = 10;
int pinI3 = 12; 
int pinI4 = 13;
int speedpin = 11; 
long test4sec; //deuxieme variable de stockage de temps

void setup() {
  pinMode (2, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(8, INPUT_PULLUP);
  Serial.begin(9600);
  pinMode (pinI1, OUTPUT);
  pinMode (pinI2, OUTPUT);
  pinMode (speedpin, OUTPUT);
  pinMode (pinI3, OUTPUT);
  pinMode (pinI4, OUTPUT);
}

void loop() {
  val = digitalRead(capt); //lecture des entrées de capteurs : 
  val2 = digitalRead(capt2);   
  val3 = digitalRead(capt3);   
  int etatBouton = digitalRead(bouton); //lecture de l'état du bouton (0/1)


//si mode programmation
if (STATE_PROG == State){
  if (val != PreviousVal || val2 != PreviousVal2 || val3 != PreviousVal3) {
    if ( val == 0 && val2 == 0 && val3 == 0) {
      PreviousVal = val;
      PreviousVal2 = val2;
      PreviousVal3 = val3;
      //comparaison des valeurs des capteurs entre les anciennes valeurs et les nouvelles
      test4sec = millis();
      Serial.println(test4sec);
    } else {
      if (PreviousVal == 0 && PreviousVal2 == 0 && PreviousVal3 == 0) {
        if (frame < MAX_Liste) {
          if (val == 1) {
            Liste[frame] = 100;
          } else if (val2 == 1) {
            Liste[frame] = 10;
          } else if (val3 == 1) {
            Liste[frame] = 1;
          }
          PreviousVal = val;
          PreviousVal2 = val2;
          PreviousVal3 = val3;
          frame++; //incrémentation pour passer à la case suivante
          //rangement dans la liste uniquement si changement d'état. 
        }
      }
    }
  }
  if(frame >=1){ //si la liste est remplie d'au moins une valeur
    if ( val == 0 && val2 == 0 && val3 == 0) { //que chaque valeur est égale à 0
      if(millis()-test4sec>4000){ //et que millis - test4sec est supérieur à 4 secondes
         Serial.println("OKAY"); //on enregistre la liste 
         State = STATE_EXEC; //on passe en état exécution
      }
    }
  }
}

if ( STATE_EXEC == State) {   
    analogWrite(speedpin, 250); //initialiser la vitesse d'exécution des moteurs
    if (etatBouton == 0) { 
      for (int i = 0; i < frame; i = i + 1) {
        Serial.print("ligne bande perforee: ");
        Serial.print(i);
        Serial.println();
        Serial.print("valeur: ");
        Serial.println(Liste[i]); //une fois que l'on atteind les 5 données, si le bouton est appuyé (0), alors on imprime sur le moniteur les valeurs récoltées
        //quand on obtient 100, on avance dans un seul sens ; quand on obtient un 1, on tourne dans un seul sens; quand on obtient 10, on tourne dans le sens inverse
        if(Liste[i] == 100 || Liste[i] == 1){
           digitalWrite(pinI1, LOW);
           digitalWrite(pinI2, HIGH);
         } 
         if(Liste[i] == 10){
          digitalWrite(pinI1, HIGH);
          digitalWrite(pinI2, LOW);
         } 
         //quand on obtient 100, on avance dans un seul sens ; quand on obtient un 10, on tourne dans un seul sens; quand on obtient 1, on tourne dans le sens inverse
         if(Liste[i] == 100 || Liste[i] == 10){
           digitalWrite(pinI3, LOW);
           digitalWrite(pinI4, HIGH);
         }
         if(Liste[i] == 1){
           digitalWrite(pinI3, LOW);
           digitalWrite(pinI4, HIGH);
         }
        delay(1000); 
         debut_appui1 = millis(); //si le bouton est relâché, alors on stocke le chiffre que le compteur affiche à partir de ce moment dans la variable debut_appui1
         }
        State = STATE_DONE; //une fois la liste exécutée, on passe à statut suivant (STATE_DONE)
      }
    }

  if ( STATE_DONE == State) //a-t-on bien terminé notre action ? si oui...
  {
       digitalWrite(pinI1, LOW);
       digitalWrite(pinI2, LOW); //on remet les sorties moteur à 0
       digitalWrite(pinI3, LOW);
       digitalWrite(pinI4, LOW);
     if (etatBouton == 1) //si bouton relâché
    {
      debut_appui1 = millis(); //alors on stocke le chiffre que le compteur affiche à partir de ce moment dans la variable debut_appui1
      delay(1000);
    }
    else if ((millis() - debut_appui1) >= temps_defini) //est-ce que le temps choisi est écoulé ? compteur - debut_appui1 = ou > au temps défini, alors... 
    {
      for(frame = 0; frame <  MAX_Liste; frame++){
        Liste[frame] = 0; 
      }
      frame = 0;
      State = STATE_PROG;       
      for (int frame = 0; frame < MAX_Liste; frame++)
      {
        Serial.print("ligne bande perforee: ");
        Serial.print(frame);
        Serial.println();
        Serial.print("valeur: ");
        Serial.println(Liste[frame]);   
      } //on remet tout à 0, et on vérifie en imprimant la liste dans le moniteur 
    }
  }
} 

Design

Pièces médium 3mm
photo

ateliermobile.txt · Dernière modification: 2016/09/27 19:20 par melo