Catégorie:RobotGEII
Sommaire
- 1 Description et présentation du Projet
- 2 Carte ultrason (Alexandre.N)
- 3 Carte gestion des moteurs (Johan)
- 4 Carte ultrason (Vincent)
- 5 Carte Codeur (Alexandre.L)
- 6 Gestion du déplacement du robot
- 7 système de fin de course (ballon) (Maxime)
Description et présentation du Projet
Présentation du championnat
Règle du jeu
Structure du robot
Mécanique
Design
Alimentation
Arrêt d'urgence
Prise jack
Dimensions
Ballon
Indicateur d'arriver
Carte ultrason (Alexandre.N)
programme de test des capteurs US :
int trig = 36;
int echo = A9;
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("Distance : ");
Serial.print(cm);
Serial.println(" cm");
delay(100);
}
programme final des capteur US :
#include <util/delay.h>
#define distUSmini 30
/* _Trigger_
37 - PC0
36 - PC1
35 - PC2
34 - PC3
33 - PC4
32 - PC5
31 - PC6
_Echo_
8 - PK0
9 - PK1
10 - PK2
11 - PK3
12 - PK4
13 - PK5
14 - PK6
*/
boolean toggle1 = 0;
volatile unsigned long t[8];
unsigned long tfin, tdebut, d;
volatile boolean recpt;
volatile boolean newmesure = false;
volatile char numCapt;
volatile uint8_t USmode;
void setup() {
Serial.begin(115200);
pinMode(37, OUTPUT);
pinMode(36, OUTPUT);
pinMode(35, OUTPUT);
pinMode(34, OUTPUT);
pinMode(33, OUTPUT);
pinMode(32, OUTPUT);
pinMode(31, OUTPUT);
cli();
TCCR2A = 0;
TCCR2B = 0;
OCR2A = 156;
TCCR2B |= (1 << WGM12);
TCCR2B |= (1 << CS11);
TCCR2B |= (1 << CS10);
TCCR2B |= (1 << CS12);
TIMSK2 |= (1 << OCIE1A);
PCICR |= 1 << PCIE2;
sei();
}
ISR(TIMER2_COMPA_vect)
{
static boolean start = true;
if (start == true)
{
if (USmode == 0) numCapt = 7;
if (USmode == 1) numCapt = 0;
if (numCapt != 7) //mode1
{
numCapt++;
if (numCapt == 2) numCapt = 0; //à retirer quand 7 capteurs
}
TCCR2B &= ~((1 << CS12) | (1 << CS10));
OCR2A = 150;
if (numCapt == 7) // mode0
{
PORTC = 0b01111111;
PCMSK2 = 0b01111111;
}
else
{
PORTC = 1 << numCapt;
PCMSK2 = 1 << numCapt;
}
}
else
{
PORTC = 0;
recpt = false;
TCCR2B |= ((1 << CS12) | (1 << CS10));
OCR2A = 30;
}
start = !start;
}
ISR(PCINT2_vect)
{
if (recpt == false)
{
tdebut = micros();
recpt = true;
}
else
{
tfin = micros();
if ((tfin - tdebut) > 50)
{
t[numCapt] = tfin - tdebut;
recpt = false;
newmesure = true;
}
}
}
void loop() {
setUSmode(0);
static unsigned long dateAffichage = 0, dateActuelle;
dateActuelle = millis();
if (newmesure == true)
{
//t = tfin - tdebut;
if ((dateActuelle - dateAffichage) > 200)
{
//if
dateAffichage = dateActuelle;
//d = t / 58;
Serial.print("Duree 0: ");
Serial.print(t[0], DEC);
Serial.println(" us.");
Serial.print("Duree 1: ");
Serial.print(t[1], DEC);
Serial.println(" us.");
Serial.print("Duree 2: ");
Serial.print(t[2], DEC);
Serial.println(" us.");
Serial.print("Duree 3: ");
Serial.print(t[3], DEC);
Serial.println(" us.");
Serial.print("Duree 4: ");
Serial.print(t[4], DEC);
Serial.println(" us.");
Serial.print("Duree 5: ");
Serial.print(t[5], DEC);
Serial.println(" us.");
Serial.print("Duree 6: ");
Serial.print(t[6], DEC);
Serial.println(" us.");
Serial.print("Duree 7: ");
Serial.print(t[7], DEC);
Serial.println(" us.");
}
newmesure = false;
}
}
void setUSmode(uint8_t mode)
{
if (mode == 0) {
USmode = 0;
//numCapt=7;
}
if (mode == 1) {
USmode = 1;
//numCapt=0;
}
}
Carte gestion des moteurs (Johan)
Carte Moteur
Carte ultrason (Vincent)
Presentation
La carte ultrason joue un rôle essentiel dans les déplacements de notre robot, elle est chargée de détecter les obstacles de manière précise et rapide afin d'informer le robot sur leur position pour qu'il puisse réagir et les éviter. Pour détecter les obstacles nous utilisons le module HC-SR04 permettant l'acquisition d'une information de distance.
- Présentation du module HC-SR04 : Le HC-SR04 est un module ultrason permettant l'évaluation d'une distance de 2cm à 4m. La mesure est réalisée "sans contact". Le module est composé d'un émetteur et d'un récepteur ultrason ainsi qu'une électronique de contrôle. Le fonctionnement de ce module s'apparente à celui d'un sonar de sous marin et sa mise en œuvre est relativement simple car il est prêt à l'emploi et possède 4 pattes: un GND, un VCC, un triger pour effectuer la mesure et un Écho pour le résultat de la mesure.
Conception de la carte ultrason
Cahier des charges
Tout d'abord, pour la conception de cette carte, nous utiliseront 7 modules ultrason afin de donner le plus d'informations possible sur les obstacles positionnés sur la trajectoire du robot. Le module HC-SR04 n’étant pas répertorié par Eagle nous devons donc commencer par créer le composant, ainsi que son empreinte qui comportera la taille réelle du composant sur Eagle.
- Alimentation du micro-contrôleur séparée de l'alimentation des capteurs ultrason
- Utilisation d'un micro-contrôleur (ATtiny88) pour gérer plus facilement les mesures des capteurs
- Condensateur de découplage pour chaque capteur ultrason afin d'éviter le bruit
- Bornier SPI pour communiquer avec les autres cartes du robot
- Angle de 30° entre les capteurs pour gérer plus facilement le déplacements du robot
Ensuite nous devons choisir un microcontrôleur afin de piloter cette carte: on choisira un AT TINY 88 car il possede 2 port (C et D) dont on se servira pour gerer les 7 triger et les 7 echo des modules ultrason. Ce microcontrôleur permet aussi une communication SPI dont on se servira pour communiquer avec les autres cartes du robot.
Le bornier utilisé pour la liaison SPI doit répondre à des normes :
Schéma, board, typon et schéma de connexion de la carte ultrason
Voici les différents schémas utiles de la carte ultrason:
On peut voir sur le schéma éléctrique que les 7 modules ultrason sont reliés sur les deux ports du micro-contrôleur.
Voici le board de la carte ultrason.
Ici les typons utiles à la réalisation de la carte.
Voici le Schéma des connexions de la carte ultrason.
Programmation de la carte ultrason
Premiers tests
Après la réalisation de la carte ultrason, nous avons effectués plusieurs tests pour vérifier son bon fonctionnement. Tout d'abord nous avons constaté une erreur: sur l'empreinte du composant HC-SR04, nous avons inversé le GND et le VCC, ce qui a par la suite causé des problèmes sur la carte. Nous avons donc corrigé ce problème, et avons effectué d'autres tests comme celui de la continuité.
Nous avons ensuite testé le fonctionnement des 7 capteurs ultrason utilisé à l'aide du programme arduino si dessous qui nous transmettait par la liaison série la distance mesurée par le capteur:
/* Pinmapping */
const byte TRIGGER_PIN = 2; // Broche TRIGGER
const byte ECHO_PIN = 3; // Broche ECHO
/* Constantes */
const long MEASURE_TIMEOUT = 25000L; // 40Hz = 25ms = ~8m à 340m/s
/* setup() */
void setup() {
/* Pour l'affichage des résultats */
Serial.begin(9600);
/* Initialisation des broches */
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
digitalWrite(TRIGGER_PIN, LOW); // DOIT être à LOW au repos
/* Message d’accueil */
Serial.println(F("~~ HC-SR04 ~~"));
}
/* loop() */
void loop() {
/* 1) Lance une mesure de distance en envoyant une impulsion HIGH de 10µs sur la broche TRIGGER */
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
/* 2) Mesure le temps entre l'envoi de l'impulsion ultrasonique et son écho (si il existe) */
long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
/* 3) Calcul la distance à partir du temps mesuré */
long mm = measure / 2 * 0.34;
/* Affiche les résultats en mm, cm et m */
Serial.print(F("Distance: "));
Serial.print(mm);
Serial.print(F("mm ("));
Serial.print(mm / 10.0, 2);
Serial.print(F("cm, "));
Serial.print(mm / 1000.0, 2);
Serial.println(F("m)"));
/* Délai d'attente pour éviter d'afficher trop de résultats à la seconde */
delay(60);
}
programme de communication SPI :
Ce programme permet d'établir la communication entre la carte ultrason (esclave) et la carte Arduino (maître).
Pour vérifier le bon fonctionnement de la communication il suffit de programmer le micro-contrôleur de la carte ultrason pour qu'il transmette une valeur sur la liaison serie.
#include <SPI.h> //master
void setup (void)
{
Serial.begin(115200);
digitalWrite(SS, HIGH);
// ensure SS stays high for now
// Put SCK, MOSI, SS pins intooutput mode
// also put SCK, MOSI into LOWstate, and SS into HIGH state.
// Then put SPI hardware into Mastermode and turn SPI on
SPI.begin ();
// Slow down the master a bit
SPI.setClockDivider(SPI_CLOCK_DIV128);
}
// end of setup
void loop (void)
{
uint8_t c,a;
// enable Slave Select
digitalWrite(SS, LOW);
// SS is pin 10
// send test string
a=SPI.transfer (10);
digitalWrite(SS, HIGH);
Serial.println(a,DEC);
// disable Slave Select
delay (100);
// 1 seconds delay
}
Carte Codeur (Alexandre.L)
Comunication SPI arduino
Principe de la communication SPI sur Arduino
Une liaison SPI (Serial Peripheral Interface) est un bus de données série synchrone, qui opère en Full-duplex. Les circuits communiquent selon un schéma maître-esclaves, où le maître s'occupe totalement de la communication. Plusieurs esclaves peuvent coexister sur un même bus, dans ce cas, la sélection du destinataire se fait par le Slave Select.
on dispose donc des pattes suivantes:
- MOSI : Master Output Slave Input, le maître parle l'esclave écoute
- MISO : Master Input Slave Output, le maître écoute, l’esclave parle
- SLK : Serial Clock, Horloge de synchronisation généré par le maître
- SS : Slave Select, utilisé si on dispose de plusieurs esclaves pour sélectionner avec lequel on communique
Echanges de données en SPI:
Maintenant que le principe de fonctionnement de la liaison SPI est éclaircit, intéressons nous aux échanges de données
on notera que les données circulent de manière circulaire; le bit 7 du master arrive sur b0 du slave, tandis que b7 du slave est envoyé sur b0 du master. il y a un décalage des bits contenus dans le registre SPDR (registre qui stock les données recues et envoyées sur la liaison SPI).
programme minimum Arduino de communication SPI:
Avec ces quelques bases, nous pouvons comprendre le programme Arduino suivant qui établit une communication quelques peu rudimentaire, mais qui illustre les fonctions Arduino utilisées pour créer une communication SPI:
la carte Arduino Uno que nous utilisons possède déjà des pattes dédiées à la communication SPI:
- MOSI : Pin 11
- MISO : Pin 12
- SCLK : Pin 13
- SS : Pin 10
- N'oublions pas de connecter les masses Arduino ensembles pour que la tension de référence soit la même
Programme maître:
// Written by Nick Gammon
// February 2011
#include <SPI.h>
void setup (void)
{
digitalWrite(SS, HIGH); // ensure SS stays high for now
// Put SCK, MOSI, SS pins into output mode
// also put SCK, MOSI into LOW state, and SS into HIGH state.
// Then put SPI hardware into Master mode and turn SPI on
SPI.begin ();
// Slow down the master a bit
SPI.setClockDivider(SPI_CLOCK_DIV8);
Serial.begin(115200);
} // end of setup
void loop (void)
{
char c,r;
// enable Slave Select
digitalWrite(SS, LOW); // SS is pin 10
// send test string
for (const char * p = "Hello, world!\n" ; c = *p; p++)
Serial.write(SPI.transfer (c));
Serial.write('\n');
// disable Slave Select
digitalWrite(SS, HIGH);
delay (1000); // 1 seconds delay
} // end of loop
Programme esclave:
// Written by Nick Gammon
// February 2011
#include <SPI.h>
char buf [100];
volatile byte pos;
volatile boolean process_it;
void setup (void)
{
Serial.begin (115200); // debugging
// turn on SPI in slave mode
SPCR |= bit (SPE);
// have to send on master in, *slave out*
pinMode(MISO, OUTPUT);
// get ready for an interrupt
pos = 0; // buffer empty
process_it = false;
// now turn on interrupts
SPI.attachInterrupt();
} // end of setup
// SPI interrupt routine
ISR (SPI_STC_vect)
{
static uint8_t i=0;
byte c = SPDR; // grab byte from SPI Data Register
// add to buffer if room
if (pos < sizeof buf)
{
buf [pos++] = c;
// SPDR=i;
// i++;
// example: newline means time to process buffer
if (c == '\n')
process_it = true;
} // end of room available
} // end of interrupt routine SPI_STC_vect
// main loop - wait for flag set in interrupt routine
void loop (void)
{
if (process_it)
{
buf [pos] = 0;
Serial.println (buf);
pos = 0;
process_it = false;
} // end of flag set
} // end of loop
Conception et réalisation de la carte codeur
Pour concevoir et réaliser la carte, nous devons respecter les contraintes suivantes:
- pas de pistes au dos de la carte : la carte sera fixée et plaquée sur le châssis (à cause de l'espace occupé par les moteurs), le contact entre le dos de la carte et le châssis va créer des court-circuits si des pistes sont au dos. De plus pour des raisons de coût et de simplicité de réalisation cela est préférable.
- la position des codeurs sera fixe : ils seront placés précisément sous les roues dentées fixées sur les axes des moteurs.
- les pistes devrons être courtes : les grandeurs circulant sur la carte sont très faibles et seront donc facilement perturbées par les champs électriques et magnétiques.
- choix et emplacement du connecteur : ces derniers n'ont pas de contraintes, le connecteur sera placé simplement de la manière la plus avantageuse pour le routage, et à la fois de manière accessible pour le connecter facilement.
Conception: Schéma électrique et Routage
choix des composants:
- nous avons choisis un connecteur droit pour ça simplicité de branchement
- les codeurs seront des Tcut 1300 du constructeur Vishay
voici le schéma électrique:
Codeur et mesure
ce schéma est plutôt simple, il est constitué d'une partie qui alimente les codeurs et d'une partie qui récupère les mesures des codeurs.
Ces mesures sont renvoyé via le connecteur vers une autre carte qui analysera ces données.
Correspondance des pattes du connecteur (vue du board):
- Patte n°1 : mesure codeur EME1 (Gauche)
- Patte n°2 : +Vcc alimentation
- Patte n°3 : mesure codeur EME2 (droite)
- Patte n°4 : mesure codeur EME2 (Gauche)
- Patte n°5 : GND masse
- Patte n°6 : mesure codeur EME1 (droite)
on notera que les pistes sont relativement proches et que le connecteur va être difficile à souder mais cela reste envisageable. Des trous de perçage sont prévus sur la carte pour la fixer et la plaquer sur le chassi
Programme test de la carte codeur
programme de test : ce programme à pour but de valider ou non le bon fonctionnement des codeurs, il permet d'afficher le nombre d'encoches passées sur chaque roue. On peut ainsi tester si les mesures effectuées par la carte sont valides, le sens des roues etc...
Gestion du déplacement du robot
équations du positionnement
Le positionnement du robot sera calculé en traitant les informations de mesures reçues sur des petits déplacements, le fait d'effectuer ces mesures sur des petits déplacements limitera l'erreur de positionnement et augmentera la précision de calcul.
Il y a deux manières d'approximer la trajectoire parcourue par le robot :
- En utilisant des segments de droites : On considère alors que le robot va en ligne droite sur toute la période de calcul. Ceci revient à supposer que les deux roues ont une vitesse constante et identique sur cet portion de trajectoire. A la fin de cet portion, on corrige l'orientation du robot en fonction de la différence de distance parcourue par les deux roues.
- En utilisant des arcs de cercles : On considère alors que le robot se déplace et change d'orientation en suivant un arc de cercle pendant le temps . Ceci revient à considérer que chacune des roues a une vitesse constante sur la période mais que les vitesses des 2 roues ne sont pas identiques.
Et avec ces équations, obtenir à la position du robot (coordonnées x,y)
programme de test : ce programme à pour but de valider le calcul des équations ci-dessus. Grâce au nombre d'encoches comptées sur chaque roue,il permet d'afficher la position en x du robot, sa position en y (voir axes ci-dessus), sa position angulaire et le nombre d'encoches comptés. On peut ainsi tester si les calculs effectuées renvoient une distance et un angle valide.
Programmes de déplacement
Suite a ces programmes nous avons commencé à essayer de nous rapprocher un peu plus d'un premier objectif: rendre le robot capable de se déplacer précisément.
Nous avons donc travaillé sur un programme qui fait réaliser au robot un déplacement en ligne droite et s’arrête au bout d' 1 mètre.
La difficulté ici a été de maintenir une trajectoire rectiligne ce qui implique une correction de trajectoire en permanence à cause de certains facteurs (les roues ne tournent pas à la même vitesse, glissement...)
programme de déplacement sur 1m : Le robot se déplace en ligne droite sur 1 mètre, sa vitesse augmente progressivement au démarrage pour éviter les glissements, elle atteint une vitesse maximum constante, puis ralentit progressivement pour s’arrêter.
système de fin de course (ballon) (Maxime)
Pages dans la catégorie « RobotGEII »
Cette catégorie comprend 4 pages, dont les 4 ci-dessous.