jeudi 13 novembre 2014

FGM-3

Continuant sur la lancée d'Aurora detector, j'ai fait l'acquisition d'un petit magnétomètre 'fluxgate' FGM-3 (pour environ 40 euros tout compris)...
Un premier essais avec une pile. À noter que sur la photo, la terre du 'logic analyser' est dessinée... C'est aussi une mauvaise idée d'utiliser des piles sans régulateur; la tension varie et la période du signal dérive... Avec une batterie 12 volts et un régulateur 78L05, cela fonctionne beaucoup mieux. Le constructeur recommande d'utiliser un 78L05 en cascade avec un 78L09.

Le bidule, grand comme une pile AA, comporte 4 broches (mais je n'en utilise que 3). Il suffit de l'alimenter en 5 volts et un signal rectangulaire dont la période dépend du champ magnétique sort sur une troisième broche. La documentation annonce une période relativement linéaire entre 8 µS et 20 µS dans le champ magnétique terrestre (-.5 gauss à +.5 gauss) suivant l'orientation du capteur.
Forme du signal quand le capteur est orienté est-ouest (Pulseview avec sigrok dans le clone Saleae à 24 MHz)

Plusieurs options existent pour mesurer cette période. On peut mesurer la fréquence en comptant le nombre de cycles pendant une période donnée, par exemple, une seconde. Elle varie donc entre 125 KHz et 50 KHz. C'est l'option choisie ici avec un Arduino (pendant 5 secondes). On peut aussi mesurer la période si on dispose d'un compteur suffisamment rapide... Après, c'est une question de compromis entre la finesse de la mesure et le temps d'acquisition. Comme je disposais d'un clone Saleae, j'ai décidé de mesurer le temps pris par un certain nombre de cycles.
Enregistrement brut du 12 novembre 2014. NanoTesla à partir du nombres de ticks à 4 MHz pour 25000 flancs descendants. Les barres verticales correspondent à des entrées/sorties de voitures dans le passage latéral. Il y a un certain bruit de fond et une perturbation entre 13 et 22 heures. Pourquoi est-ce aussi stable et à quoi est due cette perturbation? Il va falloir faire des mesures durant plusieurs jours pour essayer de le comprendre. L'idéal serait de disposer d'une mesure officielle pas trop éloignée pour pouvoir comparer.

De telles mesures sont disponibles sur le site Intermagnet (sous forme graphique et sous forme chiffrée). Les mesures les plus proches sont probablement celles de Dourbes (~100 km, code 'DOU'). Cela varie, de fait, continuellement et les données sont filtrées. La manière dont sont prises les données est documentée. Il est à noter que les courbes disponibles sont généralement non corrélées et que mes mesures en génèrent peut-être une autre encore...

En rapprochant la génération du 5 Volts du FGM-3 et en le faisant de la manière recommandée (avec un 78L09 suivi d'un 78L05 et 3 condensateurs) les zones de stabilités ont tendance à disparaître. Cela donne, après filtrage, quelque chose comme :
...Ce qui ne correspond pas vraiment à ce qu'ils ont mesuré à Dourbes.... Et, ce qui chipote aussi, c'est que l'amplitude est plus grande ici. Y aurait-il une erreur dans la formule de conversion ticks->Tesla?

Une manière d'évacuer ce doute est de mettre le FGM-3 dans un champ connu (ou, plus exactement, faire varier le champ de manière connue). Un bon moyen pour le faire est de mettre le détecteur au centre de bobines de Helmoltz... Aussitôt dit, aussitôt fait.
Deux fois dix tours sur un morceau de bouteille en plastique de 2 litres (R = ~0.05 m), une source de 5 Volts avec une résistance de ~ 2.5 KOhm (ce qui donne un courant de 2 mA) est sensé me donner un champ de 360 nT... Alors que la déviation d'une boussole est imperceptible (la modification du champ est inférieure au % du champ terrestre), la variation est clairement visible sur un graphe.
Le 'stuut' c'est que ma formule de conversion donne une variation de 40 nT... Ha-là-là... (alors que j'aurais voulu diviser la mesure par 10, voilà maintenant que je dois la multiplier par 10; ça ne s'arrange pas, il va falloir revoir les calculs...; Il faudrait aussi faire un essai à l'extérieur, en pleine nature, loin des perturbations potentielles)

Des mesures 'scientifiques' en temps réel sont disponibles sur http://InterMagnet.org ([données] et la documentation dans [publications]). À suivre...

vendredi 26 septembre 2014

Aurora detector

En cours de rédaction...

En cherchant sur Internet 'Aurora detector', on tombe en premier sur le 'Pop-bottle detector' proposé par l'AuroraWatch UK de l'université de Lancaster; aussi connu sous le nom de 'jam-jar magnetometer'. Un aimant pendu à un fil dans une bouteille ou un pot de confiture se déplace au gré des fluctuations du champ magnétique ambiant. Les aurores étant liées aux perturbations du champ magnétique terrestre par le vent solaire, on essaye de détecter celles-ci au moyen de ce magnétomètre 'maison'. Ces perturbations étant faibles en Belgique, il convient d'amplifier le 'signal' pour en faciliter la mesure. Traditionnellement, on colle un petit miroir sur l'aimant, on l'éclaire par une source plus ou moins ponctuelle et on s'intéresse au 'spot' lumineux réfléchi sur un mur (un dixième de degré de rotation se traduit par un déplacement du spot de près d'un centimètre et demi à quatre mètres (4*tg(2*.1)=1.01396 (à vérifier...)). Le dispositif a la réputation d'être très sensible malgré sa simplicité : avec un fort aimant et un fin fil, on détecte le mouvement de voitures à plusieurs dizaines de mètres.

C'est amusant mais ce n'est pas très pratique. Il faudrait encore détecter les mouvement du spot lumineux pour l'enregistrer, générer une alarme, que sais-je encore... On trouve maintenant de petits magnétomètres dans les téléphones portables, les boussoles électroniques, les GPS,... On peut même acheter des kits comprenant le HMC5883L pour un peu plus d'un euro sur eBay (GY-271). Il s'interface facilement avec un Arduino ou un Raspberry Pi, les trois petits magnétomètres X-Y-Z fournissent leurs mesures sur 12 bits sur un bus i²c. Rien n'est plus simple à interfacer : 4 fils, quelques lignes de code et nous voilà avec un magnétomètres mesurant jusqu'à 8 gauss avec une résolution de 2 milligauss. Est-ce suffisant pour 'détecter les aurores'? Pas sûr. Le champ magnétique terrestre fait 500 mG... (il faudrait tester sans l'aimant et trouver des références expliquant que les perturbations peuvent atteindre 10% (où?))

Par contre, un truc amusant, c'est de placer ce détecteur dans le champ de l'aimant pendu au fil dans le bocal... L'idée, c'est que l'aimant va prendre sa place dans le champ ambiant tout en générant un champ beaucoup plus puissant et donc plus facile à mesurer. En fait, on s'intéresse à la variation du champ suite au déplacement infime de l'aimant (et on espère que ces variations seront facilement mesurables)...

Avec des aimants de disque dur, cela donne quelque chose comme :
Si on s'intéresse au spectre du signal avec GNU Octave (plotspec.m),
on trouve une oscillation de 4-5 secondes. Cela doit correspondre à l'oscillation naturelle de l'aimant au bout du fil. Sa période dépend du moment d'inertie de l'aimant et des forces de rappel qu'exercent le fil et l'interaction des champs magnétiques. Si on zoome sur le graphique, on observe bien les oscillations.
Dans ce cas-ci, je prends (environ) deux mesures par seconde. La fréquence d'échantillonnage n'est pas exactement 2 Hz parce que l'interrogation boucle dans un script qui relance chaque fois le programme... Pour l'instant, ce n'est pas très important, c'est donc 'bon assez'. À noter que cette technique de mesure a certaines conséquences : on ne mesure pas le champs instantané, on ne risque pas de louper une brève perturbation pour autant qu'elle ait un effet sur le pendule qui réagit comme une balançoire : on peut pousser dans le sens du mouvement ou à contre-temps. Ensuite, on a tout le temps pour prendre la mesure, le bidule oscille autour du champ non perturbé (-> balance de pharmacien; on n'attend pas que l'oscillation s'arrête, on la centre (?)).

Si on analyse le résultat global, sur ces 10 premières heures, je ne détecte pas vraiment d'aurores mais beaucoup de perturbations locales : fortes, des passages de voitures vers/de l'arrière de l'immeuble pendant les heures de bureaux et moyennes, les véhicules qui passent dans la rue; cela se calme en soirée; c'est encore plus calme pendant la nuit et reprend le matin. À noter que ces voitures passent d'ouest en est dans la rue et (principalement) du nord au sud le matin et du sud au nord à 17 heures dans le passage latéral (où les camions, bus,... ne peuvent pas passer).

On note quand même une tendance à la baisse. Mais, on ne peut pas vraiment savoir si c'est le fil qui s'allonge sous la fatigue, une modification de l'hygrométrie, de la température ou un autre phénomène. Il faut aussi noter que le bidule est sur la table du salon au milieu de la pièce et que les pas sur le plancher laissent probablement également leur empreinte. On note également que l'oscillation est amortie mais c'est très lent, il est très rare qu'elle s'amortisse suffisamment pour noyer le signal dans le bruit du capteur avant qu'une nouvelle perturbation du champ ne vienne remettre l'aimant en mouvement. Il faut encore apprendre à connaître, apprivoiser le dispositif...

D'où l'intérêt de lancer une plus longue campagne de mesure...
Elle court pendant une semaine et un jour (du 23 septembre à 15:37 jusqu'au 30 septembre mi-journée + un jour sans bocal). La présence de l'aimant dans le bocal amplifie bien le signal (XYZ devient quasi plat quand on retire le bocal, il n'y a pas une simple modification de la direction; à noter que les autres directions saturaient avec l'aimant). On observe les entrées/sorties de voitures dans le passage latéral (une vingtaine (?) de voitures chaque fois). Le reste, c'est du trafic dans la rue (il faudrait que je me procure un horaire des bus...). Notez que le 27 est un samedi et qu'il n'y a pas d'entrées massives vers les bureaux dans le passage latéral. Mais, ce que l'on observe aussi, c'est une variation de grande ampleur. En fait, pour le moment, SpaceWeather montre des aurores. Le NOAA NOAA's Space Weather Prediction Center affiche
Le graphe ne redescend pas, cela semble dû au vieillissement de quelque chose qui se laisse aller (?)... (Entre-temps, je pourrais vérifier que la fréquence d'oscillation est restée constante, ce qui aurait tendance à indiquer que ce n'est pas lié au fil mais c'est vrai qu'un changement dans l'intensité du champ va aussi provoquer une modification de la fréquence...).

Quand la nuit est calme, on peut observer l'amortissement des oscillations. Cela met vraiment très longtemps. Après une perturbation à 03h17 le 28/09, on peut toujours percevoir les oscillations 40 minutes plus tard (?) (sans que l'on puisse percevoir d'autres perturbations).
En fait, c'est la méthode utilisée lors des premières études du magnétisme terrestre à la fin du XVIII-ième siècle. Notamment par Robert de Lamanon lors de l'expédition de La Pérouse. La force du champ magnétique dépend de la latitude. Cela se traduit par des oscillations plus lentes à l'Équateur qu'aux latitudes plus élevées. Y-a-t-il bien un lien entre la déviation et l'apparition d'aurores? Il semble que oui. Par exemple, lors de l'aurore du 21 octobre 2001, en Belgique, on peut observer une déviation à l'observatoire de Chambon-la-Forêt et à Wingst (pas de mesures à Dourbes (plus proche) à cette époque). Ces déviations sont rares, très rares, exceptionnelles à nos latitudes, d'ordinaire, c'est le calme plat.

En empilant un tas de petits cylindres au néodium et en le pendant à une fibre extraite d'un lacet, on peut observer l'inclinaison magnétique. L'inertie du bareau étant plus importante, la période d'oscillation augmente quand on l'allonge.

À suivre...

Parmi les trucs à regarder de près, la géométrie de l'aimant, le type et la longueur du fil, la position du capteur pour maximiser la dynamique en fonction du mouvement (mais sans saturer). À noter que si on plonge l'aimant dans un bain d'huile, l'amortissement des oscillations est radical mais la sensibilité disparaît également. Évaluer (par calcul quand j'aurai un aimant plus orthodoxe) le moment d'inertie et les forces de rappel (par mesure des périodes avec des barreaux similaires (aimanté et non aimanté).

Bref, plein de trucs intéressants à faire pour quelques euros... ;-)

lundi 15 septembre 2014

Filtrons avec Octave

Chipotons un peu avec GNU Octave (MATLAB)... Je m'étais intéressé, il y a quelques mois à la détection des signaux faisant basculer les compteurs électriques bihoraires au moyen d'un simple fil sur le connecteur microphone d'un PC. Je vais utiliser un bout de fichier pour faire du 'traitement de signal' (filtrage numérique).
$ echo 'date "+%g%m%d.%H%M%S"' > now; chmod +x now
$ arecord -f S16_LE -t raw -r 25000 > 25000.`./now`
$ dd if=25000.131204.064758 of=sample.raw bs=1000 count=5 skip=1
$ sox -r 25000 -e signed -b 16 -c 1 sample.raw sample.wav
Et dans Octave,
x = wavread('sample.wav');
y = x - mean(x);   # remove the DC component
plot(y)
print -dpng 'bzzz_50Hz.png'
donne
et
plotspec(y, 1/25000)
print -dpng '50Hz_spectrum.png'
donne
On voit (ou pourrait voir en zoomant avec le bouton de gauche de la souris) que la composante principale du spectre se trouve à +/- 50 Hz mais que l'on trouve des harmoniques avec une magnitude atteignant 10% de la composante principale. Ce n'est probablement pas la bonne manière de faire (?) mais le but est ici de jouer avec les fonctions de filtrage de MATLAB/GNU Octave. Par exemple, éliminons les harmoniques avec un FIR :
b = fir1(120, 0.0035);
z=filter(b, 1, y);
clf;
plotspec(z, 1/25000);
print -dpng 'spectrum_50Hz_filtered_FIR_120_0.0035.png'
donne
La réponse fréquentielle du filtre nous est donnée par :
clf;
freqz(b, 1, 512, 'half', 25000);
print -dpng 'filter_FIR_120_0.0035.png'
Essayons d'isoler l'harmonique à 250 Hz en concevant un FIR avec remez() (firpm() dans MATLAB. On spécifie la réponse fréquentielle approximative que l'on désire au moyen de deux vecteurs (fréquences/réponses) :
f = [0 0.03 0.04 1];
a = [0 1    0    0];
w = [1 1];
b = remez (120, f, a, w);
clf;
freqz(b, 1,512,'half',25000);
print -dpng 'remez.120_0-1-0-0_0-.03-.04-1_freq.png'
z=filter(b, 1, y);
clf;
plot(z);
hold on;
plot(y, 'r');
print -dpng 'remez.120_0-1-0-0_0-.03-.04-1_result.png'
donne
et
Le filtre n'est pas très sélectif mais le 250 Hz ressort bien (en bleu).


...En cours de rédaction / y-a un truc qui cloche...
Le 0.0035 passé à 'fir1()' est à comparer avec 50/(25000/2) ('fréquence normalisée'), on coupe un peu dans le 50Hz, cela aurait dû être supérieur à 0.004 (50/12500) (?). La pente du filtre n'est pas extraordinaire, on est à -10 dB à 250 Hz...

dimanche 20 juillet 2014

AIS

Dans le cadre des expérimentations rtl-sdr (radio logicielle avec clé TNT/DAB à moins de dix euros), une petite captation avec ais_rx.py sous Linux sur le terril Saint-Gilles à Cointe derrière le stade du Standard.  On a une belle vue sur la vallée de la Meuse vers Huy; au loin, on aperçoit les tours de refroidissement de la centrale nucléaire de Tihange.
Un quart d'heure de captation (sous lubuntu) a permis de recevoir environ 900 messages AIS de péniches entre Kinkempois et Amay.
En vert, la captation par un programme encore expérimental moins sensible mais beaucoup plus léger que ais_rx.py qui est basé sur GNU-Radio.  Il est possible d'envoyer les lignes NMEA dans OpenCPN.  On obtient alors quelque chose comme :
Mais, bien sûr, ce serait mieux avec une carte en fond...  Ici, c'était juste pour tester la cross-compilation vers XP (avec Mingw) et l'interface tcp avec OpenCPN.  On notera la présence de l'écluse d'Ivoz-Ramet au milieu de l'écran (?).

Plus tard, ailleurs...

En utilisant les cartes de OpenNauticalChart et en utilisant OpenCPN avec naive_ais, en mars, on obtient :

Il faut noter que la version de naive_ais manque terriblement de sensibilité à cette époque et ne capte qu'une partie des messages. La carte monte un agrégat de deux campagnes de captation. Une sur un terril qui n'avait réussi qu'à capter un bateau et l'autre, dans le port même (un peu trop près du bateau pompe-à-essence) qui ne les capte pas tous non plus...

Voir aussi



lundi 28 avril 2014

ADS-B sur piles

Liège-Bastogne-Liège 2014, le jour idéal pour tester dump1090 sur un Rasberry Pi (avec touchscreen) sur piles sur les hauteurs de Liège... Le but est de capter les messages ADS-B envoyés par les hélicoptères de la courses. L'équipement est simple : un pack de 6 piles rechargeables NiMH (ALDI/Top Craft), un petit convertisseur DC-DC pour ramener la tension à 5 volts, un Raspberry Pi, son touchscreen Tontec (MZTX-PI-EXT) et une petite clé USB TNT équipé du chip Realtek RTL2832U permettant le RTL-SDR avec son antenne d'origine (ou une de ses sœurs.


Dump1090 fonctionne dès le départ sur le Raspberry Pi.  Le problème était de rendre celui-ci portable pour aller capter les avions sur les hauteurs...  Pour cela, deux aspects : l'alimentation et le contrôle.  Pour le contrôle, l'idéal est un touchscreen.  Il y en avait un pas cher mais il n'était pas sûr que cela fonctionne.  Si l'affichage semblait ne poser aucun problème grâce à un article de ce blog , la partie 'touch' a nécessité quelques recherches et développements... Mais, donc, cela a fini par fonctionner.  Pour l'alimentation, le pack de six piles et le convertisseur DC-DC offre la solution idéale pour peu que l'on se contente d'une autonomie de quelques heures; le RPi et le touchscreen consomment 0.5A sous 5 volts (sans le dongle TNT).  Le convertisseur permet 2 A et les piles ont une capacité de 2.3 Ah.

Restait juste à développer une petite application graphique pour lancer l'acquisition, la stopper et éteindre le Pi...  Le plus simple est d'écrire quelques lignes en Tcl/Tk faisant appel à des scripts shell.


Bien sûr, ce serait mieux d'avoir une interface montrant les avions, etc...  Mais pour l'acquisition, c'est le plus facile.  Avec une Raspbian, il suffit d'ajouter une ligne à /etc/xdg/lxsession/LXDE/autostart du genre '@wish /home/pi/menu.tcl'.  Un script de quelques lignes :

#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

button .quit -text "Quit!" -command { exit }
button .rec -text "Record" -command { exec /home/pi/rec.sh & }
button .stop -text "Stop" -command { exec /home/pi/stop.sh & }
button .shutdown -text "Shutdown" -command { exec /home/pi/shutdown.sh & }

pack .rec .stop .quit .shutdown
Et le tour est joué. Les scripts contiennent des lignes comme : '/home/pi/bin/dump1090 > dump1090.`/usr/local/bin/now`' (now est 'date "+%g%m%d.%H%M%S"' et permet de suffixer le fichier avec le jour et l'heure); 'pkill dump1090' et 'sudo shutdown -h now'. La captation d'environ une heure entre 14 et 16h30 donne le résultat suivant :
Où l'on peut voir les coordonnées envoyées par les aéronefs : en abscisse, la longitude, en ordonnée, la latitude.  Pour donner une idée, Maline est en 51/4.5, Cologne 54/7, Orléans 48/2 et Bâle 47.5/7.6.  La captation était en 50.6/5.6 avec une bonne vue vers le sud (et moins bonne vers le nord où l'hôpital de la Citadelle masque la vue).

Si on trace la distance à l'aéronef (projeté au sol) calculée à partir des coordonnées géographiques contenues dans certains messages (grâce à la formule trouvée ici), cela donne le graphique suivant :

Les ruptures sont dues au fait qu'il s'agit d'un assemblage de plusieurs captations mais on voit clairement les avions s'approcher puis s'éloigner.  En général, plus les traces sont proches, plus elles sont continues mais certaines traces étonnamment lointaines sont aussi visibles.

Si on s'intéresse à l'altitude des aéronefs, on obtient le graphique suivant :
On observe de nombreux vols à altitude constantes mais aussi des montées et des descentes.  Le plus haut, à 44925 pieds est un jet privé, M-JANP, parti de Londres vers la Turquie, les plus bas sont les hélicoptères de la courses.  À nouveau, il y a des coupures dues à l'assemblage.

Pour la petite histoire, les hélicoptères captés étaient OO-HCZ, OO-HCW et OO-HCP. Mais j'ai aussi capté OO-SEX, le Cessna des parachutistes de Spa; OO-URS et OO-VPD, un petit bi-moteur et près de 300 avions de lignes.  Sur un peu plus d'une heure, entre 14h30 et 16h30, le système a capté 726 713 messages (! peut-être à vérifier, cela fait 200 messages à la seconde !).

Je peux isoler un profil de vol particulier.  Par exemple, pour OO-SEX, cela donne :
Il semble larguer les parachutistes à 2800 pieds (et comme le terrain est à un peu plus de 400 mètres d'altitude, cela fait environ 500 mètres au dessus du sol (?)).  Le cafouillage vers la fin provient probablement d'une perte de communication due à une altitude trop basse et on reprend avec la montée de la rotation suivante (?).  En fait, les mesures ont été prises sans repères temporels (le dump1090 original ne donne pas le temps de la captation du message et le Raspberry Pi n'a pas d'horloge temps-réel à la base; ceci peut être réglé avec un module RTC i2c avec un composant DS1307 (howto (.pdf)) mais il n'était pas branché (et donc, pas lu...)).

Identifications captées : AAF515, AAR501, ABW715, ADH818, AEE601, AEE624, AEE625, AFL2455, AFL2458, AFL2463, AFR1053, AFR112, AFR1147, AFR1211, AFR128, AFR146F, AFR1535, AFR1607, AFR1623, AFR1645, AFR1822, AFR1844, AFR1851, AFR1889, AFR1953, AFR253, AFR389E, AFR508, AFR562, AFR936F, ASR342, AUF171, AUI128, AWE711, AZA88Z, AZA97U, BAF610, BAH7, BAW147, BAW2676, BAW277, BAW347, BAW35, BAW45T, BAW53ZG, BAW547, BAW563, BAW632, BAW64G, BAW679, BAW703, BAW905U, BAW910N, BAW952M, BCS723, BEL2GP, BEL3PR, BEL5HR, BEL5VC, BEL716, BEL7PC, BEL7TX, BER2860, BER527N, BER797Q, BMR16GB, BMR45JR, BMR46CN, BMS123, BOX413, BRU866, CFE41G, CFG8TD, CTN4456, CYP347, DAL245, DAL475, DKGSA, DLH25E, DLH2CH, DLH2F, DLH2MF, DLH2NL, DLH2RX, DLH37E, DLH53T, DLH66A, DLH7TP, DLH8WH, DLH96E, EIN358, EIN359, EIN44T, EIN55N, ETD021, ETH3717, EXS92WX, EZS13EY, EZS82FX, EZS93FY, EZY11JX, EZY1972, EZY1975, EZY2085, EZY2134, EZY263F, EZY31RU, EZY46MN, EZY49VU, EZY5116, EZY51KE, EZY57EV, EZY58UH, EZY62WU, EZY64KC, EZY65XL, EZY67LT, EZY74GK, EZY75HC, EZY83EB, EZY85JM, EZY8832, EZY88PX, EZY8909, FALCN01, FBR14DI, FGVLD, FHY7884, FPO191X, GBYNE, GMI1142, GWI55M, GWI65B, GWI73E, HKY91, HOP3575, HVN16, IBS3731, ICV518, IRL258V, ISF60EU, JAF12Y, JAF29V, JAF3YG, JAF83W, JAF9BJ, JEF11, KAY56, KLM13T, KLM1415, KLM1602, KLM1987, KLM19P, KLM67Z, KLM79K, LAN704, LCO1505, LGL4603, LGL742, LGL7WD, LGL95E, LNX83GP, MJANP, MON1376, MON486G, MON5409, MON812, MON908, MSR725, MSR784, MSX521, MTINK, N3BR, N900HG, NAX2497, NAX5181, NAX92Y, NJE6MA, OMA134, OOHCP, OOHCW, OOHCZ, OOSEX, OOURS, OOVPD, OYMMM, PAL720, PGT502, PGT521, PGT522, PHAML, PHEDM, PRI244, PRI2704, QTR004, QTR040, QTR194, RJA111, ROT383, ROT384, ROT392, RRR2305, RYR10DL, RYR10UB, RYR16NB, RYR18DR, RYR1939, RYR26KZ, RYR30XE, RYR36VT, RYR39RT, RYR4014, RYR40JB, RYR40MX, RYR44BZ, RYR46QZ, RYR54HG, RYR582, RYR70JU, RYR70NW, RYR70SN, RYR754, RYR755, RYR793, RYR87BT, RYR87RK, RYR88QC, RYR973, RYR98EG, SAS559, SNM572, SUS9152, SWR319, SWR31N, SWR324, SWR35T, SWR64, TAP561, TAP686, TAP757W, TAP787B, TCW7922, TCW814E, TCX1588, TCX1628, TCX2549, TCX3425, TFL523, THA931, THY1819, THY1939, THY1966, THY7LT, TOM053, TOM23C, TOM393, TOM3FC, TOM435, TOM4JG, TOM843, TRA1739, TRA347T, TRA512N, TRA6348, TRA653P, TUI6PC, TVS13J, TWI583, UAE205, UAL964, VIR652W, VJS617, VLG1265, VLG1876, VLG6206, VLG8355, VPBDB, VPBZL, VPCYY, VQBFN, VQBHO, WZZ3TF, WZZ7UG, WZZ959.

Voir aussi

mardi 21 janvier 2014

Autour du Raspberry Pi



Le Raspberry Pi comporte un header 13x2 pins donnant accès à un bus I2C et il est possible de trouver, sur eBay, un tas de petites cartes comportant des capteurs, compatibles avec ce bus, pour quelques euros. On peut ainsi mesurer l'accélération en 3D, la giration, le champ magnétique, la température, l'humidité (pas encore trouvé en I2C), etc...

Par exemple, la micro-carte GY-271 mesure le champ magnétique 3D avec une résolution de l'ordre du milli-Gauss.


Elle utilise le composant HMC5883L de Honeywell. Il fait 3x3 mm² et est épais de moins d'un millimètre!

Avant toute chose, il faut savoir que la possibilité de développement d'applications utilisant le bus I2C n'est pas activée par défaut. Il y a quelques opérations à effectuer : il faut installer les packages i2c-tools et libi2c-dev, ajouter deux lignes dans /etc/modules, commenter une ligne dans /etc/modprobe.d/raspi-blacklist.conf. Voir 'Guide to interfacing a Gyro and Accelerometer with a Raspberry Pi'.

La connexion physique du module est très simple : il suffit de repérer les quatre headers utiles sur le Raspberry Pi : 3.3V, Ground, sda, scl et leur correspondant sur la micro carte. Avec des fils 'femelle'-'femelle', c'est trivial (là, je n'avais que des mâle-femelle, j'ai dû chipoter un peu).

Une fois connecté, on peut faire :
xofc@raspberrypi ~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
On constate que le HMC5883L est bien vu à l'adresse 0x1e. Le code minimal, en 'C' pour accéder au composant ressemble à quelque chose comme
#include <unistd.h>  
#include <errno.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <linux/i2c-dev.h>  
#include <sys/ioctl.h>  
#include <fcntl.h>  
  
const char *I2C_BUS_DEV = "/dev/i2c-1";

void crash(const char *str)
    {
    perror(str);
    exit(-1);
    }
int i2c_rw(int fd, int reg)
    {
    int    x;

    if ((x = i2c_smbus_read_word_data(fd, reg)) < 0)
        return(-1);
    return(((x&0xff)<<8) + ((x&0xff00)>>8));
    }
int main()  
    {  
    int    fd;
    int    res;
    int    ira, irb, irc; /* Identification registers : 'H','4','3' */
    int    mag_x, mag_y, mag_z;
  
    if ((fd = open(I2C_BUS_DEV, O_RDWR)) < 0)
        crash(I2C_BUS_DEV);
  
    if (ioctl(fd, I2C_SLAVE, 0x1e) < 0)  /* 0x1e = hmc5883l address */
        crash("I2C_SLAVE 0x1e hmc5883l");  

    if ((ira = i2c_smbus_read_byte_data(fd, 10)) < 0)
        crash("reading IRA");
    if ((irb = i2c_smbus_read_byte_data(fd, 11)) < 0)
        crash("reading IRB");
    if ((irc = i2c_smbus_read_byte_data(fd, 12)) < 0)
        crash("reading IRC");
    printf("Identification Registers A-B-C = 0x%02x-0x%02x-0x%02x ('%c'-'%c'-'%c')\n", ira, irb, irc, ira, irb, irc);

    if ((res = i2c_rw(fd, 10)) < 0)
        crash("rw error\n");
    printf("IR A-B = 0x%04x\n", res);

    /* set control register : CRA = 0x70 - CRB = 0x00 */
    if ((res = i2c_smbus_write_byte_data(fd, 0, 0x70)) < 0)
        crash("CRA");
    if ((res = i2c_smbus_write_byte_data(fd, 1, 0x00)) < 0)
        crash("CRB");

    /* Mode = 0x01 Go! */
    if ((res = i2c_smbus_write_byte_data(fd, 2, 0x01)) < 0)
        crash("Mode");

    usleep(6000); /* wait command to complete */

    /* check status - command complete */
    if ((res = i2c_smbus_read_byte_data(fd, 9)) < 0)
        crash("status");
    if (!(res & 0x01))
        crash("**** Not ready!\n");

    if ((mag_x = i2c_rw(fd, 3)) < 0)
        crash("reading Mag X\n");
    if ((mag_z = i2c_rw(fd, 5)) < 0)
        crash("rw error\n");
    if ((mag_y = i2c_rw(fd, 7)) < 0)
        crash("rw error\n");

    printf("Mag_xyz= %5d %5d %5d\n", (short)mag_x, (short)mag_y, (short)mag_z);

    close(fd);
    exit (0);
    }
Et se compile avec la commande :
$ gcc -o hmc5883l -l rt hmc5883l.c
En fait, ce code fait un peu plus que le minimum puisqu'il commence par aller chercher l'identité du composant en allant lire les 'Identity Registers' qui sont bien 'H', '4', '3'. Qu'il en lit ensuite deux à la fois pour vérifier que i2c_smbus_read_word_data() ne lit pas les octets d'un mot dans le bon ordre (il faut les inverser). Il configure ensuite les 2 registres de configuration, lance la commande, attend 6000 micro-secondes, lit les résultats et les affiche. Le programme n'utilise que i2clib (et n'utilise pas de #define's par paresse; il faut consulter la datasheet pour vérifier à quoi correspondent les données numériques). Il est aussi un peu radical du côté du traitement des erreurs : si quelque chose ne se passe pas comme prévu, il affiche un message et abandonne. Le but n'est pas ici de faire un programme complet mais de faire le programme le plus simple possible pour aller chercher la valeur de mesures.

Mais donc, c'est très simple. Pour s'en tenir au principal, on a :
    fd = open(I2C_BUS_DEV, O_RDWR));         /* i2c access */
    ioctl(fd, I2C_SLAVE, 0x1e);              /* connect chip */
    i2c_smbus_write_byte_data(fd, 0, 0x70);  /* Config Reg A = max sensibility */
    i2c_smbus_write_byte_data(fd, 1, 0x00);  /* Config Reg B = default */
    i2c_smbus_write_byte_data(fd, 2, 0x01);  /* Go! */
    usleep(6000);                            /* wait a little */
    mag_x = i2c_smbus_read_word_data(fd, 3); /* read values */
    mag_z = i2c_smbus_read_word_data(fd, 5);
    mag_y = i2c_smbus_read_word_data(fd, 7);
À noter que i2c_smbus_read_word_data() ne lit pas les octets dans le bon ordre, une histoire d'Indiens...

Ce qui n'est pas traité non plus, c'est la calibration, l'usage des différentes gammes de puissance du champ magnétique (le traitement des overflows), la traduction en vecteur indiquant la direction du Nord magnétique.

En tripotant le montage dans le champ magnétique terrestre, on obtient les premières mesures 'brutes' suivantes :
Il faudrait faire des mesures avec le capteur à plat à différents angles et voir si on peut retrouver les angles à partir de mag_x et mag_y (quelles valeurs de base?, multiplicateurs? (est-ce linéaire?) et probablement calculer un arc tangente(val_y/val_x)).

Note: à partir de l'hiver 2014-2015, le bus i2c est passé sous 'device tree'. Le moyen le plus simple de refaire fonctionner l'i2c est d'utiliser
$ sudo raspi-config
d'aller dans 'Advanced Options' et d'autoriser i2c (enable device tree & i2c).