Probleme avec un capteur de pression

Les cartes Arduino, les platines

Probleme avec un capteur de pression

Message non lude xezi » Mar 18 Mar 2014 14:42

Bonjour,

voila dans le cadre d'un projet j'ai été en charge du capteur BMP085, un altimètre permettant de relever la pression atmosphérique pour y déterminer l'altitude. Le programme fonction bien, la pression change sans arrêt. Pour plus de précision je dois relever 10 fois la valeur de la pression, en faire une moyenne et l'afficher .
Mais étant débutant je ne sais pas comment faire ...
Je sollicite un peu d'aide !

voici le programme:

#include <Wire.h>

//L'adresse I2C du BMP085
#define BMP085_ADDRESS 0x77

// Lit 1 byte du BMP085 à 'address'
char bmp085ReadChar(unsigned char address)
{
unsigned char data;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();

Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available());

return Wire.read();
}

// Lit 2 bytes sur le BMP085
// Le premier byte vient de 'address'
// Le second byte vient de 'address'+1
int bmp085ReadInt(unsigned char address)
{
unsigned char msb, lsb;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();

//on va lire 2 bytes, correspondant à un integer
Wire.requestFrom(BMP085_ADDRESS, 2);

//Attendons que les 2 bytes soient arrivés...
while(Wire.available()<2);
msb = Wire.read();
lsb = Wire.read();

return (int) msb<<8 | lsb;
}

const unsigned char OSS = 0;

// Valeurs de calibration
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

// b5 est calculé dans bmp085GetTemperature(...),
// et est aussi utilisée dans bmp085GetPressure(...)
// donc ...Temperature(...) doit être appelée avant ...Pressure(...).
long b5;

short temperature;
long pressure;

// Stocke toutes les valeurs de calibration du BMP085 dans des variables globales.
// Ces valeurs sont nécessaires pour calculer la température et la pression.
// Cette fonction doit être appelée au début du programme.
void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}
void setup()
{
Serial.begin(9600);
Wire.begin();
bmp085Calibration();
}


// Lit la température non compensée
unsigned int bmp085ReadUT()
{
int ut;

// Ecrit 0x2E dans le registre 0xF4.
// Cela demande une lecture de température.
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();

// Attendons au moins 4.5ms
delay(5);

// Lit les 2 octets des registres 0xF6 et 0xF7
ut = bmp085ReadInt(0xF6);
return ut;
}

// Lit la pression non compensée
unsigned long bmp085ReadUP()
{
unsigned char msb, lsb, xlsb;
unsigned long up = 0;

// Ecrit 0x34 + (OSS<<6) dans le registre 0xF4 pour
// demander une lecture de la pression avec le paramètre d'oversampling
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();

// Attend la fin de conversion, le délai dépend de OSS
delay(2 + (3 << OSS));

// Lit la réponse dans les registres :
// 0xF6 (MSB), 0xF7 (LSB), et 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 3);

// Attend aue les données soient dispo (3 bytes)
while(Wire.available() < 3);

msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();

up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);

return up;
}


// Calcule la température à partir de ut.
// La valeur de sortie est exprimée en dixièmes de degrés.
short bmp085GetTemperature( int ut)
{
long x1, x2;

x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc << 11)/(x1 + md);
b5 = x1 + x2;

return ((b5 + 8)>>4);
}

// Calcule la pression à partir de up.
// Les valeurs de calibration doivent être initialisées.
// b5 est aussi requise, donc bmp085GetTemperature(...) doit être appelée en premier.
// La valeur de sortie est exprimée en Pascals.
long bmp085GetPressure(unsigned long up)
{
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;

b6 = b5 - 4000;
// Calcule B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

// Calcule B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

b7 = ((unsigned long)(up - b3) * (50000>>OSS));
if (b7 < 0x80000000)
p = (b7<<1)/b4;
else
p = (b7/b4)<<1;

x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;

return p;
}

//Retourne l'altitude théorique
//en fonction de la pression atmosphérique
float getAltitude(long pressure)
{
// Pression au niveau de la mer (Pa)
const float p0 = 101325;
float altitude = (float)44330 * (1 - pow(((float) pressure/p0), 0.190295));
return altitude;
}



//Calculons tout ça dans la boucle principale, et envoyons les résultats dans le port série:

void loop()
{
temperature = bmp085GetTemperature(bmp085ReadUT());
pressure = bmp085GetPressure(bmp085ReadUP());
float altitude = getAltitude(pressure);

Serial.println("***********************");
Serial.print("Temperature: ");
Serial.print(((float)temperature / 10), 1);
Serial.println(" degres");

Serial.print("Pression: ");
Serial.print(pressure, DEC);
Serial.println(" Pascals");

Serial.print("Altitude: ");
Serial.print((int)altitude, DEC);
Serial.println(" metres");

delay(1000);
}

La partie qui m'interresse est donc dans la fonction loop

J'ai essayé ceci : Les modification sont en bleu

void loop()
{
temperature = bmp085GetTemperature(bmp085ReadUT());
pressure = bmp085GetPressure(bmp085ReadUP());
float altitude = getAltitude(pressure);
int i;
int somme = 0; // tableau contenant les valeurs de pression
int valeurmoy = 0;

for (i=0;i<10;i++)
{
Wire.beginTransmission(BMP085_ADDRESS);
somme = somme + bmp085GetPressure(bmp085ReadUP()); //il va lire ,renvoi une valeur, cette valeur va etre ajouter a somme
Wire.endTransmission();

}

valeurmoy =somme/10;

Serial.println("***********************");
Serial.print("Temperature: ");
Serial.print(((float)temperature / 10),0);
Serial.println("degres");

Serial.print("Pression: ");
Serial.print(valeurmoy, DEC);
Serial.println("Pascals");

Serial.print("Altitude: ");
Serial.print((int)altitude, DEC);
Serial.println(" metres");

delay(1000);
}

Mais cela ne fonctionne tjrs pas !!! HELP :(
xezi
 
Messages: 2
Inscription: Mar 18 Mar 2014 14:37

Re: Probleme avec un capteur de pression

Message non lude Bemolu » Jeu 20 Mar 2014 22:45

xezi a écrit:void loop()
{
temperature = bmp085GetTemperature(bmp085ReadUT());
pressure = bmp085GetPressure(bmp085ReadUP());
float altitude = getAltitude(pressure);
int i;
int somme = 0; // tableau contenant les valeurs de pression
int valeurmoy = 0;

for (i=0;i<10;i++)
{ [...]
somme = somme + bmp085GetPressure(bmp085ReadUP()); //il va lire ,renvoi une valeur, cette valeur va etre ajouter a somme
} [...]
valeurmoy =somme/10;

Serial.print(valeurmoy, DEC);
}
Mais cela ne fonctionne tjrs pas !!!


Bonsoir
Commence par utiliser des unsigned long (32 bits pour autant que je me souvienne) à la place des int (8 bits) pour i, somme et valeurmoy. Si ton problème persiste, sois plus précis en décrivant sur ce que tu reçois par rapport à ce tu attends.
Cordialement
Bemolu
 
Messages: 63
Inscription: Mer 8 Fév 2012 21:19

Re: Probleme avec un capteur de pression

Message non lude xezi » Ven 21 Mar 2014 15:06

Merciiiii c'était simplement ca ... dégouté mais content !

Mais j'ai un autre soucis maintenant, mon projet donc est une nacelle pour photographier des paysages avec un appareil photo situé dans les aires avec mon capteur et une tablette en bas pour controler tout ca.
Mon role est de relevé l'altitude du ballon par rapport a ma position au sol. Le truc c'est que mon programme mesure l'altitude par rapport au niveau de la mer. Donc dans l'idéal ça serait (lors de la calibration) enregistrer l'altitude par rapport au niveau de la mer par rapport a ma position au dessus de la mer et ensuite soustraire cette altitude là à l'altitude mesurée au fur et à mesure que le ballon monte .

et je ne sais pas comment procéder. Mon capteur est un BMP085 et voici son programme:


#include <Wire.h>

//L'adresse I2C du BMP085
#define BMP085_ADDRESS 0x77

// Lit 1 byte du BMP085 à 'address'
char bmp085ReadChar(unsigned char address)
{
unsigned char data;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();

Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available());

return Wire.read();
}

// Lit 2 bytes sur le BMP085
// Le premier byte vient de 'address'
// Le second byte vient de 'address'+1
int bmp085ReadInt(unsigned char address)
{
unsigned char msb, lsb;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();

//on va lire 2 bytes, correspondant à un integer
Wire.requestFrom(BMP085_ADDRESS, 2);

//Attendons que les 2 bytes soient arrivés...
while(Wire.available()<2);
msb = Wire.read();
lsb = Wire.read();

return (int) msb<<8 | lsb;
}
/*Nous sommes à présent capables de lire des valeurs du module.
Cool! On va en avoir besoin pour lire les 11 coefficients de calibration, stockés dans l’EEPROM du BMP085.
Ces valeurs vont nous permettre de calculer la pression absolue. Il suffit de les lire une seule fois, au début du programme.
Nous allons les mettre dans la fonction setup()
paramètre d'oversampling 0 à 3,
qui permet d'avoir plus de précision dans les mesures*/
const unsigned char OSS = 0;

// Valeurs de calibration
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

// b5 est calculé dans bmp085GetTemperature(...),
// et est aussi utilisée dans bmp085GetPressure(...)
// donc ...Temperature(...) doit être appelée avant ...Pressure(...).
long b5;

short temperature;
long pressure;

// Stocke toutes les valeurs de calibration du BMP085 dans des variables globales.
// Ces valeurs sont nécessaires pour calculer la température et la pression.
// Cette fonction doit être appelée au début du programme.
void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}

// Déclaration du tableau qui va nous permettre de stocker les valeurs pour effectuer la moyenne des mesures.
unsigned long somme = 0; // tableau contenant les valeurs de pression
unsigned long valeurmoy=0;
unsigned long i;
void setup()

{
Serial.begin(9600);
Wire.begin();
bmp085Calibration();
}
/*Une fois que les valeurs de calibration sont lues, il nous faut encore deux variables pour calculer la température et la pression : ut et up.
Ce sont les valeurs de température et pression non compensées, notre point de départ pour déterminer les valeurs réelles de température et pression.
A chaque fois qu’on veut obtenit la température ou la pression, il faut lire au préalable ces valeurs.
La température non compensée est sur 16 bits (type int), la pression sur 32 bits (type long).*/

// Lit la température non compensée
unsigned int bmp085ReadUT()
{
int ut;

// Ecrit 0x2E dans le registre 0xF4.
// Cela demande une lecture de température.
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();

// Attendons au moins 4.5ms
delay(5);

// Lit les 2 octets des registres 0xF6 et 0xF7
ut = bmp085ReadInt(0xF6);
return ut;
}

// Lit la pression non compensée
unsigned long bmp085ReadUP()
{
unsigned char msb, lsb, xlsb;
unsigned long up = 0;

// Ecrit 0x34 + (OSS<<6) dans le registre 0xF4 pour
// demander une lecture de la pression avec le paramètre d'oversampling
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();

// Attend la fin de conversion, le délai dépend de OSS
delay(2 + (3 << OSS));

// Lit la réponse dans les registres :
// 0xF6 (MSB), 0xF7 (LSB), et 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 3);

// Attend aue les données soient dispo (3 bytes)
while(Wire.available() < 3);

msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();

up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);

return up;
}
/*Dans ces deux fonctions, nous utilisons la fonction delay() pour laisser le temps au BMP085 de terminer ses traitements.
Le paramètre d’oversampling (OSS) indique au capteur de calculer une moyenne de plusieurs mesures, afin d’avoir une précision accrue. Ici, il est désactivé.
La durée d’attente est le maximum indiqué dans le datasheet du module,
mais nous pourrions à la place nous baser sur le pin EOC (End Of Conversion) pour connaitre avec précision le moment où le BMP05 a terminé de lire les données.
Tant qu’il travaille, le pin EOC est à l’état LOW, et dès qu’il a terminé, il passe à HIGH.

Nous avons toutes les variables requises pour calculer la température et la pression. Dans le datasheet, une formule assez cool nous donne la température,
et une autre, beaucoup, beaucoup plus barbue, nous donne la pression.
Merci à Jimbo, chez Sparkfun, d’avoir transcrit tout ça en C, ça fait vraiment plaisir :)*/

// Calcule la température à partir de ut.
// La valeur de sortie est exprimée en dixièmes de degrés.
short bmp085GetTemperature( int ut)
{
long x1, x2;

x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc << 11)/(x1 + md);
b5 = x1 + x2;

return ((b5 + 8)>>4);
}

// Calcule la pression à partir de up.
// Les valeurs de calibration doivent être initialisées.
// b5 est aussi requise, donc bmp085GetTemperature(...) doit être appelée en premier.
// La valeur de sortie est exprimée en Pascals.
long bmp085GetPressure(unsigned long up)
{
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;

b6 = b5 - 4000;
// Calcule B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

// Calcule B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

b7 = ((unsigned long)(up - b3) * (50000>>OSS));
if (b7 < 0x80000000)
p = (b7<<1)/b4;
else
p = (b7/b4)<<1;

x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;

return p;
}
//Bon alors là, on est pas mal ! Encore une fonction pour calculer l’altitude à partir de la pression :

//Retourne l'altitude théorique
//en fonction de la pression atmosphérique
float getAltitude(long pressure)
{
// Pression au niveau de la mer (Pa)
const float p0 = 101325;
float altitude = (((float)44330 * (1 - pow(((float) pressure/p0), 0.190295)))-25);
return altitude;
}

//Calculons tout ça dans la boucle principale, et envoyons les résultats dans le port série:

void loop()
{
temperature = bmp085GetTemperature(bmp085ReadUT());
pressure = bmp085GetPressure(bmp085ReadUP());
float altitude = getAltitude(pressure);
unsigned long somme = 0; // tableau contenant les valeurs de pression
unsigned long valeurmoy=0;

for(i=0;i<31;i++)

{
Wire.beginTransmission(BMP085_ADDRESS);
somme = somme + bmp085GetPressure(bmp085ReadUP());
Wire.endTransmission();
}

valeurmoy = somme /30;


Serial.println("***********************");
Serial.print("Temperature: ");
Serial.print(((float)temperature / 10),0);
Serial.println("degres");

Serial.print("Pression: ");
Serial.print(valeurmoy, DEC);
Serial.println("Pascals");

Serial.print("Altitude: ");
Serial.print((int)altitude, DEC);
Serial.println(" metres");

delay(1000);
}
xezi
 
Messages: 2
Inscription: Mar 18 Mar 2014 14:37


Retourner vers Arduino

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 2 invités

cron