





Le module Devantech CMPS03 est une boussole digitale. Il sait communiquer par signal PWM ou par le protocole i2c. C’est ce dernier qui va nous intéresser avec le Raspberry Pi.
Ce module s’alimente en 5v, et consomme 15 mA pour les révisions antérieures à la 14 (reconnaissables à la présence d’un quartz gris au milieu du circuit), ou 25 mA pour les versions plus récentes (qui à la place du quartz ont trois pastilles non-utilisées).
Il est basé sur deux détecteurs de champs magnétique [Philips KMZ51], montés à 90°. Il atteint une précision théorique de 0,1°. En pratique on considérera une précision de 3 à 4 °. Il faudra aussi prendre en compte le fait que ce type de capteur est très sensible à l’environnement extérieur, et perd beaucoup en précision lorsqu’il prend de l’inclinaison.
Le Raspberry Pi supporte matériellement le protocole I2C, mais il n’est pas actif par défaut. Nous allons donc voir comment l’activer.
Activation du bus i2c
Le fichier »/etc/modprobe.d/raspi-blacklist.conf » contient la liste des modules du noyau à ne jamais charger. Mettre en commentaire l’instruction »blacklist i2c-bcm2708 » en plaçant un dièse (#) en début de ligne.
Avant :
1 2 3 4 |
# blacklist spi and i2c by default (many users don't need them) blacklist spi-bcm2708 blacklist i2c-bcm2708 |
Après :
1 2 3 4 |
# blacklist spi and i2c by default (many users don't need them) blacklist spi-bcm2708 #blacklist i2c-bcm2708 |
Le fichier »/etc/modules » contient la liste des modules du noyau à charger. Nous allons y ajouter le module »i2c-dev ».
Avant :
1 2 3 4 5 6 7 8 |
# /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. # Parameters can be specified after the module name. snd-bcm2835 spi-bcm2708 |
Après :
1 2 3 4 5 6 7 8 9 |
# /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. # Parameters can be specified after the module name. snd-bcm2835 spi-bcm2708 i2c-dev |
Installer le package i2c-tools. Il contient les commandes »i2cdetect », »i2cdump », »i2cget », et »i2cset », qui permettent le dialogue en i2c par la ligne de commande.
1 |
$ sudo apt-get install i2c-tools |
Ajouter votre utilisateur au groupe i2c afin qu’il puisse accéder au bus i2c. Sans cette étape, vous devrez lancer toute commande qui communique avec le bus i2c en tant que »root », ou via »sudo ».
1 |
$ sudo adduser pi i2c |
Redémarrer le RaspberryPi afin de charger les modules du noyau appropriés, et de prendre en compte votre nouveau groupe.
1 |
$ sudo reboot |
On peut ensuite tester l’activation du module i2c grâce à »i2cdetect ».
Si le module i2c du noyau est bien chargé, lorsqu’aucun périphérique i2c n’est connecté, on doit obtenir quelque chose comme cela :
1 2 3 4 5 6 7 8 9 10 |
$ i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- |
Le module CMPS03
Nous allons connecter le CMPS03 au connecteur P1 du Raspberry Pi (les broches indiquées sont celles d’un révision 2) :
- La broche 1 du CMPS03 (+5v) à la broche 2 du RPi
- La broche 2 du CMPS03 (SCL) à la broche 5 du RPi
- La broche 3 du CMPS03 (SDA) à la broche 3 du RPi
- La broche 9 du CMPS03 (GND) à la broche 9 du RPi
Dans la mesure où le calibrage peut se faire de manière logicielle, nous n’allons pas utiliser de broche dédiée.
Aucun composant externe n’est nécessaire, les résistances de pull-up requises sur le bus i2c sont déjà intégrées au Raspberry Pi.
Note: Sur la photo ci-contre, le nord est situé à gauche.
Une fois la boussole connectée, en relançant »i2cdetect », on doit obtenir quelque chose de semblable à ceci (essayer »-y 0 » sur un RPi revision 1 et »-y 1 » sur un RPi revision 2) :
1 2 3 4 5 6 7 8 9 10 |
$ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- |
Le module est donc à l’adresse 0x60 du port i2c 1 (sur un RaspberryPi révision 2).
On peut tester le branchement grâce aux outils i2c :
1 |
$ watch -n 1 i2cget -y 1 0x60 1 |
Doit afficher toutes les secondes la valeur héxadécimale sur 8 bit du cap observé. On peut le voir évoluer en pivotant lentement le module. Pour quitter, presser CTRL+C.
Fonctionnement logiciel
Le CMPS03 expose 16 registres de 8 bits. Lorsqu’une valeur sur 16 bits est disponible, elle prend deux registres, bit de poids fort en tête.
Reg. | Révision <14 | Révision >= 14 |
0 | Révision du firmware. | Idem. |
1 | Cap sur 8 bits non signés. Retourne une valeur de 0 pour 0° à 255 pour un peu moins de 360°. | Idem. |
2, 3 | Cap sur 16 bits non signés. Retourne une valeur de 0 pour 0° à 3599 pour 359,9°. | Idem. |
4, 5 | Signal de différence 1 sur 16 bits signés. | Idem. |
6, 7 | Signal de différence 2 sur 16 bits signés. | Idem. |
8, 9 | Signal de calibration 1 sur 16 bits signés. | Signal brut 1 sur 16 bits signés. |
10, 11 | Signal de calibration 2 sur 16 bits signés. | Signal brut 2 sur 16 bits signés. |
12 | Inutilisé, retourne zéro. | Code de déblocage 1. |
13 | Inutilisé, retourne zéro. | Code de déblocage 2. |
14 | Inutilisé, retour indéfini. | Code de déblocage 3. |
15 | Commande de calibrage. | Registre de commandes. |
Connaître la version du firmware peut vous permettre de prendre en compte différentes versions du module, et adapter le comportement du logiciel à chaque module. Pour ma part, ne disposant que d’un seul exemplaire en révision 9, je ne vais m’en servir que pour valider ou non la communication.
Je n’utiliserais pas non plus les registres 4 à 11. Ils exposent des valeurs internes permettant de calculer le cap exposé aux registres 1, 2 et 3.
Je ne serais pas en mesure de jouer avec les codes de déblocage des registres 12, 13 et 14 puisque mon modèle (en révision 9) ne les prend pas en compte.
Même chose pour le registre de commandes (le 15), que j’utiliserais simplement pour calibrer la boussole.
Mise en pratique 1: Script Bash
La première mise en pratique consistera à créer un script Bash qui utilisera i2cget afin :
- De pouvoir lire le numéro de révision du CMPS03
- De pouvoir lire le cap sur 8 bits (de 0 à 255)
- De pouvoir lire le cap sur 16 bits (de 0 à 360)
Voici l’utilisation de ce script :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Devantech CMPS03 compass module utility for Raspberry Pi. Usage: cmps03 [options] Options: -h|--help : Displays this help and exits. -b|--bus=int : Raspberry Pi i2c bus integer number [0|1]. Mandatory for the next options. -a|--address=hex : CMPS03 i2c hexadecimal address. Mandatory for the next options. -r|--revision : Displays the CMPS03 revision number and exits. -p|--precision=int : Bearing precision [8|16] bits. Defaults to 16 bits. |
Voici maintenant le code source :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#!/bin/bash # Displays usage information and exits. _help() { cat</dev/null` if [ $? == 0 ]; then printf "Devantech CMPS03 rev %d at address %s on bus %d.n" "$REVISION" "$I2C_ADR" "$I2C_BUS" exit 0 else printf "Error: unable to find Devantech CMPS03 at address %s on bus %d.n" "$I2C_ADR" "$I2C_BUS" exit 1 fi } # Checks, reads, and affects command line parameters. _readCommandLine() { opt=`getopt --options hb:a:rp: --longoptions help,bus:,address:,revision,precision: -n '$0' -- "$@"` eval set -- "$opt" while true ; do case "$1" in -h|--help) _help ; shift ;; -b|--bus) I2C_BUS="$2" ; shift 2 ;; -a|--address) I2C_ADR="$2" ; shift 2 ;; -r|--revision) _revision ; shift ;; -p|--precision) PRECISION="$2" ; shift 2 ;; --) shift ; break ;; *) echo "Invalid option: $opt." ; exit 1 ;; esac done } _init _readCommandLine "$@" _check # In 8 bits precision, result will be a value between 0 and 255. if [[ "$PRECISION" == '8' ]]; then bearing=`i2cget -y $I2C_BUS $I2C_ADR 1 b` # In 16 bits precision, result will be a value between 0 and 360. else data1=`i2cget -y $I2C_BUS $I2C_ADR 2 b` data2=`i2cget -y $I2C_BUS $I2C_ADR 3 b` bearing=$(( (255 * data1 + data2) / 10 )) fi printf "%dn" $bearing |
Pour plus de simplicité, je vous conseille d’activer le bit d’exécution de ce script avec la commande :
1 |
$ chmod +x cmps03 |
Vous pouvez aussi le placer ou placer un lien symbolique dans votre path; ou bien ajouter l’emplacement du script à la fin de votre path.
Exemple d’utilisation : Lecture du numéro de révision.
1 2 |
$ ./cmps03 --bus 1 --address 0x60 --revision Devantech CMPS03 rev 9 at address 0x60 on bus 1. |
Exemple d’utilisation : Lecture du cap sur 16 bits.
1 2 |
$ ./cmps03 --bus 1 --address 0x60 --precision 16 21 |
Une prochaine version mise à jour intégrera aussi le calibrage par logiciel du module CMPS03. Mais cette fonctionnalité attendra que le module soit monté sur un châssis avec le reste de ce qui constituera un robot.
Note: Cet article n’est pas terminé, merci de visiter cette page à nouveau dans quelque temps.
Références
- Documentation à priori officielle en anglais du module CMPS03, révisions 13 et antérieures.
- Documentation à priori officielle en anglais du module CMPS03, révisions 14 et postérieures.





