Go Down

Topic: détection d'objet avec un magnétomètre (Read 521 times) previous topic - next topic

1777

Mar 31, 2018, 07:13 pm Last Edit: Mar 31, 2018, 07:25 pm by 1777
salut
j'ai pour projet de réussir à détecter un objet avec un magnetometre (le mag3110 de chez sparkfun)
le code si dessous me permet d'avoir 3 valeur dans le port série x, y et z
j'ai appliqué cette formule
 
pour pouvoir réunir c'est 3 valeur en une seule que j'ai appelé xyz
Code: [Select]
xyz = sqr ( pow(xMag,2) +   ( pow(yMag,2) +   ( pow(zMag,2) );
  Serial.println(xyz);
 

cette valeur représente le champ magnétique ambiant
mon problème maintenant c'est que xyz = le champ magnétique ambiant
sauf que du coup cette valeur varie déjà juste par rapport à l'endroit où je pose mon capteur ce qui fait que je peut pas faire un truc du style si xyz = "tant" alors mon objet est présent  pcq xyz aura pas la même valeur de par rapport à où mon système est posé.
apparemment je doit  calibrer mon capteur pour qu'il ne capte plus que le champ magnétique de mon objet  qui ne correspond pas au champ magnétique ambiant de départ ( sans mon objet ) si j'ai bien compris .
ps : je dois pouvoir savoir si mon objet est présent où pas
comment faire ? svp

Code: [Select]

#include<Wire.h>
#define adresse 0x0E

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Wire.beginTransmission(adresse);
  Wire.write(0x10);
  Wire.write(0x01);
  Wire.endTransmission();
  delay(300);
}

void loop()
{
  unsigned int donnees[6];
 
  Wire.beginTransmission(adresse);
  Wire.write(0x01);
  Wire.endTransmission();
  Wire.requestFrom(adresse, 6);

  if(Wire.available() == 6)
  {
    donnees[0] = Wire.read();
    donnees[1] = Wire.read();
    donnees[2] = Wire.read();
    donnees[3] = Wire.read();
    donnees[4] = Wire.read();
    donnees[5] = Wire.read();
  }
 
  int xMag = ((donnees[1] * 256) + donnees[0]);
  int yMag = ((donnees[3] * 256) + donnees[2]);
  int zMag = ((donnees[5] * 256) + donnees[4]);
   
  Serial.print("Champ magnetique dans l'axe X : ");
  Serial.println(xMag);
  Serial.print("Champ magnetique dans l'axe Y : ");
  Serial.println(yMag);
  Serial.print("Champ magnetique dans l'axe Z : ");
  Serial.println(zMag);
 
  xyz = sqr ( pow(xMag,2) +   ( pow(yMag,2) +   ( pow(zMag,2) );
  Serial.println(xyz);
 
delay(1000);
 

Christian_R

Faire une mesure statique du module du champ, et soustraire cette valeur aux mesures suivantes.
Christian

biggil

à la place de pow(xMag,2), tu mets xMag*xMag , c'est beaucoup plus efficace !

1777

à la place de pow(xMag,2), tu mets xMag*xMag , c'est beaucoup plus efficace !
peut etre mais quand j'ai fais ça dans le moniiteur  serie ça m'affichait parfois "nan not a number" et la avec les pow ça me le fais pas

biggil

peut etre mais quand j'ai fais ça dans le moniiteur  serie ça m'affichait parfois "nan not a number" et la avec les pow ça me le fais pas
Si le résultat de x*x n'est pas égal à pow(x,2), tu as un problème de dimensionnement de tes variables !
tu utilises quoi, des floats ? des ints ? des longs ?

1777

Si le résultat de x*x n'est pas égal à pow(x,2), tu as un problème de dimensionnement de tes variables !
tu utilises quoi, des floats ? des ints ? des longs ?
Code: [Select]
#include <Wire.h>
#define  adresse 0x0E

int xyz_initial = -1;
int xyz;
unsigned int donnees [6];
int xMag;
int yMag;
int zMag;

void setup()
{
Wire.begin ();
Serial.begin (9600);
Wire.beginTransmission (adresse);
Wire.write (0x10);
Wire.write (0x01);
Wire.endTransmission ();
delay(300);
}

void loop ()
{

Wire.beginTransmission (adresse);
Wire.write (0x01);
Wire.endTransmission ();
Wire.requestFrom (adresse, 6);

if (Wire.available () == 6)
{
donnees [0] = Wire.read ();
donnees [1] = Wire.read ();
donnees [2] = Wire.read ();
donnees [3] = Wire.read ();
donnees [4] = Wire.read ();
donnees [5] = Wire.read ();

xMag = ((donnees [1] * 256) + donnees [0]);
yMag = ((donnees [3] * 256) + donnees [2]);
zMag = ((donnees [5] * 256) + donnees [4]);

Serial.print( "Champ magnetique Dans l'axe X:");
Serial.println(xMag);
Serial.print( "Champ magnetique Dans l'axe Y:");
Serial.println(yMag);
Serial.print( "Champ magnetique Dans l'axe Z:");
Serial.println(zMag);

xyz = sqrt(pow(xMag, 2)+pow(yMag, 2)+pow(zMag, 2));
Serial.println(xyz);

if(xyz_initial == -1)
xyz_initial = xyz;

if(xyz_initial * 1.1 <xyz)
Serial.println( "voiture presente");
else
Serial.println( "voiture non présent");

}

delay(1000);

}

biggil

#6
Apr 04, 2018, 07:51 am Last Edit: Apr 04, 2018, 07:52 am by biggil
Code: [Select]
int xMag;
int yMag;
int zMag;


la valeur d'un int est limitée à la plage [ -32768, +32767 ].
Quand le compilateur voit le produit de 2 int ( xMag*xMag ), il place le résultat dans un int, et des fois, ça déborde !
Donc au minimum, il faut déclarer tes variables comme des long.

Maintenant, pour être cohérent avec le problème à résoudre, où xmag ymag et zmag sont des nombres réels, if faut encore mieux les déclarer comme des float.

Il est très courant que les débutants confondent le type d'une info avec sa représentation:
- le type est réel pour une grandeur physique (une distance, une masse, une accéleration..) et entier pour un comptage ( le nombre d'enfants, la taille d'un texte...)
- la représentation peur être un int, un long, un float, un bool, un double. C'est la cuisine interne du programme. Il faut choisir avec soin.


Go Up