Robot : Hector : Différence entre versions
(→{{Rouge|Carte d'extension}}) |
(→{{vert|Routage de la carte d'extension}}) |
||
Ligne 378 : | Ligne 378 : | ||
= {{Rouge|Carte d'extension}} = | = {{Rouge|Carte d'extension}} = | ||
Pour faciliter la connexion entre les différents capteur et la carte Arduino on a crée une carte d’extension qu'on vas connecter entre la carte Arduino et Ardumoto. Sur cette carte il existe 3 bornier de 4 pour les capteurs ultrasons et un bornier de 3 pour la carte de détection d'arrivée. | Pour faciliter la connexion entre les différents capteur et la carte Arduino on a crée une carte d’extension qu'on vas connecter entre la carte Arduino et Ardumoto. Sur cette carte il existe 3 bornier de 4 pour les capteurs ultrasons et un bornier de 3 pour la carte de détection d'arrivée. | ||
− | |||
− |
Version du 15 juin 2015 à 17:45
Sommaire
Cahier des charges
Présentation du projet
Détection d'obstacle
Capteur à ultrason : HC-SR04
Description du composant
Ce capteur est composé de 4 pins : - VCC, 5V supply, - Trigger, Trigger pulse input, - Echo, Echo pulse output, - GND, 0V ground.
Ce module permet d’évaluer les distances entre un objet mobile et les obstacles rencontrés. Il suffit d'envoyer une impulsion de 10 µs en entrée et le capteur renvoie une largeur d'impulsion proportionnelle à la distance. Alimentation: 5 Vcc Consommation: 15 mA Fréquence: 40 kHz Portée: de 2 cm à 4 m Déclenchement: impulsion TTL positive de 10µs Signal écho: impulsion positive TTL proportionnelle à la distance. Calcul: distance (cm) = impulsion (µs) / 58 Dimensions: 45 x 21 x 18 mm
Un premier programme
int trig = 10;
int echo = 9;
long lecture_echo;
long cm;
void setup()
{
pinMode(trig, OUTPUT);
digitalWrite(trig, LOW);
pinMode(echo, INPUT);
Serial.begin(9600);
}
void loop()
{
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
lecture_echo = pulseIn(echo, HIGH);
cm = lecture_echo / 58;
Serial.print("Distancem : ");
Serial.println(cm);
delay(1000);
}
Cependant, afin d'optimiser notre robot, il va falloir qu'il puisse rouler tout en émettant de ondes. Nous allons donc utiliser le TIMER1 et ses interruptions.
TIMER1
Voici le programme afin d'utiliser le TIMER1
//this code will enable all three arduino timer interrupts.
//timer0 will interrupt at 2kHz
//timer1 will interrupt at 1Hz
//timer2 will interrupt at 8kHz
#include <util/delay.h>
//storage variables
boolean toggle1 = 0;
volatile unsigned long t;
unsigned long tfin, tdebut, d;
volatile boolean recpt;
volatile boolean newmesure = false;
void setup() {
Serial.begin(57600);
//set pins as outputs
pinMode(10, OUTPUT);
cli();//stop interrupts
//set timer1 interrupt at 10^5Hz
TCCR1A = 0 ;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
// TCNT1 = 0;//initialize counter value to 0
// set compare match register for 1hz increments
OCR1A = 20000;// = (16*10^6) / ((40546*8) - 1) (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS11 bit for 8 prescaler
TCCR1B |= (1 << CS11);
TCCR1B |= (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
//configuration interruption
EICRA |= (1 << ISC00);
EIMSK |= (1 << INT0);
sei();//allow interrupts
}//end setup
ISR(TIMER1_COMPA_vect)
{
PORTB |= (1 << PB4);
_delay_us(60);
PORTB &= ~(1 << PB4);
}
ISR(INT0_vect)
{
if (recpt == false)
{
tdebut = micros();
recpt = true;
}
else
{
tfin = micros();
t = tfin - tdebut;
recpt = false;
newmesure = true;
}
}
void loop() {
//do other things here
if (newmesure == true)
{
d = t / 58;
Serial.print("Duree : ");
Serial.print(t, DEC);
Serial.println(" us.");
Serial.print("Distance : ");
Serial.print(d, DEC);
Serial.println(" cm.");
Serial.println("_");
delay(1000);
newmesure = false;
}
}
On a alors un capteur qui répond bien et prêt à être tester sur notre robot, cependant le TIMER1 a un influence sur la patte 11 de l'arduino (en PWM), utilisé par l'un de moteurs, la rendant inutilisable. On utilisera donc le TIMER2 qui ne posera aucun problème.
TIMER2
Il suffira de modifier quelques parties du TIMER1, on obtient alors ceci :
#include <util/delay.h>
boolean toggle1 = 0;
volatile unsigned long t;
unsigned long tfin, tdebut, d;
volatile boolean recpt;
volatile boolean newmesure = false;
void setup() {
Serial.begin(115200);
//set pins as outputs
pinMode(10, OUTPUT);
cli();//stop interrupts
TCCR2A = 0;
TCCR2B = 0;
OCR2A = 156;
// turn on CTC mode
TCCR2B |= (1 << WGM12);
TCCR2B |= (1 << CS11);
TCCR2B |= (1 << CS10);
TCCR2B |= (1 << CS12);
TIMSK2 |= (1 << OCIE1A);
//configuration interruption
EICRA |= (1 << ISC00);
EIMSK |= (1 << INT0));
sei();//allow interrupts
}//end setup
ISR(TIMER2_COMPA_vect)
{
static boolean start = true;
if (start == true)
{
PORTB |= 1 << PB4;
TCCR2B &= ~((1 << CS12) | (1 << CS10));
OCR2A = 150;
}
else
{
PORTB &= ~(1 << PB4);
recpt = false;
TCCR2B |= ((1 << CS12) | (1 << CS10));
OCR2A = 30;
}
start = !start;
}
ISR(INT0_vect)
{
if (recpt == false)
{
tdebut = micros();
recpt = true;
}
else
{
tfin = micros();
t = tfin - tdebut;
recpt = false;
newmesure = true;
}
}
void loop() {
//do other things here
static unsigned long dateAffichage = 0, dateActuelle;
dateActuelle = millis();
if (newmesure == true)
{
t = tfin - tdebut;
d = t / 58;
if ((dateActuelle - dateAffichage) > 200)
{
dateAffichage = dateActuelle;
Serial.print("Duree : ");
Serial.print(t, DEC);
Serial.println(" us.");
Serial.print("Distance : ");
Serial.print(d, DEC);
Serial.println(" cm.");
Serial.println(' ');
}
newmesure = false;
}
}
Des améliorations ont été effectuées afin d'obtenir un robot plus réactif lors de la rencontre d'un obstacle.
Test
Lorsqu'on implémente notre TIMER au programme commandant les roues, notre robot s'arrête comme prévu lorsqu'il détecte un obstacle.
void loop() du programme testé
void loop()
{
Capteur();
if (d < 30)
{
stopBoth();
}
else
{
driveArdumoto(MOTOR_A,CCW,100);
driveArdumoto(MOTOR_B,CW,100);
}
}
Nous sommes alors prêt pour commencer la pré-définition du mouvement afin de contourner un obstacle lors de sa détection.
Pré-définition du mouvement
Premier approche
Nous allons premièrement faire tourner le robot lorsqu'il rencontre un obstacle :
void loop()
{
Capteur();
if (d < 40)
{
driveArdumoto(MOTOR_A,CW,100);
driveArdumoto(MOTOR_B,CW,100);
}
else
{
driveArdumoto(MOTOR_A,CCW,100);
driveArdumoto(MOTOR_B,CW,100);
}
}
Cependant, le résultat obtenu n'est pas celui espéré : lorsque le robot détecte l'obstacle, il tourne à droite, mais une fois qu'il n'y a plus d'obstacle devant lui, il avance.
Lorsqu'on place notre robot dans la pièce utilisée pour NAO, il tourne lorsqu'il s'approche trop près d'un mur, ce programme est alors nommé "ProgRobAspi" pour programme robot aspirateur. Il n'est pas possible de définir un mouvement avec un simple test de distance.
Second approche
Après réflexion, il fallait que le robot puisse déterminer des points particuliers, c'est à dire lorsqu'il ne détectait rien puis qu'un obstacle apparaissait, et lorsqu'il détectait un obstacle puis qu'il ne détectait plus rien : on utilisera alors le principe de l'état présent et passé.
On a alors le programme suivant :
void setup()
{
d=500000;
delay(2000);
setupArdumoto(); // Set all pins as outputs
setupCapteur();
}
void loop()
{
Capteur();
Etat1 = Etat2;
if (d < 15) Etat2 = 1;
else Etat2 = 0;
if (Etat1 == 0 && Etat2 == 0)
{
driveArdumoto(MOTOR_A, CCW, 70);
driveArdumoto(MOTOR_B, CW, 70);
}
if (Etat1 == 1 && Etat2 == 1)
{
droite();
courbedroite();
droite2();
}
}
void courbedroite()
{
driveArdumoto(MOTOR_A, CCW, 140);
driveArdumoto(MOTOR_B, CW, 110);
delay(1900);
}
void droite2()
{
driveArdumoto(MOTOR_A, CW, 100);
driveArdumoto(MOTOR_B, CW, 100);
delay(250); //delay différent en raison de la modification de vitesse soudaine
}
void droite()
{
driveArdumoto(MOTOR_A, CW, 100); // tourner droite 45°
driveArdumoto(MOTOR_B, CW, 100);
delay(400);
}
On a alors un robot capable d'éviter un obstacle qu'il rencontre. Cependant, ce programme ne marche pas dans toutes les conditions possibles : il ne marchera que si les obstacles sont alignés et selon les frottements des roues par rapport au sol (le bois marche très bien), il ne détectera pas d'autres obstacles lorsqu'il sera dans sa phase d'esquive et il perdra alors son objectif.
Solutions à apporter
Afin d'obtenir le robot espéré pour la compétition, il faudra qu'il puisse détecter un obstacle pendant son mouvement prédéfini. Pour cela, ajouter un "if" est envisageable, ainsi qu'un autre état (Etat3). De plus, utiliser un seul capteur est suffisant, mais pas assez précis, il est dont envisageable d'ajouter un ou deux capteurs à ultrason supplémentaires pour améliorer cette précision.
Carte d'extension
Pour faciliter la connexion entre les différents capteur et la carte Arduino on a crée une carte d’extension qu'on vas connecter entre la carte Arduino et Ardumoto. Sur cette carte il existe 3 bornier de 4 pour les capteurs ultrasons et un bornier de 3 pour la carte de détection d'arrivée.