Difference between revisions of "Projets:Perso:2013:Module de localisation"

From Electrolab
Jump to: navigation, search
(Configuration des ports d'entrées / sorties)
(Paramétrage du timer)
Line 140: Line 140:
 
:: T1CON=0x0020;    
 
:: T1CON=0x0020;    
 
::: /* configuration du registre de controle :
 
::: /* configuration du registre de controle :
Le bit de poids fort <Bit_15> commande le démarrage du timer,
+
::: Le bit de poids fort <Bit_15> commande le démarrage du timer,
 
Les bits <5-4> permettent de ralentir la vitesse du timer, en divisant la fréquence de mise à jour du timer par une valeur spécifique (ce que l’on appelle un prescaler. Ainsi, au lieu d’être incrémenté à chaque coup d’horloge (Fcy), le compteur du timer est incrémenté tous les 8, 64 ou 256 coups :
 
Les bits <5-4> permettent de ralentir la vitesse du timer, en divisant la fréquence de mise à jour du timer par une valeur spécifique (ce que l’on appelle un prescaler. Ainsi, au lieu d’être incrémenté à chaque coup d’horloge (Fcy), le compteur du timer est incrémenté tous les 8, 64 ou 256 coups :
::: * <5-4> = 0 ; // A chaque coup d’horloge
+
:::* <5-4> = 0 ; // A chaque coup d’horloge
::: * <5-4> = 1 ; // tous les 8 coups
+
:::* <5-4> = 1 ; // tous les 8 coups
::: * <5-4> = 2 ; // tous les 64 coups
+
:::* <5-4> = 2 ; // tous les 64 coups
::: * <5-4> = 3 ; // tous les 256 coups */
+
:::* <5-4> = 3 ; // tous les 256 coups */
 
:: PR1= <<valeur>>;
 
:: PR1= <<valeur>>;
 
::: // Lorsque le compteur du timer atteint cette valeur, une interruption est générée et le timer remis à 0
 
::: // Lorsque le compteur du timer atteint cette valeur, une interruption est générée et le timer remis à 0
 
:: T1CONbits.TON=1;  // démarrage du timer
 
:: T1CONbits.TON=1;  // démarrage du timer
 
:}
 
:}

Revision as of 22:47, 10 March 2014

Système de balisage infrarouge

Cette page présente mes travaux actuels sur la fabrication d'un système de balisage infrarouge pour mobile.
Le système contient les fonctions suivantes :

  • Emission infrarouge de 4 balises autonomes,
  • Réception infrarouge sur une tourelle,
  • Contrôle d'un moteur pas à pas d'entrainement de la tourelle.

En plus de la fonction de triangulation associée au balisage, le système intègre en permanence deux entrées codeuses, assurant ainsi l'odométrie du mobile. Les données d'odométrie sont ensuite intégrées aux données de balisage en permanence par l'intermédiaire d'un filtre de Kalman.

Un troisième volet de ce projet est le calcul en permanence d'une "void area", basée sur un réseau de capteurs ultrason déployés sur le mobile.

Dans un second temps, un autre projet viendra compléter celui-ci avec la réalisation d'un système de contrôle commande des moteurs (en DC, stepper DC puis en BLDC) avec un calcul de trajectoire basé sur les splines de Catmull-Rom.


Localisation par balisage infrarouge

Le principe de balisage infrarouge consiste à utiliser des balises émettant un signal infrarouge que va détecter un plot central, déployé sur une structure mobile roulante par exemple. Le concept est développé dans le cadre de la coupe de France de robotique, et permet de disposer facilement d’une information de localisation sur la table de 3x2m. >>Table + balisage<<

Le but est d’obtenir la meilleur estimation de x et y afin d’avoir la position du robot sur la table, ainsi que son orientation. Le principe appliqué est celui de la triangulation, basée sur une mesure d’angle (il existe le même principe avec les distances, tout n’étant au final qu’une application des équations de trigonométrie). Le choix du balisage infrarouge est lié au faible coût de la mise en œuvre (une centaine d’euros tout compris) et à la relativement grande précision du système. Il sera couplé, dans la suite de ce document, à un dispositif d’odométrie et un dispositif de sonars permettant d’affiner la position courante du robot et de créer une « void area » autour du robot indiquant les zones accessibles ou non au robot. >>Table + odométrie<<


Microcontrôleur DsPIC

Cette section est dédiée à l'utilisation des microcontrôleurs DsPic de chez Microchip. Ces chips sont majoritairement utilisés dans le système présenté ici. Il est donc nécessaire de poser un certain nombre de bases sur leur utilisation, en particulier leur mise en oeuvre et les drivers disponibles.

Configuration générale

Les DsPic sont de petits microcontrôleurs 16 bits très puissants que l'on peut utiliser pour tout ou presque :

  • Contrôle de moteur par PWM,
  • Conversion analogique numérique 16 bits (ADC),
  • Acquisition de signaux numériques (Input Capture)
  • Communication CAN (natif), i2c (natif), UART (natif), SPI (natif), etc.
  • Une foultitude de timers,
  • etc.

Il existe plusieurs familles de DsPIC : 30F, 32, 33F, 33E. Seuls les 33F sont détaillés ici.
Dans une même famille, tous les microcontrôleurs utilisent les drivers de la même façon, avec le même code, sous réserve qu'ils disposent du driver. En effet, dans la famille des 33F il va exister pléthore de chips différents, la différence se situant au niveau du nombre de drivers, d'E/S, de timers, de place mémoire, etc.
Dans la suite, les explications seront apportées sur un DsPIC33FJ128MC802 ou un DsPIC33FJ64GP802, dont la principale différence est un PWM pour le premier. La programmation peut se faire en C ou en assembleur. Les exemples proposés sont en C, je reviendrais par la suite sur la manière de les programmer.

Schéma de câblage

Tous les microcontrôleurs de la famille des DsPIC33FJ sont câblés pareils : >> Schéma de câblage chip <<

Le connecteur J1 est utilisé pour la programmation du DsPic, en utilisant un ICD2 ou un Pickit 3.

  1.  !MCLR
  2. +Vcc
  3. GND
  4. PGEC1
  5. PGED1

Les ports suivants sont nécessairement câblés pour pouvoir utiliser le chip, conformément à la figure précédente :

  • !MCLR : La patte sert à la fois à la programmation et à la mise en marche du Chip : !MCLR = 0/NC - Chip inactif, !MCLR = VDD : Chip actif.
  • PGEDi/PGECi : broches de programmation, elles peuvent aussi avoir d'autres application lors de l'usage du chip. Il y a plusieurs mappages des PGEC/D possibles, j'utilise ici le premier.
  • VSS/AVSS : ground, 0 logique. La broche "A-" est normalement la branche utilisée pour faire passer de la puissance dans le chip, mais en règle général il vaut mieux tout avoir sur la même source et utiliser ensuite des composant fait pour pour les aspects puissance.
  • OSC1 / OSC2 : entrées du quartz. Voir le chapitre horloge pour le détail d'utilisation.
  • VDD/AVDD : 3,3V (+/- 10%)
  • VCAP : Cette entrée doit être reliée à la masse par un condo de 10µF, l'idéal étant un tantale polarisé (CMS ou non d'ailleurs). Sans ce condo, le chip ne marchera pas et ne pourra même pas être programmé.

Horloge

Les DsPIC peuvent être cadencés assez haut, mais ils utilisent pour cela une PLL interne (Phase Lock Loop). Le principe de la PLL est détaillé sur internet, nous ne verrons ici que l'application. Trois types d'horloges sont utilisées :

  • Quartz,
  • Oscillateur,
  • Horloge interne.

De manière générale, il est déconseillé d'utiliser des horloges trop rapides. En effet, les signaux "carrés" sont plus mauvais à ces fréquences. Une bonne pratique est de dédier un quartz de fréquence raisonnable (8 ou 10 MHz) à chaque chip, et d'en augmenter la fréquence par une PLL.

Utilisation d'un quartz

Les quartz sont des cristaux passifs que le microcontrôleur utilise pour générer une horloge. Le quartz est relié aux broches OSC1 et OSC2 du microcontrôleur. Les quartz utilisables sont de deux types, en fonction de leur vitesse d'horloge :

  • XT : quartz jusqu'à 10 MHz,
  • HS : quartz de 10 MHz à 40 MHz.

Chaque broche OSC1 et OSC2 est également relié à la masse (GND), par l'intermédiaire d'un condo de 15 µF. A noter que ça marche aussi sans le condo, mais ils sont recommandés dans la doc du chip.
Dans : MPLAB : Configure\configuration bits...

  • Oscillator mode : Primary oscillator (XT, HS, EC) w/ PLL
  • Internal External switch over mode : Start up device with FRC, then automatically switch to bla bla bla...
  • Primary oscillator source : HS Oscillator mode (pour cause de quartz utilisé à 10 MHz)

Nota : les quartz étant passifs, ils sont dédiés à un seul chip et unique chip, on ne peut pas utiliser un quartz pour plusieurs chips.

Utilisation d'un oscillateur

ADU

Utilisation de l'horloge interne

ADU

Configuration de l'horloge

Ci-dessous un bout de code permettant de paramétrer la PLL au démarrage du chip :

void oscConfig(void){
PLLFBD=30; // M=32
CLKDIVbits.PLLPOST=0; // N1=2
CLKDIVbits.PLLPRE=0; // N2=2
OSCTUN=0; // Tune FRC oscillator, if FRC is used
RCONbits.SWDTEN=0; // Disable Watch Dog Timer
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to Primary Oscillator with PLL (NOSC=0b011)
__builtin_write_OSCCONL(0x01); // Start clock switching
while (OSCCONbits.COSC != 0b011); // Wait for Clock switch to occur
while(OSCCONbits.LOCK!=1) {}; // Wait for PLL to lock
}

Ce code est prévu pour un quartz de 10 MHz, permettant de passer la fréquence de cycle du microcontrôleur à 40 MHz (une opération toutes les 1 / [40.E6], soit 25 ns).

Configuration des ports d'entrées / sorties

La configuration des ports d’E/S est réalisée de base par les trois registres suivants :

  • AD1PCFGL' : Ports analogiques, à positionner à [0xffff] pour les désactiver,
  • _TRISBx / _TRISAx : Direction de la broche RBx / RAx :
    • 1 : broche en entrée,
    • 0 : broche en sortie.
  • _RBx / _RAx : Etat de la broche :
    • 1 : broche à VDD (+3,3V),
    • 0 : broche à VSS (GND).

Nota : Lorsque l’on passe plusieurs broches à l’état logique 1 l’une à la suite de l’autre, notamment avec des très hautes fréquences, il est possible que le condensateur qui sert à modifier l’état de la broche ne puisse pas suivre et alimenter toutes les broches. Dans ce cas, il faut séparer les opérations de changement d’état de plusieurs cycles (au moins deux ou trois) pour permettre au condo de recharger.

En plus des manipulations standards, il existe deux autres opérations associées à l’utilisation des drivers : redirection des ports d’entrée ou de sortie : _RPxR (output) et RPINRx (input).

  • _RPxR : les _RPxR sont des registres associés à **ADU**
  • RPINRx : la plupart des drivers ont leurs entrées redirigeables vers l’une ou l’autre des broches RPx du chip. Pour chaque driver, il faut trouver le bon RPINRx et indiquer dans ce registre le numéro de la broche à laquelle associer l’entrée.

Pour chaque driver, les redirections de port seront précisées au cas par cas.

Les timers

Les timers sont probablement les fonctions les plus utiles d’un microcontrôleur. Ils permettent de réaliser des opérations avec une fréquence particulière, avec des actions spécifiques à chaque révolution du timer. Le principe est qu’un registre va être incrémenté régulièrement, proportionnellement à la fréquence Fcy, jusqu’à une certaine valeur. Lorsque cette valeur est atteinte, une interruption est déclenchée qui permet de réaliser l’action voulue à la révolution du timer.
Les DsPIC disposent de plus ou moins de timer selon les séries, celui utilisé ici dispose de 5 timers.
Certains timers sont utilisés par des fonctions (comme les timers 2 et 3 avec l’Input Capture, définit plus loin), ou peuvent être combinés pour former des timers 32 bits (de révolution très largement supérieure). Les applications présentées ici utiliseront plusieurs de ces fonctions, mais sans être exhaustif.

Principe

Les timers fonctionnent selon le principe ci-dessous : <<Schéma Timer à ajouter>>

Paramétrage du timer

Le code ci-dessous permet de paramétrer un timer pour avoir une interruption cadencée à la fréquence voulue :

void init_timer1(void)
{
_T1IE=0; // interruption timer
_T1IF=0; // flag d’interruption remis à zéro
T1CON=0x0020;
/* configuration du registre de controle :
Le bit de poids fort <Bit_15> commande le démarrage du timer,

Les bits <5-4> permettent de ralentir la vitesse du timer, en divisant la fréquence de mise à jour du timer par une valeur spécifique (ce que l’on appelle un prescaler. Ainsi, au lieu d’être incrémenté à chaque coup d’horloge (Fcy), le compteur du timer est incrémenté tous les 8, 64 ou 256 coups :

  • <5-4> = 0 ; // A chaque coup d’horloge
  • <5-4> = 1 ; // tous les 8 coups
  • <5-4> = 2 ; // tous les 64 coups
  • <5-4> = 3 ; // tous les 256 coups */
PR1= <<valeur>>;
// Lorsque le compteur du timer atteint cette valeur, une interruption est générée et le timer remis à 0
T1CONbits.TON=1; // démarrage du timer
}