Modulo sensor de presión y
temperatura BMP085 de la firma BOSCH.
Este es un sensor de prestaciones
hogareñas, ya que los límites de presión y temperatura son estándar como para
una estación meteorológica.
La presión a medir va de
30kPa a 110kPa
La altura (por conversión)
es de -500m a 9000m
Bueno son algunos datos, la
realidad es que si se quiere ver en detalle pueden descargar el datasheet donde
encontraran una extensa cantidad de datos sobre este sensor.
El protocolo de comunicación
es I2C, en este caso se aprovecha el puerto I2C del microcontrolador de forma
nativa.
En nuestro ejemplo se ha
utilizado un display de LCD pero es posible usar cualquier otra interfase de visualización.
El diagrama de bloques del
programa esta detallado en el Datasheet del sensor, para aquellos que no les
gusta programar van a tener un poco de problemas ya que Bosch decidió utilizar
11 variables de calibración, que deben calcularse en tiempo real para lograr
una representación de la presión.
De todas formas esta todo escrito
en el datasheet, las variables, los cálculos, la forma de leer este sensor, los
bytes a enviar para accederlo y demás.
Circuito:
Calibración:
Algoritmo y Cálculos:
Programa:
Nótese que en la rutina de inicialización las variables que poseen una x minúscula son los resultados de los cálculos que se piden en el cuadro de arriba, pero los mismos están directamente como constante, esto se debe a que el hardware del microcontrolador utilizado queda corto para la cantidad de memoria necesaria para realizar todos los cálculos, por ende se han puesto solo los resultados, esto quita exactitud.
Si se utiliza un microcontrolador más potente sería recomendable utilizar los cálculos para que la exactitud sea óptima.
Para ampliar la exactitud debe reemplazar el bloque:
Nótese que en la rutina de inicialización las variables que poseen una x minúscula son los resultados de los cálculos que se piden en el cuadro de arriba, pero los mismos están directamente como constante, esto se debe a que el hardware del microcontrolador utilizado queda corto para la cantidad de memoria necesaria para realizar todos los cálculos, por ende se han puesto solo los resultados, esto quita exactitud.
Si se utiliza un microcontrolador más potente sería recomendable utilizar los cálculos para que la exactitud sea óptima.
Para ampliar la exactitud debe reemplazar el bloque:
xC3 = 0.00489*AC3;
xC4 = 0.0000000306*AC4;
xC5 = 0.000000191*AC5;
xC6 = (float)AC6;
xB1 = 0.0000238*B1;
xMc = 0.0812*MC;
xMd = (float)MD/160;
xX1 = (float)AC1;
xX2 = 0.0195*AC2;
xX3 = 0.000763*B2;
xY1 = xC4*32768;
xY2 = xC4*xC3;
xY3 = xC4*xB1;
por el bloque:
xC3 = 160*pow(2,-15)*AC3;
xC4 = pow(1,-3)*pow(2,-15)*AC4;
xC5 = (pow(2,-15)/160)*AC5;
xC6 = (float)AC6;
xB1 = pow(160,2)*pow(2,-30)*B1;
xMc = (pow(2,11)/25600)*MC;
xMd = (float)MD/160;
xX1 = (float)AC1;
xX2 = 160*pow(2,-13)*AC2;
xX3 = pow(160,2)*pow(2,-25)*B2;
xY1 = xC4*pow(2,15);
xY2 = xC4*xC3;
xY3 = xC4*xB1;
y debe incluir la librería math.h, esto requiere de un microcontrolador mas potente.
por el bloque:
xC3 = 160*pow(2,-15)*AC3;
xC4 = pow(1,-3)*pow(2,-15)*AC4;
xC5 = (pow(2,-15)/160)*AC5;
xC6 = (float)AC6;
xB1 = pow(160,2)*pow(2,-30)*B1;
xMc = (pow(2,11)/25600)*MC;
xMd = (float)MD/160;
xX1 = (float)AC1;
xX2 = 160*pow(2,-13)*AC2;
xX3 = pow(160,2)*pow(2,-25)*B2;
xY1 = xC4*pow(2,15);
xY2 = xC4*xC3;
xY3 = xC4*xB1;
y debe incluir la librería math.h, esto requiere de un microcontrolador mas potente.
#include
<16F883.h>
#use
delay(int=4000000)
#use
i2c(master,sda=PIN_C4,scl=PIN_C3,FAST,FORCE_HW)
#include
<lcd.c>
signed
int16 AC1, AC2, AC3, B1, B2, MC, MD, MB;
int16
AC4, AC5, AC6;
float
xC3, xC4, xB1, xC5, xC6, xMc, xMd, xX1, xX2;
float
xY2, xY3, xS, xX3, xY1;
int8
DescargaByte_BMP085(int8 address){
int8 datos;
i2c_Start();
i2c_write(0xEE);
i2c_write(address);
i2c_Start();
i2c_write(0xEE|0x01);
datos=i2c_read(0);
i2c_Stop();
return(datos);
}
int16
DescargaEntero_BMP085(int8 address){
int16 ent;
i2c_Start();
i2c_write(0xEE);
i2c_write(address);
i2c_Start();
i2c_write(0xEE|0x01);
ent=make16(i2c_read(),i2c_read(0));
i2c_Stop();
return(ent);
}
void
inicializa_BMP085(){
AC1 = DescargaEntero_BMP085(0xAA);
AC2 = DescargaEntero_BMP085(0xAC);
AC3 = DescargaEntero_BMP085(0xAE);
AC4 = DescargaEntero_BMP085(0xB0);
AC5 = DescargaEntero_BMP085(0xB2);
AC6 = DescargaEntero_BMP085(0xB4);
B1 = DescargaEntero_BMP085(0xB6);
B2 =
DescargaEntero_BMP085(0xB8);
MB =
DescargaEntero_BMP085(0xBA);
MC =
DescargaEntero_BMP085(0xBC);
MD =
DescargaEntero_BMP085(0xBE);
xC3 = 0.00489*AC3;
xC4 = 0.0000000306*AC4;
xC5 = 0.000000191*AC5;
xC6 = (float)AC6;
xB1 = 0.0000238*B1;
xMc = 0.0812*MC;
xMd = (float)MD/160;
xX1 = (float)AC1;
xX2 = 0.0195*AC2;
xX3 = 0.000763*B2;
xY1 = xC4*32768;
xY2 = xC4*xC3;
xY3 = xC4*xB1;
}
int16
DescargaTemp_BMP085(){
i2c_Start();
i2c_write(0xEE);
i2c_write(0xF4);
i2c_write(0x2E);
i2c_Stop();
delay_ms(5);
return((float)DescargaEntero_BMP085(0xF6));
}
int32
DescargaPres_BMP085(){
i2c_Start();
i2c_write(0xEE);
i2c_write(0xF4);
i2c_write(0x34+(3<<6));
i2c_Stop();
delay_ms(26);
return((256*DescargaByte_BMP085(0xF6))+
DescargaByte_BMP085(0xF7)+
(DescargaByte_BMP085(0xF8)/256));
}
float
LeeTemperatura_BMP085(float tempeAux){
float Conversor, Temperatura;
Conversor=xC5*(tempeAux-xC6);
Temperatura=Conversor+(xMc/(Conversor+xMd));
xS=Temperatura-25;
return(Temperatura);
}
float
LeePresion_BMP085(float presAux){
float auxA, auxB, auxC;
float Presion;
auxA=xX3*xS*xS+xX2*xS+xX1;
auxB=xY3*xS*xS+xY2*xS+xY1;
auxC=((float)presAux-auxA)/auxB;
Presion=0.0000045*auxC*auxC+0.994*auxC+2.37;
Presion+=4.58;
return(Presion);
}
void
main(){
lcd_init();
inicializa_BMP085();
while(true){
lcd_gotoxy(1,1);
printf(lcd_putc,"T[c]: %.1g
\n",LeeTemperatura_BMP085(DescargaTemp_BMP085()));
lcd_gotoxy(1,2);
printf(lcd_putc,"P[mBar]: %0.2g
\n",LeePresion_BMP085(DescargaPres_BMP085()));
delay_ms(500);
}
}
hello, so thanks you for your sharing. but i'm just beginning to learn about ccs, can you answer to me for code "lcd.c"?
ResponderBorrarHello, the libraries that are included in the program include default within the CCS compiler files, I use the IDE PCWH with CCS compiler, it has the libraries. (The libraries can not include in the post because they own CCS).
BorrarGreetings.
I would like to thank u, my English is not too good.Hopefully u can understand. I wanna ask your help a bit.How to make it active between pic and lcd or how to show up between pic and lcd?I cant handle at the temperature at decimal number.
BorrarThis is code which based on ur assignment. Because i have learnt ccs for a short time, can you help me to correct it at decimal point/part
#define RS RE0
#define RW RE1
#define E RE2
#define LCD PORTD
int32 T;
Int T_C,T_DV;
Int T_TP;
void GDK()
{
RS = 0;
RW = 0;
E = 1;
E = 0;
delay_ms(1);
}
void GHT()
{
RS = 1;
RW = 0;
E = 1;
E = 0;
delay_ms(1);
}
void doc_nhietdo()
{
T=LeeTemperatura_BMP085(DescargaTemp_BMP085());
T_C=T/10;
T_DV=T%10;
T_TP=(T*10)%10;
}
void main(){
//lcd_init();
inicializa_BMP085();
TRISE=0;
TRISD=0;
LCD = 0x01;
GDK();
LCD = 0x38;
GDK();
LCD = 0x0C;
GDK();
LCD = 0x84;
GDK();
LCD = 'T'; GHT();
LCD = ' '; GHT();
LCD = '='; GHT();
LCD = ' '; GHT();
while(true){
doc_nhietdo();
LCD = 0x88; GDK();
LCD = T_C+48; GHT();
LCD = T_DV+48; GHT();
LCD = '.'; GHT();
LCD = T_TP+48; GHT();
delay_ms(500);
}
}
this is link contains my problems and photos of electric circuit. I use pic 16f877a i look forward for getting your kindly help
Borrarhttp://imgur.com/8lcce9C
Hello , Thanks ! ,
BorrarHere https://gist.github.com/ARod/1782270 I leave a place site LCD.C download the library , including library can the manipulate the comma or floating point simply site as seen in the schedule to this post , sin need to handle each character separately.
Greetings.
PD: my english is bad....
Thanks for your sharing. I have finished the decimal part of the temperature . Now i would like to learn more about how to compute the height and pressure. Can you give me an exercise as an example ?
Borrari wanna ask a bit that where may i can learn algorithm communication with bmp085 ? how to get it
xC3 = 160*pow(2,-15)*AC3;
xC4 = pow(1,-3)*pow(2,-15)*AC4;
xC5 = (pow(2,-15)/160)*AC5;
xC6 = (float)AC6;
xB1 = pow(160,2)*pow(2,-30)*B1;
...
? Im looking forward to hearing from you soon. Thanks a lot.
Hello , the calculations are in datasheet https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf Provides Bosch sheet , on page 14 of this sheet you can see the exponential calculation That Suggests to Calculate the height function of the atmospheric pressure .
BorrarGreetings.
hello S.C
Borrarthanks you very much one more time.
i will seek more information about datasheet, it would be great to get your kindly support if I meet any difficultis. But, can you please give me an example or a sample code about how to compute the height and pressure of this bmp?
Hello , the formula is:
Borrarfloat altitude, pressure
altitude = 44330 * (1 - pow((pressure/1013.25),0.19))
is the altitude in meters.
ok thanks you very much :D
Borrarone more time :D
you welcome!
BorrarEste comentario ha sido eliminado por el autor.
ResponderBorrar