![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
BMP085 interfacing with PIC microcontroller problem |
Posted: Tue Mar 18, 2014 11:15 am |
|
|
hi
i want to interface bmp085 pressure sensor with pic18f452....i have completed my testing code but i can't to get proper value from bmp085...
i have used 4.7 k pull up resistor.......
here i just try to get co-efficient value of ac1.......plz help me
Code: |
#include <18F452.h>
#FUSES HS //Resistor/Capacitor Osc
#use delay(clock=20mhz)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
#byte PORTA=0xf80
#byte PORTB=0xf81
#byte PORTD=0xf83
#byte PORTC=0xf82
#BYTE TRISD=0XF95
#BYTE TRISB=0XF93
#BYTE TRISC=0XF94
#BYTE TRISA=0XF92
#BIT rs=PORTD.0
#BIT rw=PORTD.1
#BIT en=PORTD.2
#BIT EOC=PORTA.0
#include "flex_lcd.c"
VOID Display(int16 TEMPER);
UNSIGNED INT Ascii[]={'0','1','2','3','4','5','6','7','8','9'};
void Init();
int8 BMP085_read(int8);
void BMP085_write(int8 addr,int8 data);
unsigned int16 x=0,y=0,TEMP=0;
//int32 ;
void main()
{
delay_ms(100);
Init();
lcd_init();
lcd_gotoxy(0X0F,1);
lcd_putc('A');
while(true)
{
//BMP085_write(0XF4,0x2E);
// delay_ms(5);
// if(EOC)
//{
x=BMP085_read(0xAA);
y=BMP085_read(0xAB);
delay_ms(5);
TEMP=x << 8 ;
TEMP=TEMP|y;
display(TEMP);
}
//delay_ms(1000);
//}
}
void Init()
{
TRISB=0;
output_float(PIN_C3);
output_float(PIN_C4);
BMP085_write(0XF4,0x2E);//init the 0th reg in RTC
output_b(0x00);
}
void BMP085_write(int8 addr,int8 data)
{
i2c_start();
i2c_write(0xEE);
i2c_write(addr);
i2c_write(data);
i2c_stop();
}
int8 BMP085_read(int8 addr)
{
int8 data;
i2c_start();
i2c_write(0xEE);
i2c_write(addr);
i2c_start();
i2c_write(0xEF);
data=i2c_read(0);
i2c_stop();
return (data);
}
void Display(int16 TEMPER)
{
int8 a,b,c,d,e,f,g,h;
a=TEMPER/10000;//1 st
b=TEMPER%10000;
c=b/1000;//2 nd
d=b%1000;
e=d/100;//3 rd
f=d%100;
g=f/10;// 4 th
h=f%10;// 5th
lcd_gotoxy(1,1);
lcd_putc("TEMP:");
lcd_gotoxy(7,1);
lcd_putc(Ascii[a]);
lcd_gotoxy(8,1);
lcd_putc(Ascii[c]);
lcd_gotoxy(9,1);
lcd_putc(Ascii[e]);
lcd_gotoxy(0x0A,1);
lcd_putc(Ascii[g]);
lcd_gotoxy(0X0B,1);
lcd_putc(Ascii[h]);
} |
_________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Tue Mar 18, 2014 11:18 am |
|
|
pathmasugu,
Before you begin to hyperventilate, have you checked the Code Library? I know for a fact that there is working BMP085 over there. Have you studied that code?
Link to the BMP085 code: http://www.ccsinfo.com/forum/viewtopic.php?t=48874
John |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
|
Posted: Wed Mar 19, 2014 2:13 am |
|
|
i refered that bmp085 driver.........but i got 12.8 c temperature and 1008.28 pressure value ........... these values are not correct because my room temp is 33 c ......help me ...
here i include my code with driver
Code: |
#include <18F452.h>
#FUSES HS //Resistor/Capacitor Osc
#use delay(clock=20mhz)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=GPS,errors)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)
#byte PORTA=0xf80
#byte PORTB=0xf81
#byte PORTD=0xf83
#byte PORTC=0xf82
#BYTE TRISD=0XF95
#BYTE TRISB=0XF93
#BYTE TRISC=0XF94
#BYTE TRISA=0XF92
#BIT rs=PORTD.0
#BIT rw=PORTD.1
#BIT en=PORTD.2
#BIT EOC=PORTA.0
#include "driver_bmp085.c"
#include "flex_lcd.c"
UNSIGNED INT Ascii[]={'0','1','2','3','4','5','6','7','8','9'};
VOID Display(float TEMPER);
void Init();
float T_Cent;
float P_mBar;
void main()
{
delay_ms(100);
Init();
lcd_init();
lcd_gotoxy(0X0F,1);
lcd_putc('A');
bmp085Calibration();
//fprintf(GPS,"b1:%d,b2:%d,ac1:%d,ac2:%d,ac3:%d,\r\n",b1,b2,ac1,ac2,ac3);
while(true)
{
T_Cent=BMP085Temperature();
delay_ms(5);
display(T_Cent);
P_mBar = BMP085Pressure(false);
fprintf(GPS,"temp:%.1g\r\n",T_Cent);
fprintf(GPS,"Pressure (mBar): %0.2g\r\n\n", P_mBar);
P_mBar=0;
}
}
void Init()
{
TRISB=0;
output_float(PIN_C3);
output_float(PIN_C4);
output_b(0x00);
}
void Display(float TEMPER)
{
int32 a,b,c,d,e,f,g,h;
a=(int32)TEMPER/10000;//1 st
b=(int32)TEMPER%10000;
c=b/1000;//2 nd
d=b%1000;
e=d/100;//3 rd
f=d%100;
g=f/10;// 4 th
h=f%10;// 5th
lcd_gotoxy(1,1);
lcd_putc("TEMP:");
lcd_gotoxy(7,1);
lcd_putc(Ascii[a]);
lcd_gotoxy(8,1);
lcd_putc(Ascii[c]);
lcd_gotoxy(9,1);
lcd_putc(Ascii[e]);
lcd_gotoxy(0x0A,1);
lcd_putc(Ascii[g]);
lcd_gotoxy(0X0B,1);
lcd_putc(Ascii[h]);
}
|
driver code: Code: |
#include <math.h>
const int8 OVS_S = 3; // Oversampling Setting (0,1,2,3 from ultra low power, to ultra hi-resolution)
#define BMP085_ADDRESS 0xEE // I2C address of BMP085
#define P_CORRECTION 1.5 // in mBars - factor to adjust for elevation to match local weather station pressure
// this value for 14' above sea level (in Boca Raton, Florida)
// Calibration values
signed int16 ac1;
signed int16 ac2;
signed int16 ac3;
int16 ac4;
int16 ac5;
int16 ac6;
signed int16 b1;
signed int16 b2;
signed int16 mb;
signed int16 mc;
signed int16 md;
// floating point cal factors
float _c3;
float _c4;
float _b1;
float _c5;
float _c6;
float _mc;
float _md;
// polynomomial constants
float _x0;
float _x1;
float _x2;
float _y0;
float _y1;
float _y2;
float _p0;
float _p1;
float _p2;
float _s; // T-25, used in pressure calculation - must run temperature reading before pressure reading
float _Temp; // set after every temperature or temperature/pressure reading
//----------------------------------------------
int8 BMP085ReadByte(int8 address)
//----------------------------------------------
{
int8 data;
i2c_start();
i2c_write(BMP085_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(BMP085_ADDRESS | 0x01 );
data=i2c_read(0);
i2c_stop();
return(data);
}
//----------------------------------------------
int16 BMP085ReadInt(int8 address)
//----------------------------------------------
{
int8 msb, lsb;
int16 temp;
i2c_start();
i2c_write(BMP085_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(BMP085_ADDRESS | 0x01 );
msb = i2c_read();
lsb = i2c_read(0);
i2c_stop();
temp = make16(msb, lsb);
return ( temp );
}
//----------------------------------------------
void BMP085WriteByte(int8 address, int8 data)
//----------------------------------------------
{
i2c_start();
i2c_write(BMP085_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
}
//----------------------------------------------
void bmp085Calibration()
//----------------------------------------------
{
// read BMP085 EEPROM cal factors
ac1 = bmp085ReadInt(0xAA);
delay_ms(5);
ac2 = bmp085ReadInt(0xAC);
delay_ms(5);
ac3 = bmp085ReadInt(0xAE);
delay_ms(5);
ac4 = bmp085ReadInt(0xB0);
delay_ms(5);
ac5 = bmp085ReadInt(0xB2);
delay_ms(5);
ac6 = bmp085ReadInt(0xB4);
delay_ms(5);
b1 = bmp085ReadInt(0xB6);
delay_ms(5);
b2 = bmp085ReadInt(0xB8);
delay_ms(5);
mb = bmp085ReadInt(0xBA);
delay_ms(5);
mc = bmp085ReadInt(0xBC);
delay_ms(5);
md = bmp085ReadInt(0xBE);
delay_ms(5);
// calculate floating point cal factors
_c3 = 0.0048828125 * ac3; // 160 * pow2(-15) * ac3;
_c4 = 0.000000030517578125 * ac4; // 1E-3 * pow2(-15) * ac4;
_c5 = 0.00000019073486328125 * ac5; // (pow2(-15)/160) * ac5;
_c6 = (float)ac6;
_b1 = 0.00002384185791015625 * b1; // 25600 * pow2(-30) * b1;
_mc = 0.08 * mc; // (pow2(11) / 25600) * mc;
_md = (float)md / 160;
// calculate polynomial constants
_x0 = (float)ac1;
_x1 = 0.01953125 * ac2; // 160 * pow2(-13) * ac2;
_x2 = 0.000762939453125 * b2; // 25600 * pow2(-25) * b2;
_y0 = _c4 * 32768; //_c4 * pow2(15);
_y1 = _c4 * _c3;
_y2 = _c4 * _b1;
_p0 = 2.364375;
_p1 = 0.992984;
_p2 = 0.000004421;
}
// Read the uncompensated temperature value
//----------------------------------------------
int16 BMP085ReadUT()
//----------------------------------------------
{
int16 ut;
// Write 0x2E into Register 0xF4
BMP085WriteByte(0xF4, 0x2E);
delay_ms(5); // Wait at least 4.5ms
// Read two bytes from registers 0xF6 and 0xF7
ut = BMP085ReadInt(0xF6);
return((float)ut);
}
// Read the uncompensated pressure value
//----------------------------------------------
int32 bmp085ReadUP()
//----------------------------------------------
{
int8 msb, lsb, xlsb;
float p;
// Write 0x34+(OSS<<6) into register 0xF4
// Request a pressure reading w/ oversampling setting
BMP085WriteByte(0xF4, (0x34 + (OVS_S<<6)) );
// Wait for conversion, delay time dependent on OSS
switch (OVS_S)
{
case 0: delay_ms(5); break;
case 1: delay_ms(8); break;
case 2: delay_ms(14); break;
case 3: delay_ms(26); break;
}
// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
msb = BMP085ReadByte(0xF6);
lsb = BMP085ReadByte(0xF7);
xlsb = BMP085ReadByte(0xF8);
p = (256*msb) + lsb + (xlsb/256);
return(p);
}
//----------------------------------------------
float BMP085GetTemp(float _tu)
//----------------------------------------------
{
float alpha, T;
alpha = _c5 * (_tu - _c6);
T = alpha + (_mc/(alpha + _md));
_s = T - 25;
return(T);
}
//----------------------------------------------
float BMP085GetPressure(float _pu)
//----------------------------------------------
{
float x, y, z;
float P;
x = _x2*_s*_s + _x1*_s + _x0;
y = _y2*_s*_s + _y1*_s + _y0;
z = ((float)_pu - x) / y;
P = _p2*z*z + _p1*z + _p0;
P += P_CORRECTION;
return(P);
}
//----------------------------------------------
float BMP085Pressure(boolean getTemp)
//----------------------------------------------
{
if (getTemp)
_Temp = BMP085GetTemp(BMP085ReadUT()); // creates _s required for pressure calculation
return(BMP085GetPressure(BMP085ReadUP()));
}
//----------------------------------------------
float BMP085Temperature(void)
//----------------------------------------------
{
_Temp = BMP085GetTemp(BMP085ReadUT());
return(_Temp);
}
|
_________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Mar 19, 2014 3:52 am |
|
|
The barometric return seems perfectly likely (assuming a slight 'low' nearby).
The termperature though, does not look as though it is doing the calculation properly.
If you look at the formula given on Page13 of the data sheet, and then compare what is done with the actual calculation in the driver, a couple of parts seem to have been omitted. The offset of '8' is completely lacking. The division if being done by extra scaling of the _c5 value, but the result is going to be incorrect.
Try reading the uncompensated temperature value, and reporting this here, together with AC6, AC5, MC, and MD.
We or you, can then simply put this through the calculation from the data sheet. If this gives the correct value, then there are only a couple of lines that need to change at the end of the formula in the driver.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
|
Posted: Wed Mar 19, 2014 4:19 am |
|
|
thank you MR.Ttelmah..
above driver now working properly..... i made mistake in my circuit ...... _________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 19, 2014 4:30 am |
|
|
Sorry, I can't help you with your actual problem but with a quick glance at your code I noticed the following function: Code: | void Display(float TEMPER)
{
int32 a,b,c,d,e,f,g,h;
a=(int32)TEMPER/10000;//1 st
b=(int32)TEMPER%10000;
c=b/1000;//2 nd
d=b%1000;
e=d/100;//3 rd
f=d%100;
g=f/10;// 4 th
h=f%10;// 5th
lcd_gotoxy(1,1);
lcd_putc("TEMP:");
lcd_gotoxy(7,1);
lcd_putc(Ascii[a]);
lcd_gotoxy(8,1);
lcd_putc(Ascii[c]);
lcd_gotoxy(9,1);
lcd_putc(Ascii[e]);
lcd_gotoxy(0x0A,1);
lcd_putc(Ascii[g]);
lcd_gotoxy(0X0B,1);
lcd_putc(Ascii[h]);
} | This gives me a headache!
A lot of code. Variable names like a, b, c, d, etc. that are meaningless. Mixing decimal and hexadecimal in the calls to lcd_gotoxy.
Why not use printf or sprintf like you are using in main()? You do know the function exists, or is this all copy/paste code?
Code: | void Display(float temper)
{
lcd_gotoxy(1,1);
lcd_putc("TEMP:");
lcd_gotoxy(7,1);
printf(lcd_putc, "%5.1f", temper);
} |
Two other notes:
- It is good practice to have variable names in lower capital letters. All capital letter names are reserved for constants and #defined values.
- Variables starting with '_' are in the C standard reserved for use by the compiler internally. |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
|
Posted: Wed Mar 19, 2014 5:49 am |
|
|
I don't know about printf & sprintf in ccs.....now i got that information from you ..... thanks for your information and one more thing is that portion of code wrote by me only, that's why lot of mistakes ....but it works good. _________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|