thermal camera arduino based (MLX90614)
First draft of this project is finished and functional feel free to fork and/or improve at https://github.com/PostTenebrasLab/2d-thermography
Status du project | |
---|---|
Date de début | 15/08/2014 |
Status | finished |
Initiateur(s) | Sebastien (sinux) |
Le but de ce projet était de générer un thermogramme à l’aide d’un
thermomètre infrarouge.
Deux moteurs pas-à-pas orientent un capteur IR en 2 dimensions. Ce
mécanisme permet de balayer une surface (X-Y). Pour chaque coordonnée,
une mesure de température est effectuée.
Au final, les données permettent de générer une cartographie thermique de la surface sous
forme d’image (ou thermogramme).
Toutes les pièces ont été dessinées et usinées au PTL. Seul les moteurs et l'éléctronique ont été acheté.
pièces imprimées en ABS ave une imprimante du PTL.
ensemble .stl...
(toutes les sources openscad et .stl sur github)
l'équerre et la base ont été usinés avec la badog
l'équerre est fraisée et pliée à l'étau (avec des cales en bois).
Le roulement, les vis de fixation des moteurs, le dégagement du moteur ont également été fraisé (dans une chute de bois).
Le montage a été relativement facile. Le capteur est sur un bus SMBbus
(System Management Bus, proche de l'I2C). Pour le faire fonctionner,
la librairie wire.h de l'arduino ne suffit pas. On peut trouver une
librairie “améliorée” sous le nom i2cmaster.h et des exemples de code
pour récupérer les données du MLX90614. Le bus est monté avec deux
pullup et une capacité de découplage.
Les moteurs se montent directement sur la shield qui est bien
documentée (wiki). Ces moteurs consomment peu est ont une tension
d'alimentation de 4-6V. Je voulais au début utiliser des drivers
pololu A4988 mais ils avaient besoin que les moteurs soient alimentés
au moins en 8V ce qui a éliminé ce choix.
Une des difficultés qui m'a fait perdre le plus de temps a été un
problème avec le moteur de l'axe Y. Le signal de la sortie (Y1B) était
étrange et le moteur ne faisait que des oscillations. Nous avons
changé le driver moteur (A3967) ce qui n'a pas résolu le
problème. J'ai finalement découvert qu'une pin touchait le blindage du
connecteur USB de l'arduino - un problème fréquent.
La shield est facile à utiliser. Une Pin contrôle la direction du
moteur, deux Pins le micro stepping (1, 1/2, 1/4, 1/8) et une Pin sert
aux steps. Un pulse de 1us minimum équivaut à un pas. Il suffit de
générer un signal pour les faire tourner.
Les endstop sont montés avec des résistances de pulldown comme pour
des boutons. Il n'y a pas d'anti rebond dans le code puisque leurs
états est lu puis suivit d'un déplacement. À la lecture leur état est
stable (au pire il y a une erreur d'un pas).
L'image est déformée pour plusieurs raisons. Tout d'abord, la distance
entre deux points n'est pas la même à 1m qu'à 2m ce qui implique
que x est proportionnel à la distance de mesure. De
plus si l'on est perpendiculaire à une surface la distance n'est pas
la même au centre que sur les côtés (léger effet
oeil-de-boeuf). L'effet est encore plus important en n'étant pas
perpendiculaire à la surface. Autre cas, si l'on mesure plusieurs
sujets sur des plans différents, leur résolution respective ne sera
pas la même.
En mesurant des objets au contour net, l'image est entrelacée. Comme
la lecture se fait par aller-retour, les pixels sont ajouté à la
matrice tantôt de gauche à droite, tantôt de droite à gauche. Un
décalage du flux de donnée pourrait expliquer cet entrelacement. Un
délai entre la mesure, la transmission et le traitement aurait aussi
pu expliquer cela. Après vérification, le problème apparaît être
mécanique. Il est dû au rattrapage du jeu de la vis (plusieurs pas
moteur ne font aucun mouvement). La communication a été testée en
envoyant des constantes (valeurs différentes G-D et D-G). Ce test a
néanmoins permis de mettre en évidence des erreurs de lecture à 115200
bauds. Pour éliminer les délais lors de la lecture, en fin de ligne,
le capteur est lu 10 fois “à vide” pour garantir de partir avec une
valeur “propre”.
Le capteur ayant un angle de 5°, ce n'est pas un point mais une zone
qui est lue. Il y a un prépondérance de lecture au centre avec une
influence décroissante sur les bords. Il reste que l'on ne lit pas la
température exacte d'un point mais d'une zone. Comme pour un appareil
photo, si la lumière n'est pas focalisée, l'image n'est pas
nette. Dans cette application, on recherche plus de l'information
qu'un rendu graphique, ce n'est donc pas aussi grave qu'en photo.
Au début, j'ai essayé d'obtenir la vitesse de déplacement la plus
rapide afin de réduire le temps d'acquisition. Les premiers résultats
avaient une succession de valeurs identiques (5-10 pixels). Le problème
vient du temps de réaction du capteur (la datasheet n'en parle
apparemment pas). Pour résoudre le problème, j'ai dû augmenter le
temps entre les mesures à 90ms. Ce délai rallonge considérablement le
temps total.
L'arduino en s'allumant vient chercher le zéro et se met en
attente. Depuis octave, on envoi les variables; le nombre de points en
X, en Y, le MS et le délai entre les mesures.
Une fois que l'arduino a reçu ces variables il commence le scan et
renvoi les datas à octave qui les mets dans une matrice.
Pour améliorer le contraste, on normalise la matrice qui est affichée
avec une colormap HSV (hue-saturation-value). Les valeurs min, max et
la température moyenne du capteur est également retourné
=== Évolutions possibles ===
[2d-thermography] | Interested in joining this project | |||
---|---|---|---|
Nom | participation active | participation passive | suivre de loins |