Picaxe et accéléromètre LSM303DLM

PieM

Senior Member
Calcul simplifié d'angle d'inclinaison de l'accéléromètre selon X ou Y.
Le calcul est effectué avec une erreur de 2° entre -50 et + 50°
la valeur de l'angle est recentrée sur 90 pour l'horizontal afin de n'avoir que des valeurs positives, (donc comprises entre 40 et 140).
A venir: la même précision pour des angles supérieurs.

Code:
[color=Green]#REM##############################################
# Lecture des données d'accéléromètre LSM303DLM
# valeurs en degrés de -50° à +50° avec erreur < 2°
# ramenées en valeurs positives centrées sur 90°
#  PieM     Date 20150125 revision 0               
#ENDREM[/color][color=Black]###########################################[/color]

[color=Navy]#picaxe [/color][color=Black]20X2[/color]
[color=Gray]{[/color]
[color=Green]'*********** E/S ********************************
'entrées ------------------------------
'sorties ------------------------------
'*********** variables **************************[/color]
[color=Blue]symbol  [/color][color=Purple]Xmg       [/color][color=DarkCyan]= [/color][color=Purple]w1[/color]
[color=Blue]symbol  [/color][color=Purple]Ymg       [/color][color=DarkCyan]= [/color][color=Purple]w2[/color]
[color=Blue]symbol  [/color][color=Purple]Zmg       [/color][color=DarkCyan]= [/color][color=Purple]w3[/color]
[color=Blue]symbol  [/color][color=Purple]Angle_X   [/color][color=DarkCyan]= [/color][color=Purple]w4[/color]
[color=Blue]symbol  [/color][color=Purple]Angle_Y   [/color][color=DarkCyan]= [/color][color=Purple]w5[/color]
[color=Blue]symbol  [/color][color=Purple]Angle     [/color][color=DarkCyan]= [/color][color=Purple]w6[/color]

[color=Green]'reserve bits = b0 et b1
'*********** constantes **************************

'*********** memorisation en EEPROM **************
'eeprom  0,(0)

'*********** Macros ******************************[/color]
[color=Navy]#MACRO [/color][color=Black]Calc_angle[/color][color=Blue]([/color][color=Purple]Val_Axe[/color][color=Blue])
   [/color][color=Purple]Val_Axe [/color][color=DarkCyan]= [/color][color=Purple]Val_Axe[/color][color=DarkCyan]/[/color][color=Navy]16
   [/color][color=Blue]if [/color][color=Purple]Val_Axe [/color][color=DarkCyan]>= [/color][color=Navy]$800 [/color][color=Blue]then
      [/color][color=Purple]Val_Axe [/color][color=DarkCyan]= [/color][color=Navy]$1000 [/color][color=DarkCyan]- [/color][color=Purple]Val_Axe  [/color][color=Green]'valeur en mg
      [/color][color=Purple]Angle [/color][color=DarkCyan]= [/color][color=Purple]Val_Axe [/color][color=DarkCyan]*[/color][color=Navy]8[/color][color=DarkCyan]/[/color][color=Navy]125  
      [/color][color=Purple]Angle [/color][color=DarkCyan]= [/color][color=Navy]90 [/color][color=DarkCyan]- [/color][color=Purple]Angle [/color][color=DarkCyan]min [/color][color=Navy]40        [/color][color=Green]'valeur négatives de 40 à 90
   [/color][color=Blue]else
      [/color][color=Purple]Angle [/color][color=DarkCyan]= [/color][color=Purple]Val_Axe [/color][color=DarkCyan]*[/color][color=Navy]8[/color][color=DarkCyan]/[/color][color=Navy]125 [/color][color=DarkCyan]+ [/color][color=Navy]90 [/color][color=DarkCyan]max [/color][color=Navy]140  [/color][color=Green]'valeur positives de 90 à 140
   [/color][color=Blue]endif 
      [/color][color=Green]'erreur < 2° entre -50 +50° [/color]
[color=Navy]#ENDMACRO[/color]

[color=Green]'************  initialisation   *******************[/color]
[color=Blue]setfreq m8              [/color][color=Green]'fréquence [/color]
[color=Blue]hi2csetup i2cmaster [/color][color=Black],[/color][color=Navy]%00110000[/color][color=Black], [/color][color=Blue]i2cfast_8[/color][color=Black], [/color][color=Blue]i2cbyte
hi2cout [/color][color=Navy]$20[/color][color=Black],[/color][color=Blue]([/color][color=Navy]$27[/color][color=Blue])  [/color][color=Green]'activation[/color]
[color=Blue]hi2cout [/color][color=Navy]$23[/color][color=Black],[/color][color=Blue]([/color][color=Navy]$00[/color][color=Blue])  [/color][color=Green]'mode 2g[/color]
[color=Gray]}[/color]
[color=Green]'######################################################################
'|||||||||||||||||||||| Programme principal |||||||||||||||||||||||||||
'======================================================================[/color]

[color=Blue]do
   hi2cin [/color][color=Navy]$A8[/color][color=Black], [/color][color=Blue]([/color][color=Purple]b2[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b4[/color][color=Black],[/color][color=Purple]b5[/color][color=Black],[/color][color=Purple]b6[/color][color=Black],[/color][color=Purple]b7[/color][color=Blue])[/color][color=Green]' lecture des valeurs

   [/color][color=Black]Calc_angle[/color][color=Blue]([/color][color=Purple]Xmg[/color][color=Blue])
   [/color][color=Purple]Angle_X [/color][color=DarkCyan]= [/color][color=Purple]Angle

   [/color][color=Black]Calc_angle[/color][color=Blue]([/color][color=Purple]Ymg[/color][color=Blue])
   [/color][color=Purple]Angle_Y [/color][color=DarkCyan]= [/color][color=Purple]Angle

   [/color][color=Blue]sertxd ([/color][color=Red]" X: "[/color][color=Black], #[/color][color=Purple]Angle_X[/color][color=Black], [/color][color=Red]" Y: "[/color][color=Black], #[/color][color=Purple]Angle_Y[/color][color=Black], [/color][color=Blue]cr[/color][color=Black], [/color][color=Blue]lf)
   pause [/color][color=Navy]500[/color]
[color=Blue]loop[/color]
 

dje8269

Senior Member
Euhhhh ... comment dire !!! RESPECT !! .

Alors retour d'expérience .
les deux valeurs fonctionnent parfaitement . La plaque posée à plat sur la table les valeurs sont :
X: 90 Y: 86

avec x qui varie de 90 à 92 et Y qui varie de 84 à 86 .

Voici un échantillon .
Code:
 X: 91 Y: 85
 X: 91 Y: 84
 X: 91 Y: 86
 X: 90 Y: 85
 X: 91 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 91 Y: 84
 X: 91 Y: 86
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 91 Y: 85
 X: 90 Y: 85
 X: 91 Y: 85
 X: 91 Y: 85
 X: 90 Y: 85
 X: 91 Y: 85
 X: 91 Y: 85
 X: 90 Y: 86
 X: 90 Y: 84
 X: 91 Y: 84
 X: 90 Y: 85
 X: 90 Y: 85
 X: 91 Y: 85
 X: 91 Y: 85
 X: 91 Y: 85
 X: 90 Y: 85
 X: 91 Y: 85
 X: 90 Y: 84
 X: 91 Y: 85
 X: 91 Y: 86
 X: 91 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 85
 X: 90 Y: 84

J'ai tout de même un petit ressenti qui donne ,que vers le bas on atteint plus vite la valeur 40 ( l'angle est plus petit) alors que pour aller à 140 la plaque est presque a la verticale ; j'ai pas de quoi tester les angles .

Sinon un grand bravo .

quelques questions tout de même :

sans vouloir abusé de ton temps , serait - il possible d'agrémenter ton programme par quelques explications générales de ce que fait et a quoi servent chaque fonction( autres que les commentaires) . car la j'y comprends rien de rien, et ça me frustre . et je pense que je serais pas le seul ! ( enfin j'espère ... lol )

est ce qu'il est possible de diminuer les pauses ?

Pourquoi les valeurs sont lues a l'adresse 0xA8 , je ne trouve cela nulle part dans la DS

Les valeurs sont elles indépendantes les une des autres ? car je n'ai besoin de la valeur Y pour le hochement de tête , l'autre valeur sera donné par le magnétomètre normalement.
 
Last edited:

PieM

Senior Member
est ce qu'il est possible de diminuer les pauses ?
on met ce qu'on veut.

Pourquoi les valeurs sont lues a l'adresse 0xA8 , je ne trouve cela nulle part dans la DS
pour lire en une fois, il faut ajouter 1 en msb à l'adresse. on ajoute 128.

Les valeurs sont elles indépendantes les une des autres ? car je n'ai besoin de la valeur Y pour le hochement de tête , l'autre valeur sera donné par le magnétomètre normalement.
Oui elles sont inépendantes. on ne lit que Y si on n'a pas besoin du reste.
 

PieM

Senior Member
quelques explications générales de ce que fait et a quoi servent chaque fonction
d'après la doc:
les valeurs sont codées sur 12bits de -2048 à + 2047.
les valeurs négatives sont codées en complément à 2 (voir le net pour savoir ce que c'est)
la gamme de mesure est de +/- 2g donc à 2% près la mesure correspond à 1000 sin(angle)
entre 0 et 50° si on multiplie le sinus par 64 on obtient l'angle à 2° près
donc:
Val_Axe = Val_Axe/16 récupère les 12 msb
if Val_Axe >= $800 si la valeur est négative (complément à 2)
Val_Axe = $1000 - Val_Axe on decode la valeur positive
Angle = Val_Axe *8/125 c'est = à *64 / 1000 : c'est l'angle en degrés
on le soustrait à 90° qu'on a pris pour référence horizontale.
Si la valeur est positive (Val_Axe < $800) on calcule directement


Le calcul pour l'angle de boussole est beaucoup plus long car nécecessite:
un étalonnage , référence de la valeur de la composante horizontale du champ magnétique.
la détermination du quadrant dans lequel on se trouve;
faire le calcul de l'angle par rapport à X ou Y selon leurs valeurs relatives (approximation en f(sinus))
déterminer l'angle final

Sachant que non compensée, une boussole est fausse dès qu'elle est inclinée.
 

dje8269

Senior Member
Merci pour PieM , pour ces lignes d'explications . Tu te doute que les lignes de calcul sont un peu trop compliqués pour moi .

Toutefois j'ai une question , tu ne definie pas la valeur "Val_Axe" dans les symbols au départ . mais alors, ou est stockée cette variable ?

La conversion mg en angle est elle obligatoire . car dans mon cas de figure, il ne me faut pas un angle , mais une valeur comprise entre 100 et 200 . Donc plutôt de convertir la valeur absolue(mg) en angle, je pourrais peut être essayer de la convertir directement en valeur applicable a mon servo , cela me feras gagner une conversion ?

Le calcul pour l'angle de boussole est beaucoup plus long car nécecessite:
un étalonnage , référence de la valeur de la composante horizontale du champ magnétique.
la détermination du quadrant dans lequel on se trouve;
faire le calcul de l'angle par rapport à X ou Y selon leurs valeurs relatives (approximation en f(sinus))
déterminer l'angle final

Sachant que non compensée, une boussole est fausse dès qu'elle est inclinée.
Donc il faut absolument que je change de module . ca ne sert a rien que je m'embête , et par la même vous aussi avec celui ci
 

PieM

Senior Member
Val_Axe est un paramètre de la macro. C'est différent d'une variable déclarée.
c'est remplacé par Xmg ou Ymg lors de la compil.

Remplace les 90 par 150 avec le mini à 100 et le maxi à 200 et tu auras les valeurs que tu veux entre 100 et 200.
 

BESQUEUT

Senior Member
@dje : un servo est bel et bien commandé en angle, même si ce dernier n'est pas exprimé en degrés.
Si les valeurs entre 100 et 200 correspondent à une course de 0 à 180° pour le servo, il n'y aura pas correspondance entre l'inclinaison de la tête et le servo.
Attention : ce programme ne marche qu'entre -50 et +50°
Pour aller au delà, il faut faire un peu ce qui est proposé pour la boussole : déterminer le bon quadrant et la bonne approximation.
 
Top