lire un accelerometre

Bonjour,

Je travaille sur un projet d'étude qui utilise l'accelerometre memsic 2125. Pour lire les valeurs qu'il retourne j'utilise le code d'exemple proposé sur cette page : http://www.arduino.cc/en/Tutorial/AccelerometerMemsic2125.
Il fonctionne parfaitement mais il y a une partie du code que je ne comprend pas :

value = digitalRead(axe);
while(value == HIGH) { // Loop until pin reads a low
value = digitalRead(axe);
}
while(value == LOW) { // Loop until pin reads a high
value = digitalRead(axe);
}
while(value == HIGH) { // Loop until pin reads a low and count
value = digitalRead(axe);
count = count + 1;
}

Je comprend la 3e boucle while (on mesure la durée pendant laquelle la valeur est HIGH), mais à quoi servent les deux précédentes boucles ? D'ailleurs lorsque l'on supprime ces boucles cela ne fonctionne plus...

C'est juste pour essayer de comprendre les scripts que j'utilise. Si quelqu'un à la réponse... :wink:

Merci :slight_smile:

Bonjour Couac,

Je n'ai pas utilisé ce model d'acceleromètre, mais je pense que la raison est la suivante :

Le signal ressemble à ça :
_ _
| || |_

Puisque tu veux mesurer combien de temps le signal reste a l'état haut, tu dois être sur de commencer à compter juste quand le signal change d'état (Sinon tu pourrais commencer à compter en plein milieu d'un état haut). Pour cela, tu dois attendre un état bas, puis attendre l'état haut, puis compter jusqu'a l'état bas.

Est-ce que cela aide ?

Lionel.

Merci beaucoup lionel, ça y'es j'ai compris :slight_smile:

C'est encore moi :slight_smile:

Pour simplifier le code j'ai voulu essayer d'utiliser la fonction pulseIn, qui devrai compter la même manière que le code ci dessus non ? Mais les valleurs renvoyées ne sont pas cohérentes.

/*
Lire le retour de l'accelerometre avec la fonction pulseIn intégré
*/

int xPin = 2;      //  x-axis input
int yPin = 3;      //  y-axis input

unsigned long xDuration;
unsigned long yDuration;

void setup() {
  beginSerial(9600);
  pinMode(xPin, INPUT);
  pinMode(yPin, INPUT);
}

void loop(){
  
  yDuration = pulseIn(yPin, HIGH);
  xDuration = pulseIn(xPin, HIGH);

  serialWrite('Y');
  serialWrite('-');
  printInteger(yDuration);
  printByte(10);
  
  serialWrite('X');
  serialWrite('-');
  printInteger(xDuration);
  printByte(10);
  
}

Merci pour votre aide.

Quelles sont les valeurs recues ? pulseIn retourne le temps en microsecondes. Le code original retourne le temps converti en valeur entre -500 et 500. Est-ce que tu as converti les valeurs ?

Pour convertir, j'utiliserai surement une calibration de ce genre:

int iRange = 1024;
int iLeft = ;
int iRight = ;

int iValue = pulseIn( pinId );
iValue = ( iValue - iLeft ) * iRange / ( iRight - iLeft ) - iRange / 2;

Ce qui retourne une valeur entre -512 et 512.

Pour initialiser la calibration (trouver les valeurs de iLeft et iRight), affiche la valeur retournée par pulseIn(). Penche l'accelerometer a gauche, note la valeure. Penche a droite, note la valeur. Voila, utilise les valeurs dans le code.

HTH,
Lionel.

Bonjour, j'aimerais simplement savoir si ma démarche pour utiliser un accéléromètre est adéquate(un LIS3LV02DQ). J'obtiens une valeur en hexadécimale de 0480 pour l'axe des Z, 0096 pour l'axe des X et 0032 pour l'axe des Y au repos. J'aurais cru que la valeur des x et des y devraient être semblable au repos, il s'agit peut-etre de faire un ajustement au niveau du offset, mais je ne suis pas sur. J'aimerais aussi savoir si je serais capable de faire une échelle pour pouvoir convertir mes valeurs hexadécimale en force 'g'.

Voici mon programme:

#include <18F2515.h>
#include <stdlib.h>
#use delay(clock=8000000)
#use I2C(master, sda = PIN_C4, scl = PIN_C3)
#use RS232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)


void main(void)
{
int xH, xL, yH, yL, zH, zL;
long int tab[6][250];
long int i;
setup_oscillator(OSC_8MHZ);

//set_tris_c(0x80); 
puts("Bonjour");

for (i=0;i<230;i++) 
{
//output_toggle(PIN_A0);
//delay_ms(250);

//debut d affichage
i2c_start();
i2c_write(0x3A); //début d'écriture
i2c_write(0x20); //écriture dans le premier registre
i2c_write(0xC7); //mode-on
i2c_stop();

i2c_start();
i2c_write(0x3A);
i2c_write(0x21);//écriture dans le second registre
i2c_write(0x00);//Full Scale selection:+-2g; Big Endian; Data Alignment Selection: 12 bit right justified
i2c_stop();

i2c_start();
i2c_write(0x3A);//adresse du 
i2c_write(0x28);//adresse du de la lecture
i2c_start();
i2c_write(0x3B);//mode lecture du LIS3LV02DQ
xL = i2c_read(0);//le i2c va lire l'axe des x
i2c_stop();

i2c_start();
i2c_write(0x3A);//adresse du 
i2c_write(0x29);//adresse du de la lecture
i2c_start();
i2c_write(0x3B);//mode lecture du LIS3LV02DQ
xH = i2c_read(0);//le i2c va lire l'axe des x
i2c_stop();

i2c_start();
i2c_write(0x3A); //adresse du 
i2c_write(0x2A); //adresse du de la lecture
i2c_start();
i2c_write(0x3B); //mode lecture du LIS3LV02DQ
yL = i2c_read(0); //le i2c va lire l'axe des y
i2c_stop();

i2c_start();
i2c_write(0x3A); //adresse du 
i2c_write(0x2B); //adresse du de la lecture
i2c_start();
i2c_write(0x3B); //mode lecture du LIS3LV02DQ
yH = i2c_read(0); //le i2c va lire l'axe des y
i2c_stop();

i2c_start();
i2c_write(0x3A); //adresse du 
i2c_write(0x2C); //adresse du de la lecture
i2c_start();
i2c_write(0x3B); //mode lecture du LIS3LV02DQ
zL = i2c_read(0); //le i2c va lire l'axe des z
i2c_stop();

i2c_start();
i2c_write(0x3A); //adresse du 
i2c_write(0x2D); //adresse du de la lecture
i2c_start();
i2c_write(0x3B); //mode lecture du LIS3LV02DQ
zH = i2c_read(0); //le i2c va lire l'axe des z
i2c_stop();


tab[0][i]=xL;
tab[1][i]=xH;
tab[2][i]=yL;
tab[3][i]=yH;
tab[4][i]=zL;
tab[5][i]=zH;

printf("\n\r %x xL %x xH %x yL %x yH %x zL %x zH %ld",tab[0][i],tab[1][i],tab[2][i],tab[3][i],tab[4][i],tab[5][i], i); );//affiche les X, Y, Z sur l'hyperterminal
delay_ms(25);
}
}

Merci pour votre aide.

bonjour, je suis nouveau ici et m'interesse de tres pres à cet accélèrometre car je pense l'utiliser pour stabiliser un hélicoptère télécommandé...
Seulement, pour communiquer avec ce composant via un PIC, j'ai rencontré un problème d'alimentation et de niveau de tension sur les broches de communication... mon PIC tourne sur 5v et l'ccéléro à 2.5v avec 2 resistances de rappel de 330ohms je crois et toi tu fais comment?
Pour les différences de mesures que tu as sur les axes, au repos, il faut effectivement lui rajouter de l'offset cf doc.... cela parait normal mais doit etre fait à chaque utilisation je pense.
Apres, tu n'as plus qu'à convertir tes données en ce que tu veux.

En fait, j'utilise un PIC 18F2515, alors je peux l'alimenter à 2.5v. De ce fait, je n'ai pas besoin de jouer dans les registres pour ajuster les offset ou les gains pour l'axe des z. J'ai finalement décidé de me concentrer sur un seul axe pour l'instant.

Néanmoins, il me reste encore une partie à comprendre pour réaliser mon projet. Je dois réussir à déchiffrer le code hexadécimale que j'obtiens à la lecture de l'accéléromètre avec labview ou hyperterminal pour ensuite l'interpréter en force g, puis en accélération, la vitesse et finalement la distance parcourue.

Toutefois, j'ai remarqué que la valeure observée diminue lorsque l'accéléromètre est en montée, tandis qu'en descente elle augmente, et il faut tenir compte que la valeure initiale est d'environ 400-40a(1024-1034). Alors dois-je comprendre que l'échelle est inversée?

Plutot bizard que les valeurs en Z soient opposées... A vrai dire ça fait un bout de temps que je ne m'y suis pas interessé.