blog/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/index.md
Louis Vallat c70ae62b47
feat: massive overhaul
Signed-off-by: Louis Vallat <contact@louis-vallat.fr>
2024-04-12 17:45:33 +02:00

9.5 KiB
Raw Blame History

+++ title = "Robot timide le robot qui fuit la lumière" description = "Création d'un robot timide pour un projet scolaire." date = 2022-05-19

[taxonomies] tags = ["maker", "fablab", "robotique"] +++

Création d'un robot timide pour un projet scolaire.

Article cloné depuis Eirlab

Dans le cadre de loption Makers proposée en deuxième année à lENSEIRB-MATMECA, en filière Informatique, un robot timide a vu le jour au sein dEirlab. Cet article est un guide pour expliquer comment reproduire notre travail, dans le plus pur esprit Maker.

Une vue de 3/4 face du robot finalisé

Concept de base

Nous voulions mettre en oeuvre un robot qui détecterait en temps réel la luminosité autour de lui et ce dans le but de se déplacer vers lendroit le plus sombre de la pièce dans lequel il se trouve, et de sy cacher. Un autre mode est aussi disponible, permettant non pas daller vers lendroit le plus sombre, mais à linverse de fuir lendroit le plus lumineux, pour avoir deux manières de voir le problème.

Une vue de face du robot timide dans sa forme finale.

Du matériel

Avant de pouvoir travailler sur une partie logicielle du projet, il faut évidemment avoir une base physique pour accueillir et exécuter ce code.

À noter que ce projet na nécessité aucune dépense et a été réalisé entièrement avec du matériel déjà disponible au sein du Fablab.

Liste du matériel

Pour pouvoir reproduire ce projet, il vous faudra avoir en votre possession les éléments suivants :

  • 1x Arduino Uno (ou clone équivalent) cest la tête pensante de ce projet
  • 1x Arduino Motor Shield pour contrôler les deux moteurs du robot
  • 2x moteurs à courant continu, ici des FT DC 130D pour se mouvoir dans lespace
  • 3x capteurs de distance à ultrasons HC-SR04 pour éviter de rencontrer des murs trop souvent
  • 4x photo résistances une par côté, pour pouvoir détecter la luminosité autour de lui
  • 4x résistances de 2kΩ pour le circuit des photo résistances, permettant davoir une amplitude optimale
  • 1x pile 9 Volts pour alimenter tout le système
  • 1x boîtier pour pile 9 Volts [OPTIONNEL] pour éviter de perdre lunique source dalimentation du robot

Base du châssis

Le châssis est une plaque en bois, ici du contreplaqué de 5 millimètres dépaisseur, qui a été usinée à laide de la découpeuse laser du Fablab. Elle mesure 17×15,5 centimètres, et dispose de deux bords biseautés pour avoir une vue frontale des obstacles que le robot pourrait rencontrer. Ici, ces biseaux ont des angles de 20 degrés, sur 4,5 centimètres. La plaque de base est ensuite percée pour accueillir les différents modules du robot. Les éléments les plus légers ou risquant moins de se détacher sont fixés par un simple système de mâchoire, prenant en étau la plaque de bois dans une forme de U.

La forme de U pour prendre la plaque de base en mâchoire et tenir un capteur par pression.

Alimentation

Pour lalimentation du robot, on vient envoyer 9 Volts dune source quelconque, dune pile ou dune alimentation stabilisée par exemple, dans lentrée VIN de lArduino, qui sera après régulée en interne pour donner les différents rails dalimentation. Cette entrée dalimentation est connectée en interne au port DC “barrel jack” de lArduino, donc avant les régulateurs de courant, et prend donc des tensions entre 5 et 9 Volts.

Dans ce projet, nous utilisons une pile 9 Volts rechargeable dans un boîtier vissé au châssis.

Une vue de la pile 9 Volts que nous utilisons, rechargeable en micro USB.

Moteurs

Les moteurs ici sont vissés au châssis, car juste pris en mâchoire ils ne tiennent pas et se détachent à la moindre accélération.

Ils sont directement alimentés et pilotés via la carte Arduino Motor Shield, qui permet de sélectionner leur vitesse sur une échelle de 0 à 255, dactionner les freins et de leur donner un sens de rotation, et ce très simplement dans le code.

Des roues ont été imprimées en 3D pour aller sur les embouts des moteurs, et un joint torique sert de pneu pour améliorer ladhérence du robot et éviter les démarrage en “burn”.

PCB

Au début de ce projet, nous avons utilisé une carte de prototypage électronique, aussi appelé breadboard. Dans un second temps et pour éviter toute déconnexion de câbles liée à une potentielle accélération violente, nous avons fait un PCB, soudé manuellement sur une carte de prototypage prévu à cet effet.

Une vue du dessus de notre PCB fait main.

Au niveau électronique, le PCB est routé de la manière suivante :

Le routage du PCB sur une carte de protypage de type Breadboard.

Les différents composants viennent se connecter sur le PCB au moyen de différentes broches femelles, pour que ce dernier puisse être détaché et modifié sans devoir dessouder le moindre composant.

Et du logiciel

Dun point de vue logiciel, notre projet est assez simple. En pseudo-algorithme, on peut tout simplement le résumer à “on regarde parmi les 4 photo résistances et on tourne ou avance vers celle ayant la valeur la plus sombre” dans le cas où followDark est à true. Si au contraire cette valeur est à false, alors il ira dans la direction opposée à la photorésistance ayant la plus haute valeur.

Une mesure des distances en face des trois capteurs à ultrasons permet darrêter le robot (presque) avant collision frontale, et le robot ne se déplacera pas tant que lobjet en face est toujours présent, et donc en théorie tant quil a trouvé lendroit le plus sombre.

#define echo1Pin 5
#define trig1Pin 4
#define echo2Pin 7
#define trig2Pin 6
#define echo3Pin 10
#define trig3Pin 2
#define rotMot1Pin 12
#define brakeMot1Pin 9
#define vitMot1Pin 3
#define rotMot2Pin 13
#define brakeMot2Pin 8
#define vitMot2Pin 11
#define photoRes1Pin A2
#define photoRes2Pin A3
#define photoRes3Pin A4
#define photoRes4Pin A5

#define followDark false

long duration;
int distance;

void setup() {
  Serial.begin(9600);
  pinMode(rotMot1Pin, OUTPUT);
  pinMode(brakeMot1Pin, OUTPUT);
  pinMode(vitMot1Pin, OUTPUT);

  pinMode(rotMot2Pin, OUTPUT);
  pinMode(brakeMot2Pin, OUTPUT);
  pinMode(vitMot2Pin, OUTPUT);

  pinMode(photoRes1Pin, INPUT);
  pinMode(photoRes2Pin, INPUT);
  pinMode(photoRes3Pin, INPUT);
  pinMode(photoRes4Pin, INPUT);

  pinMode(trig1Pin, OUTPUT);
  pinMode(echo1Pin, INPUT);
  pinMode(trig2Pin, OUTPUT);
  pinMode(echo2Pin, INPUT);
  pinMode(trig3Pin, OUTPUT);
  pinMode(echo3Pin, INPUT);

  delay(3000);
}

void loop(){
  byte echoPins[3] = {echo1Pin,echo2Pin,echo3Pin};
  byte trigPins[3] = {trig1Pin,trig2Pin,trig3Pin};
  long int durations[3] = {};
  long int distances[3] = {};

  for(int i = 0; i < 3; i++){
    digitalWrite(trigPins[i], LOW);
    delayMicroseconds(2);

    digitalWrite(trigPins[i], HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPins[i], LOW);
    durations[i] = pulseIn(echoPins[i], HIGH);
    distances[i] = durations[i] * 0.034 / 2;
  }

  int photoRes[4] = {};
  Serial.print("Capteur infra : 1[");
  photoRes[0] = analogRead(photoRes1Pin);
  Serial.print(photoRes[0]);
  Serial.print("] 2[");
  photoRes[1] = analogRead(photoRes2Pin);
  Serial.print(photoRes[1]);
  Serial.print("] 3[");
  photoRes[2] = analogRead(photoRes3Pin);
  Serial.print(photoRes[2]);
  Serial.print("] 4[");
  photoRes[3] = analogRead(photoRes4Pin);
  Serial.print(photoRes[3]);

  for(int i = 0; i < 3; i++){
    Serial.print("] - distance(cm) : ");
    Serial.print(distances[i]);
   }

  Serial.println();

  bool b = false;
  for(int i = 0; i < 3; i++){
    if (distances[i] < 30) {
      b= true;
    }
  }

  int photoResRef = photoRes[0];
  bool photoStop = true;
  int photoResMinPos = 0;

  if (followDark){
    int photoResMin = 1024;
    for (int i = 0; i < 4; i++){
      if (photoResMin > photoRes[i]){
        photoResMin = photoRes[i];
        photoResMinPos = i;
      }
      if (abs(photoResRef - photoRes[i]) > 20){
        photoStop = false;
      }
    }
  } else{
    int photoResMax = 0;
    for (int i = 0; i < 4; i++){
      if (photoResMax < photoRes[i]){
        photoResMax = photoRes[i];
        photoResMinPos = (i + 2)%4;
      }
      if (abs(photoResRef - photoRes[i]) > 20){
        photoStop = false;
      }
    }
  }
  Serial.println(photoResMinPos);

  if (b || photoStop){
    digitalWrite(brakeMot1Pin, HIGH);
    digitalWrite(brakeMot2Pin, HIGH);
  } else {
    digitalWrite(brakeMot1Pin, LOW);
    digitalWrite(brakeMot2Pin, LOW);
  }

  if (photoResMinPos == 0){
    digitalWrite(rotMot1Pin, LOW);
    digitalWrite(rotMot2Pin, LOW);
  }
   if (photoResMinPos == 1){
    digitalWrite(rotMot1Pin, LOW);
    digitalWrite(rotMot2Pin, LOW);
  }
   if (photoResMinPos == 2){
    digitalWrite(rotMot1Pin, HIGH);
    digitalWrite(rotMot2Pin, HIGH);
  }
   if (photoResMinPos == 3){
    digitalWrite(rotMot1Pin, HIGH);
    digitalWrite(rotMot2Pin, LOW);
  }
  analogWrite(vitMot1Pin, 150);
  analogWrite(vitMot2Pin, 150);
}

Remerciements

Merci au Fablab de lENSEIRB-MATMECA, Eirlab, pour nous avoir permis de travailler sur ce projet et davoir contribué matériellement au projet.

Merci aussi aux différents Fabmanagers qui nous ont aidés tout au long du projet en répondant à nos questions plus ou moins posées sous lemprise de la fatigue.

À la mémoire de Kaitlin Rooke.