Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 17:52 28 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : I2C pressure transducer

Author Message
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6101
Posted: 06:15pm 05 Jan 2014
Copy link to clipboard 
Print this post

I recently purchased a BMP085 pressure transducer (I2C).
As usual, I went for an Arduino module to save soldering etc.
Mine cost $3.91 each.

The data sheet has plenty of information and sample software for the Arduino is easy to find.
Each IC has been individually calibrated and you have to read the 11 data values in before converting the raw data to real values.
One problem I found was the sample software assumes signed and unsigned 16 bit numbers.
It took a bit of work to get things calculating correctly on the Maximite but fortunately the datasheet provides sample data for testing the maths.
Because of this, the maths looks a bit strange but it does work reliably.

' reading the BMP085 pressure sensor
' TassyJim 06 JAN 2014
Cls
print
Dim BMPData(2) ' store data from BMP085
dim cal(11) ' calibration data
oss = 0 ' over sampling 0 to 3
alt = 240 ' your altitude in metres
f$="%6.1f" ' format string
BMP085calMEM = &HAA ' start of 11 calibration values
BMP085address = &H77 ' BMP085 address
BMP085control = &HF4 ' BMP085 control register
BMP085temp = &H2E ' BMP085 temperature command
BMP085pres = &H34 ' BMP085 pressure command
BMP085pres = BMP085pres + oss*&H40 ' adjust command for oversampling
BMP085reading = &HF6 ' register for results of reading

I2CEN 400, 200 ' Enable I2C. use slow speeds for long leads
pause 20

z = Calibrate() ' read the calibration data

do
t=temperature()
p=pressure(oss)
p0=Psl(p,alt)
print time$,"T:",format$( t,f$);" P:",format$(p/100,f$);" P(sl):",format$(p0/100,f$)
pause (300000) ' delay 5 minutes between readings
loop until k$ = "q" or k$ = "Q"

end

function Calibrate()
' needs to be called once for each module.
' safest to do it on every program start.
local n, calMEM
calMEM= BMP085calMEM
for n = 1 to 11
I2CSEND BMP085address, 0, 1, calMEM ' first calibration location
pause 1
I2CRCV BMP085address, 0, 2, BMPData(0)
'print BMPData(1), BMPData(0)*256 + BMPData(1)
cal(n) = BMPData(0)*256 + BMPData(1)
if n < 4 or n > 6 then ' need to convert some to signed numbers
if cal(n) > 32767 then
cal(n) = cal(n) - 65536
endif
endif
'print n,cal(n)
pause 1
calMEM=calMEM+2 ' advance to the next calibration location
next n
end function

function temperature()
' returns the temperature in degrees C to one decimal place
local UT, x1, x2, b5
I2CSEND BMP085address, 0, 2, BMP085control, BMP085temp
pause 5
I2CSEND BMP085address, 0, 1, BMP085reading
I2CRCV BMP085address, 0, 2, BMPData(0)
UT = BMPData(0)*256 + BMPData(1)
'calculate true temperature
x1= int( (UT-cal(6))*cal(5)/32768)
x2=int( cal(10)*2048/(x1+cal(11)))
b5=x1+x2
temperature = int((b5+8)/16)/10
end function

function pressure(oss)
' returns the pressure in pascals. Divide by 100 for millibars
' recalculates the temperatre.
' time could be saved by reading the temperature once evry 10 minutes
' when taking readings at short intervals
local UT, UP, x1, x2, x3, b5, b6, b7, pres, p
pres = BMP085pres + oss*&H40
I2CSEND BMP085address, 0, 2, BMP085control, BMP085temp
pause 5
I2CSEND BMP085address, 0, 1, BMP085reading
I2CRCV BMP085address, 0, 2, BMPData(0)
UT = BMPData(0)*256 + BMPData(1)
I2CSEND BMP085address, 0, 2, BMP085control, pres
if oss = 0 then ' different oversampling requires different
pause 5 ' reading times
elseif oss = 1 then
pause 8
elseif oss = 2 then
pause 14
else
pause 26
endif
I2CSEND BMP085address, 0, 1, BMP085reading
I2CRCV BMP085address, 0, 2, BMPData(0)
UP = BMPData(0)*256 + BMPData(1)
I2CSEND BMP085address, 0, 1, BMP085reading+2
I2CRCV BMP085address, 0, 1, BMPData(0)
UP=(UP*256+BMPData(0))/2^(8-oss)
'calculate true temperature
x1= int( (UT-cal(6))*cal(5)/32768)
x2=int( cal(10)*2048/(x1+cal(11)))
b5=x1+x2
t=int((b5+8)/16)/10
'print "Temperature: ",t
'calculate true atmospheric pressure
b6 = b5 - 4000
x1 = int((cal(8)*(b6*b6/4096))/2048)
x2 = int(cal(2)*b6/2048)
x3 = x1 + x2
b3 = int(((cal(1)*4+x3)*2^oss +2)/4)
x1 = int(cal(3)*b6/8192)
x2 = int((cal(7)*(b6*b6/4096))/65536)
x3 = int(((x1+x2)+2)/4)
b4 = int(cal(4)*x3/32768+cal(4))
b7 = int((UP - b3)*(50000/2^oss))
p = int((b7*2)/b4)
x1 = int(int(p/256)*int(p/256))
x1 = int((x1*3038)/65536)
x2 = int((-7357*p)/65536)
pressure = int(p+(x1 + x2 + 3791)/16)
end function

function Psl(p, alt)
'given local pressure and altitude, returns pressure at sea level
Psl= p/(1-alt/44330)^5.255
end function


The next step is to waterproof one and throw it into the water tank to make a water level gauge.

Jim
VK7JH
MMedit   MMBasic Help
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 09:15pm 05 Jan 2014
Copy link to clipboard 
Print this post

  Quote  The next step is to waterproof one and throw it into the water tank to make a water level gauge


Looks similar to a Silicon Chip project of a few years ago. They had a bit of trouble keeping it water tight and had a few permutations.

What degree of accuracy do you need?

Some time back, I did a capacitive probe consisting of twin flex wrapped around a pole (for extra length of wire). It worked on calculating the time a RC network (probe) took to trip a comparator in the PIC. It wasn't linear but a lookup table took care of that. The ends of the twin flex in the water needed to be sealed. Temperature wasn't a problem.

The capacitance of the probe increased as the level of water in the tank increased. i.e. as the dielectric constant changed. Never took it past the prototype but is still on my "to do" list for when I get around to radio controlling the solar bore pump. The tank and pump are about 200mtrs apart.
David M.
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 09:23pm 05 Jan 2014
Copy link to clipboard 
Print this post

I've been going to get one of these for a project I was thinking about Jim but hadn't really looked at the datasheet. Just as well you've done the hard work for us, I didn't realize it would be that complicated.

Your code would be good for the MM library.

Greg
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6101
Posted: 09:25pm 05 Jan 2014
Copy link to clipboard 
Print this post

I have dug out the Silicon chip articles to see how they did things.
I think I know how I will do the probe. Just need time to experiment.

I am lucky, my bore is right beside the shed so mains power was not a problem.

Jim
VK7JH
MMedit   MMBasic Help
 
Keith @

Senior Member

Joined: 19/06/2011
Location: Australia
Posts: 167
Posted: 10:00pm 05 Jan 2014
Copy link to clipboard 
Print this post


"The next step is to waterproof one and throw it into the water tank to make a water level gauge."

With a static water level in the tank won't the reading vary with changing atmospheric pressure?

Could the atmospheric changes be cancelled out using a second sensor to measure the atmospheric pressure outside of the tank?

How will you waterproof?

I'm look forward to more on this topic ... the sensor is certainly cheap enough to wreck a couple in the process of learning. I'm looking at possibly using it in a tank mounted on a truck so it would have to be mounted into a fixed fitting in the bottom of the tank or one of the pipes under the tank.

... excellent work Jim
The more we know, the more we know we don't know !
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6101
Posted: 11:13pm 05 Jan 2014
Copy link to clipboard 
Print this post

One metre of water is about 98 hPa so reasonable accuracy should be obtainable.
In theory, 1cm resolution.

I will have a second unit measuring atmospheric pressure.

I expect I will use some soft tubing or heatshrink for waterproofing and it will be fitted inside a tee fitting placed in the outlet of the tank(s).

It might take a few attempts to get it right.

Jim
VK7JH
MMedit   MMBasic Help
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1873
Posted: 11:21pm 05 Jan 2014
Copy link to clipboard 
Print this post

I am using a BMP085 in my Weather Station, works really well. But for measuring water level I have also used MPX2202 to which you can attach a tube so the device can be remote to the tank. The device outputs a voltage directly proportional to the pressure.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024