lespetitshackers:robots
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| lespetitshackers:robots [2014/03/29 09:21] – [le code de la séance] fjean | lespetitshackers:robots [2024/04/16 22:20] (Version actuelle) – modification externe 127.0.0.1 | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| + | ====== Objectif de l' | ||
| + | |||
| + | Construction d'un robot autonome au comportement simple : | ||
| + | * il avance tout droit au démarrage | ||
| + | * s'il détecte un obstacle devant lui il s' | ||
| + | * il fait une mesure de distance à droite, puis une à gauche | ||
| + | * il tourne et part tout droit dans la direction où il a mesuré la plus grande distance | ||
| + | * ... et on recommence... | ||
| + | |||
| + | Pour Les Petits Hackers, il s'agit d' | ||
| + | Et évidemment d' | ||
| + | ====== Public concerné ===== | ||
| + | |||
| + | Un peu tout le monde... le public de l' | ||
| + | |||
| + | Pour cette année 2013-2014, les inscriptions sont closes ; l' | ||
| + | |||
| + | Nous sommes entre 3 et 4 animateurs ; notre expérience montre qu'un tel taux d' | ||
| + | |||
| + | Nous essayons de faire en sorte que l' | ||
| + | |||
| + | ====== Matériel utilisé ====== | ||
| + | |||
| + | Une plateforme avec un chassis à deux roues motrices et une roue traînante, un Arduino Uno, shield moteur, capteur ultrason, servo-moteur, | ||
| + | |||
| + | |||
| + | ====== Lieu et horaires ====== | ||
| + | |||
| + | En 2013-2014, tous les samedis de 10h00 à 12h00, à Pen ar Créac' | ||
| + | |||
| + | |||
| + | ====== Premiers pas : un grand classique ====== | ||
| + | |||
| + | blink, bien sûr ! | ||
| + | |||
| + | On regarde un Arduino Uno, on essaie d' | ||
| + | |||
| + | On en profite pour expliquer le principe des résistances, | ||
| + | |||
| + | < | ||
| + | |||
| + | ====== Que faire avec un potentiomètre ? ====== | ||
| + | |||
| + | Explication du principe du potentiomètre : une résistance variable. Donc on a maintenant une résistance qui doit nous permettre de faire varier l' | ||
| + | |||
| + | On apprend à lire les caractéristiques, | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | Les schémas ci-dessous sont donc le **résultat** des recherches des enfants, pas un modèle qui leur serait distribué en début de séance ; c'est plutôt un guide pour les adultes</ | ||
| + | ===== * Premier circuit ===== | ||
| + | |||
| + | Explication de la manière dont on manipule une entrée analogique. Faire varier l' | ||
| + | |||
| + | |||
| + | {{ : | ||
| + | Circuit 01fadepotarserial | ||
| + | |||
| + | |||
| + | Le code Arduino correspondant : | ||
| + | | ||
| + | AnalogInLPH | ||
| + | Demonstration de la lecture d'un signal analogique sur A0 reliee a un | ||
| + | potentiometre qui fait varier l' | ||
| + | On peut lire la valeur sur un terminal serie (0 - 1023) | ||
| + | | ||
| + | Le circuit: | ||
| + | * patte centrale du potentiomètre sur A0 | ||
| + | * une patte latérale sur GND | ||
| + | * l' | ||
| + | * LED anode (long) reliée à la patte centrale du potentiomètre | ||
| + | avec une résistance en serie | ||
| + | * LED cathode (court) reliee au GND | ||
| + | | ||
| + | voir le circuit | ||
| + | | ||
| + | | ||
| + | int sensorPin = A0; // pin du potentiometre | ||
| + | int sensorValue = 0; // la variable pour stocker la valeur (0 - 1023) | ||
| + | |||
| + | void setup() { | ||
| + | | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | // lecture de la valeur a la sortie du potentiometre: | ||
| + | | ||
| + | |||
| + | // On peut faire facilement la conversion de la valeur | ||
| + | // analogique (0 - 1023) | ||
| + | // en valeur de tension de courant (0 - 5V) : | ||
| + | // | ||
| + | |||
| + | |||
| + | // impression du résultat sur le terminal serie | ||
| + | | ||
| + | | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | | ||
| + | // on attend un peu pour la suivante | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | |||
| + | ===== * Deuxième Circuit ===== | ||
| + | |||
| + | Cette fois on va réutiliser la valeur lue en sortie du potentiomètre pour faire clignoter la led avec un pas de temps variable. | ||
| + | On veut montrer aux Petits Hackers comment on peut réutiliser avec l' | ||
| + | |||
| + | <note tip> | ||
| + | |||
| + | |||
| + | |||
| + | {{ : | ||
| + | Circuit 02fadeblinkpotarserial | ||
| + | |||
| + | Le code Arduino correspondant : | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | On peut lire la valeur sur un terminal serie (0 - 1023) ou (0 - 5V) | ||
| + | |||
| + | La valeur du sensor sert aussi a faire clignoter une LED reliee au | ||
| + | pin 13 et l' | ||
| + | |||
| + | Le circuit: | ||
| + | * patte centrale du potentiomètre sur A0 | ||
| + | * une patte latérale sur GND | ||
| + | * l' | ||
| + | * LED1 anode (long) reliée à la patte centrale du potentiomètre | ||
| + | * LED1 cathode (court) relièe au GND | ||
| + | * LED2 anode sur le pin 13 | ||
| + | * LED2 cathode sur le GND | ||
| + | |||
| + | voir le circuit | ||
| + | |||
| + | |||
| + | | ||
| + | | ||
| + | int sensorPin = A0; // pin du potentiometre | ||
| + | int sensorValue = 0; // la variable pour stocker la valeur (0 - 1023) | ||
| + | int ledPin = 13; // pin de la LED à faire clignoter | ||
| + | float voltage = 0; | ||
| + | | ||
| + | void setup() { | ||
| + | Serial.begin(9600); | ||
| + | pinMode(ledPin, | ||
| + | } | ||
| + | | ||
| + | void loop() { | ||
| + | // lecture de la valeur a la sortie du potentiometre: | ||
| + | sensorValue = analogRead(sensorPin); | ||
| + | | ||
| + | // allume ledPin : | ||
| + | digitalWrite(ledPin, | ||
| + | // on attend < | ||
| + | delay(sensorValue); | ||
| + | // éteind ledPin : | ||
| + | digitalWrite(ledPin, | ||
| + | | ||
| + | // On peut faire facilement la conversion de la valeur | ||
| + | // analogique (0 - 1023) | ||
| + | // en valeur de tension de courant (0 - 5V) : | ||
| + | voltage = sensorValue * (5.0 / 1023.0); | ||
| + | | ||
| + | // impression du résultat sur le terminal serie | ||
| + | Serial.print(" | ||
| + | Serial.println(sensorValue); | ||
| + | Serial.print(" | ||
| + | Serial.print(voltage); | ||
| + | Serial.println(" | ||
| + | | ||
| + | // on attend le temps d'un clignotement pour la suivante | ||
| + | delay(sensorValue); | ||
| + | | ||
| + | } | ||
| + | |||
| + | ====== Mesurer des distances avec le son ====== | ||
| + | |||
| + | Maintenant que l'on sait comment gérer des entrées et des sorties et que l'on sait comment récupérer des valeurs sur un terminal série, on peut commencer à jouer avec un émetteur/ | ||
| + | |||
| + | On va mesurer la distance entre le pinger et un obstacle placé face à lui, et on va faire afficher cette distance sur l' | ||
| + | |||
| + | |||
| + | Le pinger émet un signal ultrason inaudible puis il en reçoit l' | ||
| + | |||
| + | Pour mesurer à quelle distance se trouve l' | ||
| + | |||
| + | Et donc la distance sera (dt/2)*29,1 | ||
| + | |||
| + | On a fait un code basé sur celui de [[http:// | ||
| + | |||
| + | /* | ||
| + | | ||
| + | pour indiquer si on est au-dessus ou au dessous | ||
| + | | ||
| + | Ne pas oublier les résistances sur les leds | ||
| + | */ | ||
| + | | ||
| + | #define trigPin 13 | ||
| + | #define echoPin 12 | ||
| + | #define led 11 | ||
| + | #define led2 10 | ||
| + | | ||
| + | void setup() { | ||
| + | Serial.begin (9600); | ||
| + | pinMode(trigPin, | ||
| + | digitalWrite(trigPin, | ||
| + | | ||
| + | pinMode(echoPin, | ||
| + | | ||
| + | pinMode(led, | ||
| + | pinMode(led2, | ||
| + | } | ||
| + | | ||
| + | void loop() { | ||
| + | long duree, distance; | ||
| + | | ||
| + | digitalWrite(trigPin, | ||
| + | delayMicroseconds(10); | ||
| + | digitalWrite(trigPin, | ||
| + | | ||
| + | duree = pulseIn(echoPin, | ||
| + | | ||
| + | /* Le son va à la vitesse de 340m/s ; il lui faut donc 29 microsecondes | ||
| + | pour parcourir 1cm. Notre ping va jusqu' | ||
| + | capteur, il parcourt donc la distance deux fois : il faut donc diviser | ||
| + | la durée par deux | ||
| + | */ | ||
| + | distance = (duree / 2) / 29.1; | ||
| + | | ||
| + | if (distance < 7) { // On va allumer ou éteindre les leds | ||
| + | digitalWrite(led, | ||
| + | digitalWrite(led2, | ||
| + | } | ||
| + | else { | ||
| + | digitalWrite(led, | ||
| + | digitalWrite(led2, | ||
| + | } | ||
| + | if (distance >= 200 || distance <= 0){ // attention aux limites du capteur | ||
| + | Serial.println(" | ||
| + | } | ||
| + | else { | ||
| + | Serial.print(distance); | ||
| + | Serial.println(" | ||
| + | } | ||
| + | delay(100); // on attend un peu | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ====== le code de la séance ====== | ||
| + | ==On met ici un peu en vrac les codes à télécharger en séance== | ||
| + | |||
| + | |||
| + | |||
| + | ==Un code de découverte des fonctions== | ||
| + | |||
| + | On part de ça et on en construit d' | ||
| + | |||
| + | |||
| + | // Construction de fonctions simples avec les moteurs et | ||
| + | // mise en mouvement en utilisant les fonctions | ||
| + | | ||
| + | int DIR2 = 4; // Direction rotation Moteur 2 | ||
| + | int SP2 = 5; // Vitesse Moteur 2 | ||
| + | | ||
| + | int SP1 = 6; // Vitesse Moteur 1 | ||
| + | int DIR1 = 7; // Direction rotation Moteur 1 | ||
| + | | ||
| + | // Les pin du HCSR04 | ||
| + | #define trigPin 11 | ||
| + | #define echoPin 12 | ||
| + | | ||
| + | // Des pin pour des leds | ||
| + | #define led 13 | ||
| + | | ||
| + | | ||
| + | void setup() { | ||
| + | | ||
| + | // Tous les pin moteur sont des sorties | ||
| + | pinMode(4, OUTPUT); | ||
| + | pinMode(5, OUTPUT); | ||
| + | pinMode(6, OUTPUT); | ||
| + | pinMode(7, OUTPUT); | ||
| + | | ||
| + | // Le pin d' | ||
| + | pinMode(trigPin, | ||
| + | digitalWrite(trigPin, | ||
| + | | ||
| + | // Le pin de reception du capteur ultrason | ||
| + | pinMode(echoPin, | ||
| + | | ||
| + | // Config des pin led | ||
| + | pinMode(led, | ||
| + | | ||
| + | } | ||
| + | | ||
| + | int vitesse = 200 ; | ||
| + | | ||
| + | // Les fonctions de mouvement | ||
| + | void AVANCE(int vitesse) { | ||
| + | digitalWrite(DIR1, | ||
| + | analogWrite(SP1, | ||
| + | | ||
| + | digitalWrite(DIR2, | ||
| + | analogWrite(SP2, | ||
| + | } | ||
| + | | ||
| + | void loop(){ | ||
| + | AVANCE(vitesse) ; | ||
| + | | ||
| + | } | ||
| + | |||
| + | |||
| + | == Des fonctions sans delay() == | ||
| + | |||
| + | On fait marcher le robot en utilisant les fonctions dans la void loop() avec le capteur ultrason et on n' | ||
| + | |||
| + | |||
| + | // Fonctionnement du robot avec fonctions | ||
| + | | ||
| + | // Constantes des moteurs | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | |||
| + | // Constantes pin du capteur US HCSR04 | ||
| + | # | ||
| + | # | ||
| + | | ||
| + | // Declaration du servomoteur | ||
| + | # | ||
| + | Servo flo; | ||
| + | int pos = 0; | ||
| + | |||
| + | // Des pin pour des leds | ||
| + | # | ||
| + | | ||
| + | //la valeur de la vitesse | ||
| + | # | ||
| + | # | ||
| + | |||
| + | // | ||
| + | const int obstacle = 7; | ||
| + | long distG = 0; | ||
| + | long distD = 0; | ||
| + | long repere = 0; | ||
| + | |||
| + | |||
| + | |||
| + | // | ||
| + | long currentMillisMove = 0; | ||
| + | long currentMillisG = 0; | ||
| + | long currentMillisD = 0; | ||
| + | long previousMillis = 0; // | ||
| + | long interval = 1000; // 1 seconde | ||
| + | | ||
| + | void setup() { | ||
| + | | ||
| + | // Tous les pin moteur sont des sorties | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | // Le pin d' | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | // Le pin de reception du capteur ultrason | ||
| + | | ||
| + | | ||
| + | // Config des pin led | ||
| + | | ||
| + | |||
| + | // Config du servo sur pin 9 | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | // Les fonctions de mouvement | ||
| + | // | ||
| + | void AVANCE(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | // fonction pour reculer | ||
| + | void RECULE(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | // fonction pour tourner sur place | ||
| + | void SUR_PLACE_G(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | // fonction pour tourner sur place | ||
| + | void SUR_PLACE_D(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | // fonction pour détecter | ||
| + | /* Le son va à la vitesse de 340m/s ; il lui faut donc 29 microsecondes | ||
| + | pour parcourir 1cm. Notre ping va jusqu' | ||
| + | capteur, il parcourt donc la distance deux fois : il faut donc diviser | ||
| + | la durée par deux. Soit 58 ms / cm. | ||
| + | | ||
| + | int DETECTE () { | ||
| + | int duree ; | ||
| + | | ||
| + | | ||
| + | | ||
| + | duree = pulseIn(echoPin, | ||
| + | | ||
| + | } | ||
| + | // fonction pour tourner la tete | ||
| + | void TETE (int p) { | ||
| + | | ||
| + | } | ||
| + | | ||
| + | void loop(){ | ||
| + | |||
| + | TETE (67); | ||
| + | //Si on voit un obstacle à moins de dist.obst cm on s' | ||
| + | repere = DETECTE(); | ||
| + | if (repere < obstacle) { | ||
| + | | ||
| + | currentMillisMove = millis(); | ||
| + | while(millis() < currentMillisMove + interval) AVANCE (0,0); | ||
| + | | ||
| + | // Puis on recule | ||
| + | currentMillisMove = millis(); | ||
| + | while(millis() < currentMillisMove + (interval/ | ||
| + | | ||
| + | // on tourne la tete a gauche | ||
| + | currentMillisG = millis(); | ||
| + | while(millis() < currentMillisG + interval) | ||
| + | TETE(180); | ||
| + | distG = DETECTE(); | ||
| + | } | ||
| + | | ||
| + | // on tourne la tete a droite | ||
| + | currentMillisD = millis(); | ||
| + | while(millis() < currentMillisD + interval) | ||
| + | TETE(0); | ||
| + | distD = DETECTE(); | ||
| + | } | ||
| + | | ||
| + | // | ||
| + | SUR_PLACE_D(100, | ||
| + | delay(500); | ||
| + | } | ||
| + | | ||
| + | AVANCE(speed1, | ||
| + | | ||
| + | } | ||
| + | |||
| + | == Et le code final == | ||
| + | |||
| + | Normalement, | ||
| + | |||
| + | // Fonctionnement du robot avec fonctions | ||
| + | | ||
| + | // Constantes des moteurs | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | |||
| + | // Constantes pin du capteur US HCSR04 | ||
| + | # | ||
| + | # | ||
| + | | ||
| + | // Declaration du servomoteur | ||
| + | # | ||
| + | Servo flo; | ||
| + | int pos = 0; | ||
| + | |||
| + | // Des pin pour des leds | ||
| + | # | ||
| + | | ||
| + | //la valeur de la vitesse | ||
| + | # | ||
| + | # | ||
| + | |||
| + | // | ||
| + | const int obstacle = 7; | ||
| + | // | ||
| + | // | ||
| + | long repere = 0; | ||
| + | int k = 0; | ||
| + | |||
| + | |||
| + | |||
| + | // | ||
| + | long currentMillisMove = 0; | ||
| + | long currentMillisG = 0; | ||
| + | long currentMillisD = 0; | ||
| + | long previousMillis = 0; | ||
| + | long currentMillisV = 0; | ||
| + | long interval = 1000; // 1 seconde | ||
| + | | ||
| + | void setup() { | ||
| + | | ||
| + | // Tous les pin moteur sont des sorties | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | // Le pin d' | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | // Le pin de reception du capteur ultrason | ||
| + | | ||
| + | | ||
| + | // Config des pin led | ||
| + | | ||
| + | |||
| + | // Config du servo sur pin 9 | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | // Les fonctions de mouvement | ||
| + | // | ||
| + | void AVANCE(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | // fonction pour reculer | ||
| + | void RECULE(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | // fonction pour tourner sur place | ||
| + | void SUR_PLACE_G(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | // fonction pour tourner sur place | ||
| + | void SUR_PLACE_D(int lavitesse1, | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | // fonction pour détecter | ||
| + | /* Le son va à la vitesse de 340m/s ; il lui faut donc 29 microsecondes | ||
| + | pour parcourir 1cm. Notre ping va jusqu' | ||
| + | capteur, il parcourt donc la distance deux fois : il faut donc diviser | ||
| + | la durée par deux. Soit 58 ms / cm. | ||
| + | | ||
| + | int DETECTE () { | ||
| + | int duree ; | ||
| + | | ||
| + | | ||
| + | | ||
| + | duree = pulseIn(echoPin, | ||
| + | | ||
| + | } | ||
| + | // fonction pour tourner la tete | ||
| + | void TETE (int p) { | ||
| + | | ||
| + | } | ||
| + | | ||
| + | void loop(){ | ||
| + | |||
| + | TETE (67); | ||
| + | //Si on voit un obstacle à moins de dist.obst cm on s' | ||
| + | repere = DETECTE(); | ||
| + | | ||
| + | if (repere < obstacle) { | ||
| + | | ||
| + | // stoppe pendant interval | ||
| + | currentMillisMove = millis(); | ||
| + | while(millis() < currentMillisMove + interval) AVANCE (0,0); | ||
| + | | ||
| + | // Puis on recule pendant interval/2 | ||
| + | currentMillisMove = millis(); | ||
| + | while(millis() < currentMillisMove + (interval/ | ||
| + | | ||
| + | // stoppe pendant interval | ||
| + | currentMillisMove = millis(); | ||
| + | while(millis() < currentMillisMove + 2*interval) AVANCE (0, | ||
| + | | ||
| + | // on tourne la tete a gauche | ||
| + | // | ||
| + | // | ||
| + | TETE(180); | ||
| + | int distG = DETECTE(); | ||
| + | delay(600); | ||
| + | // | ||
| + | //} | ||
| + | | ||
| + | // on tourne la tete a droite | ||
| + | // | ||
| + | // | ||
| + | TETE(0); | ||
| + | int distD = DETECTE(); | ||
| + | delay(600); | ||
| + | // | ||
| + | //} | ||
| + | | ||
| + | // on remet la tete droite | ||
| + | TETE(67); | ||
| + | | ||
| + | int dist = distD - distG; | ||
| + | if (dist >= 0) { | ||
| + | k=1; | ||
| + | } | ||
| + | else{ | ||
| + | k=2; | ||
| + | } | ||
| + | // | ||
| + | | ||
| + | switch (k) { | ||
| + | case 1: | ||
| + | SUR_PLACE_D(100, | ||
| + | delay(700); | ||
| + | break; | ||
| + | case 2: | ||
| + | SUR_PLACE_G(100, | ||
| + | delay(700); | ||
| + | break; | ||
| + | // | ||
| + | // if nothing else matches, do the default | ||
| + | // default is optional | ||
| + | } | ||
| + | | ||
| + | | ||
| + | // if (distD >= distG){ | ||
| + | // currentMillisV =millis(); | ||
| + | // while(millis() > currentMillisV + interval/3) { | ||
| + | // SUR_PLACE_D(100, | ||
| + | // } | ||
| + | // } | ||
| + | // else { | ||
| + | // currentMillisV =millis(); | ||
| + | // while(millis() > currentMillisV + interval/3) { | ||
| + | // SUR_PLACE_G(100, | ||
| + | // } | ||
| + | // } | ||
| + | | ||
| + | } | ||
| + | | ||
| + | AVANCE(100, 100); | ||
| + | | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
