détection d'objet avec un magnétomètre

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

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

#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);

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

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

biggil:
à 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

1777:
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 ?

biggil:
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 ?

#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); 

}
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.