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 10:53] – [Un code de découverte des fonctions] 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); | ||
+ | | ||
+ | } | ||
+ | |||
+ | |||
+ | |||