PDA

View Full Version : Anyone used the Bosch BMP085 I2C baro sensor yet ?



mr.sneezy
- 15th April 2010, 01:39
Hi all,

If anyones used this new digital barometric sensor yet I'd love to see the PBP code to get calibrated readings out of it. I'm doing an open source project for R/C telemetry and using this sensor with a PIC16F819 is one of the first steps for me...

http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf

It's not just a simple I2C device (or I wouldn't be asking). It contains calibration data that must be referenced against an internal temperature sensor every time you calculate pressure (or altitude in this case). The math is a little more complex than I'm used too.

Anyway. I thought I'd ask here, might save me many migraines :-)

Thanks,
Martin

BrianT
- 15th April 2010, 03:23
Hello Martin,

I just scanned the Bosch datasheet. Their sensor is very similar to the Intersema MS5561C. The coding is more complex for the Bosch and the package will be tough to prototype I reckon. Have a look at the Intersema MS5540C. It is an easy package for hand solder prototyping. The Intersema range converts in about 35 mSecs. The Bosch unit at 7.5 mS has advantages in this area. Unless you need the speed I would have a go at the Intersema.

The MS5540C is under $20 qty 1 at Digikey which is where I get them.

HTH
BrianT

ScaleRobotics
- 15th April 2010, 04:27
Thanks Brian, I had not seen that sensor before. Nice catch.

Martin,

Don't know if you saw it already, but sparkfun has some C sample code here:
http://www.sparkfun.com/commerce/product_info.php?products_id=9694

Sometimes it helps me to look at, even though I don't know C very well.

I ordered their board, but they are out of stock right now.

Walter

Acetronics2
- 15th April 2010, 09:20
Hi,

Also have a look to this one ...

reminds you some other ???

Alain

mr.sneezy
- 15th April 2010, 10:55
Thanks Brian, I had not seen that sensor before. Nice catch.

Martin,

Don't know if you saw it already, but sparkfun has some C sample code here:
http://www.sparkfun.com/commerce/product_info.php?products_id=9694

Sometimes it helps me to look at, even though I don't know C very well.

I ordered their board, but they are out of stock right now.

Walter
Thanks Walter and Brian.

Brian I'm already committed to the Bosch sensor, and I have one on the way to me. Bare sensors are $8.95US at Sparkfun which is hard to beat.
I'd like to use it in this project as it has a good track record for use in altimeter devices. The soldering of this device shouldn't be too hard if you have some SMD experience (lots in my case). Or tip it upside down like another guy has and solder wires on top.

Walter I didn't C the C code at Sparkfun :p but I did find some in another website here
http://www.pixelproc.net/varios.html
I downloaded the C code, but it's all double dutch to me unfortunately. Maybe it will help you.
Walter maybe we can share some code when we have the devices.

Martin

rsocor01
- 15th April 2010, 12:59
Bare sensors are $8.95US at Sparkfun which is hard to beat.


Check this sensors out.

http://futurlec.com/Pressure_Sensors.shtml

Robert

BrianT
- 15th April 2010, 15:05
The FuturLec prices are excellent but I fear the HP03D will give highly variable results depending on incident light intensity. All silicon strain gauges are light sensitive. The HP01 and HP02 ones, coated in black, will be OK. The Intersema MS554x are light dependent even though they have opaque white 'silicone snot' covering the strain gauge element to reduce, but not eliminate, this effect.

Another trap with all these sensors is that distorting the ceramic substrate will bring out very large pressure and temperature offsets. In my experience, proper SMD reflow oven soldering does not stress the subsrtate anywhere like as much as hand soldering where the thermal stresses build up as each pin is soldered individually. I have found mounting the chip upside down and hand soldering fine 0.010 inch or 0.25 mm wire wrap wires keeps a batch tracking very well. You will not see the stress effects if you only make one or two units but if you build a batch of 100+ the difference unit to unit can be very frustrating.

The Hope HP03 has a cute feature of an on-board oscillator. I use the CCP registers of a PIC to provide the 32768 Hz MClk to the Intersema snsor but sometimes I would rather use a watch crystal direct on the pressure sensor instead of tying up a CCPWM port.

Lastly, most of the pressure sensor application notes specify a large tantalum cap across the supply. 47 uF in the case of the Intersema. The leakage current of this cap exceeds the sleep current of the sensor so don't forget that when you calculate your battery life.

HTH

BrianT

mr.sneezy
- 20th April 2010, 08:07
Thanks Brian.

Yes this is a one off project not a big batch, although hopefully many other RC model enthusiasts will build themselves one as it's part of an open source telemetry project using 2.4Ghz.

The sensor is actually available mounted on a small PCB for about $10 more. That may be the safest option.

I think the datasheet says only light through the small air hole is a problem on this sensor, so that should be easy to cover with something like carbon foam (antistatic chip foam).

Looks like I'm pioneering this sensor with PBP, hopefully you guys can help me cross the hard stuff when I get there in a week or so.
Martin

ScaleRobotics
- 24th April 2010, 02:04
Sparkfun has more of their BMP085 boards in stock now, if anyone is interested. Makes it nice to breadboard with. With the board, the cost is about the same as the Intersema. Still waiting on mine.

4281

mr.sneezy
- 7th May 2010, 07:57
I've got my BMP085 now, and I'm using a serial LCD and a PIC12F683 to try converse with the sensor initially. I have a problem with i2c comms, and reading the datasheet it mentions 'Restart condition' between starting a conversion (temperature in this case for simplicity to see it changing) and reading the result.
Now I've not come across the 'restart condition' before with i2c chips (just EEPROMS thus far).

Is it done in the PBP i2c statements or does it need to be bit-banged ? Or am I up the whole wrong tree here altogether ?

Cheers all,
MArtin

BrianT
- 8th May 2010, 02:11
PBP gives you four choices for ShiftIn and ShiftOut to set the clock idle high/low and whether the shift is MSB or LSB first. This should cover your needs with the exception that PBP does NOT give you much control over the timing of the clock and data lines. There is a DEFINE SHIFT_PAUSEUS nn command but this only delays the clock/data transition at the start of the bit and there is no control over timing at the end of the bit.

Cable length, cloick & data slew speed and any ringing on the clock and data lines can give bulk grief that takes days to find. Been there done that.

I found with the intersems sensors that the potted PBP ShiftIn/Out routines would only drive about 300 mm of ribbon cable but my hand written bit bang method let me run over a metre of cable.

Intersema is not the same as the Bosch interface. DIn, DOut and SClk vs SDA and SCL but otherwise the chips are very similar so the same sort of code structure ought to work.

Here is how I do it.



OutShift:
for fa = 1 to clockbits
'Don't forget OutShift adds an extra clock bit at the end.
din = (1 & iword) 'select lowest bit via AND mask
pauseus 4 'want minimum - about 4 uS or so
sclk = 4 : pauseus 4 : sclk = 0
iword = iword >> 1 'get next LSB, clock out zeros after 16 bits
next fa
sclk = 1 : pauseus 4 : sclk = 0
'this is the extra clock per DA5541B_00513 datasheet page 13
return

ResetIntersema: ' resets ALL pressure sensors
' shiftout din, sclk, 0, [85, 85, 0\5] ' Sense of Din is IN to 5541
output din : output sclk
clockbits = 20 : iword = %0101010101010101 '16 bit data word
gosub outshift
return

ConvertDelay: ' specific to each sensor
if tank = 0 then
While dout0 = 1
wend
endif
if tank = 1 then
While dout1 = 1
wend
endif
if tank = 2 then
While dout2 = 1
wend
endif
return

FetchWord: ' read specific channel reply. Different pins for DOut0,1,2
input dout0 : input dout1 : input dout2 : output sclk : iword = 0
if tank = 0 then
for fa = 15 to 0 step -1 'need 17 clock bits so add one at end
sclk = 1 : pauseus 4 'wait for Intersema to present next bit
iword.0[fa] = dout0 'read the bit on selected channel
sclk = 0 'drop clock
next fa 'do it 16 times
endif
if tank = 1 then
for fa = 15 to 0 step -1 'need 17 clock bits so add one at end
sclk = 1 : pauseus 1 'wait for Intersema to present next bit
iword.0[fa] = dout1 'read the bit
sclk = 0 'drop clock
next fa 'do it 16 times
endif
if tank = 2 then
for fa = 15 to 0 step -1 'need 17 clock bits so add one at end
sclk = 1 : pauseus 1 'wait for Intersema to present next bit
iword.0[fa] = dout2 'read the bit
sclk = 0 'drop clock
next fa 'do it 16 times
endif
sclk = 1 : pauseus 1 : sclk = 0 ' 17th clock bit
ii = iword.byte0 : ij = iword.byte1
return

ReadFactoryCal:
' This unpacks the factory calibration coefficients from the just
' read W1 ~ W4.
' These bitmaps are unpacked into the 6 working coefficients
' C1 to C6 which are then stored in EEROM for later use.
'W1
gosub resetintersema
' shiftout din, sclk, 0, [87, 1\5] ' Send W1 pattern to all sensors
clockbits = 12 : iword = %000101010111 'request W1 pattern
gosub outshift
gosub fetchword ' recall selected Tank reply
W1.byte0 = ii
W1.byte1 = ij
if (w1 = 0) or (w1 = 65535) then
debug "W1 error", 13, 10
goto readfactorycal
endif

'W2
gosub resetintersema
' shiftout din, sclk, 0, [215, 0\5] ' Send W2 pattern
clockbits = 12 : iword = %000011010111
gosub outshift
gosub fetchword
W2.byte0 = ii
W2.byte1 = ij
if (w2 = 0) or (w2 = 65535) then
debug "W2 error", 13, 10
goto readfactorycal
endif

'W3
gosub resetintersema
' shiftout din, sclk, 0, [55, 1\5] ' Send W3 pattern
clockbits = 12 : iword = %000100110111
gosub outshift
gosub fetchword
W3.byte0 = ii
W3.byte1 = ij
if (w3 = 0) or (w3 = 65535) then
debug "W3 error", 13, 10
goto readfactorycal
endif

'W4
gosub resetintersema
' shiftout din, sclk, 0, [183, 0\5] ' Send W4 pattern
clockbits = 12 : iword = %000010110111
gosub outshift
gosub fetchword
W4.byte0 = ii
W4.byte1 = ij
if (w4 = 0) or (w4 = 65535) then
debug "W4 error", 13, 10
goto readfactorycal
endif

CalcCoefficients: ' this serves all three sensors.
'C1
C1 = W1 >> 3 'unpack coefficient
read (108 + tank*20), z.byte0 'store
read (109 + tank*20), z.byte1
if z<>c1 then
write (108 + tank*20), c1.byte0 'store
write (109 + tank*20), c1.byte1
endif
'C2
C2 = ((W1 & %0000000000000111) << 10) + (W2 >> 6)
read (110 + tank*20), z.byte0
read (111 + tank*20), z.byte1
if z<>c2 then
write (110 + tank*20), c2.byte0
write (111 + tank*20), c2.byte1
endif
'C3
C3 = W3 >> 6
read (112 + tank*20), z.byte0
read (113 + tank*20), z.byte1
if z<>c3 then
write (112 + tank*20), c3.byte0
write (113 + tank*20), c3.byte1
endif
'C4
C4 = W4 >> 7
read (114 + tank*20), z.byte0
read (115 + tank*20), z.byte1
if z<>c4 then
write (114 + tank*20), c4.byte0
write (115 + tank*20), c4.byte1
endif
'C5
C5 = ((W2 & %0000000000111111) << 6) + (W3 & %0000000000111111)
read (116 + tank*20), z.byte0
read (116 + tank*20), z.byte0
if z<>c5 then
write (117 + tank*20), c5.byte1
write (117 + tank*20), c5.byte1
endif
'C6
C6 = W4 & %0000000001111111
read (118 + tank*20), z
if z<>c6 then
write (118 + tank*20), c6
endif

Show5541Coefficients: 'only used during diagnostics
' high txd : pause 1
' debug 13, 10, "Tank #", #tank, ", W1 = ", #w1, ", W2 = ",_
' #w2, ", W3 = ", #w3, ", W4 = ", #w4, 13, 10
' debug "Derived coeffs C1 = ", #C1, ", C2 = ", #C2, ", C3 = ",_
' #C3, ", C4 = ", #c4, ", C5 = ", #C5, ", C6 = ", #C6, 13, 10

return


HTH

BrianT

mr.sneezy
- 8th May 2010, 11:26
Thanks Brian,

I'm not sure quite what to say though. I'm sure the tip I need is in the reply, but most of the answer went over my head.
I've not used shiftin/shiftout of anything in PBP so I'd rather get the i2c commands to work for me (if it's possible).
The sensor is 20mm from the PIC, so I'm hoping distance related issues should not be a problem. I'll just have a quiet little play with the i2c commands and see if I can get some sense out of it with that for now :-)
Thanks,
Martin

mr.sneezy
- 8th May 2010, 13:20
OK, got comms up. I can read the temperature sensor fine now. The issue was HW not SW this time.
Martin

mr.sneezy
- 9th May 2010, 12:54
Well I've spent a few hours working on this over the weekend, and I've made good progress (for me) with communicating with the sensor. I have a PIC Serial LCD (20x4) attached to a PIC12F683, which has the BMP085 attached to GPIO.0 (clock) and GPIO.1(data).

So far I can see the inbuilt temperature sensor value changing when I put a warm finger on the sensor, and also read out the eleven 16bit calibration parameters and display them (I think).

I'm worried about two things.
One is if I have the MSB and LSB of the calibration data in the right order when I'm storing them and then again using them. I not convinced the numbers look right on the LCD. The PBP manual I find confuses me somewhat when they talk about storing the LSB first in a word sized array of the i2c device (i2cread command description).

The second is converting this math to PBP, given that the values of some seem to be signed and results of some operations are going to be 32bit size (unless I don't understand it at all, which is possible).
To convert the raw temperature result UT to Deg C (T) is
X1 = (UT - AC6) * AC5 / 2^15
X2 = MC * 2^11 / (X1 + MD)
B5 = X1 + X2
T = (B5 + 8) / 2^4

I'd love some help with some code to show how this can be done in PBP.
Anybody ?

Cheers,
Martin


'PIC 12F683 port/pin allocations
'-------------------------------
'GPIO.0/Pin 7 = I2C SCL clock
'GPIO.1/Pin 6 = I2C SDA data
'GPIO.2/Pin 5 = spare
'GPIO.3/Pin 4 = spare
'GPIO.4/Pin 3 = LED
'GPIO.5/Pin 2 = Serial TX

'-----------------------
' PIC Defines
' ===========
'Config bits set to INTERNAL OSC, Watch dog ON, Power up timer ON, Master Clear NOT used, BrownOut protection ON,
@ Device pic12f683, intrc_osc, wdt_on, pwrt_on, mclr_off, bod_on ;Config switches, different from PBP default
'@ __Config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF ;USING MPASM ONLY

Define Osc 4 '4Mhz clock used. Note - Set PIC config fuses on programmer to use Internal RC OSC

Include "modedefs.bas" ' Include serial modes

' Define some constants if needed

' Software Defines
Cal_table var word[11] '11 word array to store calibration data
Temp_Var var byte 'temp variable
Temp_Var2 var Word 'temp variable
i2c_Reg var Byte 'variable for target i2c register address

CPIN var GPIO.0 ' I2C clock pin
DPIN var GPIO.1 ' I2C data pin
SO Var GPIO.5 'Serial out pin
LED var GPIO.4 'Indicator LED, via 500ohm to +3.3V

'Alias's for calibration data in the sensor to match the Bosch paramater list names
AC1 var Cal_table[0] '
AC2 var Cal_table[1] 'BMP085 has 11 16bit values stored in EEPROM
AC3 var Cal_table[2] 'First byte is at $AA last at $BF
AC4 var Cal_table[3] 'Lowbyte is MSB, Highbyte is LSB
AC5 var Cal_table[4] 'some values are signed (not AC4, AC5, AC6)
AC6 var Cal_table[5]
B1 var Cal_table[6]
B2 var Cal_table[7]
MB var Cal_table[8]
MC var Cal_table[9]
MD var Cal_table[10]

' Initialise Processor - check for each PIC type either 12F629 or 12F675
' --------------------
VRCON.7 = %0 'Comparator voltage reference OFF
CMCON0 = %111 'Comparator inputs to OFF, all pins normal I/O
ANSEL = 0 'Turn off al AD's rem out for PIC12F629, use for PIC12F675

' Set initial state of GPIO port pins as Input or Output

TRISIO.0 = 0 'Input(0 = output, 1 = Input)
TRISIO.1 = 0 '
TRISIO.2 = 1 '
TRISIO.3 = 0 '
TRISIO.4 = 0 '
TRISIO.5 = 1 '

' PIC initialization code

Low LED 'LED on
pause 500
High LED 'LED off

Serout SO,N2400,[$FE,$01] ' Clear LCD & home LCD cursor.
pause 10 ' wait for LCD to catch up
Serout SO,N2400,[" FrSky Vario "] ' Serial print
Serout SO,N2400,[$FE,$C0] ' Shift cursor to line2
Serout SO,N2400,[" development jig "] ' Serial print
Pause 3000

i2c_Reg =$AA 'Start address of calibration data
I2CREAD DPIN,CPIN,$EF,I2C_REG,[STR Cal_table\11],read_error1 'Read 11 words out of sensor
Serout SO,N2400,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10 ' wait for LCD to catch up
Main:
Serout SO,N2400,[$FE,$02] 'home LCD cursor.

i2c_Reg = $F4 '$F4 is the control register address
I2CWRITE DPIN,CPIN,$EE,I2C_REG,[$2E] ' Write $2E to set temperature conversion
Pause 10 ' Delay 10ms after each write

i2c_Reg = $F6 '$F6 is the result register MSB
I2CREAD DPIN,CPIN,$EF,I2C_REG,[Temp_Var2],read_error 'Read temperature MSB, LSB.

Serout SO,N2400,[#Temp_Var2," "] 'Send Word size number to LCD

'lets see whats in the cal data array for a checking math
Serout SO,N2400,[$FE,$C0] ' Shift cursor to line2
Serout SO,N2400,[#AC1," ",#AC2," ",#AC3]
Serout SO,N2400,[$FE,$94] ' Shift cursor to line3
Serout SO,N2400,[#AC4," ",#AC5," ",#AC6]
Serout SO,N2400,[$FE,$D4]
Serout SO,N2400,[#B1," ",#B2," ",#MB]
' ," ",#MC," ",#MD] '
pause 1000
Toggle LED
Goto main

Read_error:
Serout SO,N2400,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10 ' wait for LCD to catch up
Serout SO,N2400,["i2c bus read error"] '
pause 250

Toggle LED
Goto main

Read_error1:
Serout SO,N2400,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10
Serout SO,N2400,["i2c cal read error "] '

End

mr.sneezy
- 10th May 2010, 13:32
Real values.
If there happens to be a mathematician amongst us that likes puzzles like the one above, I have the raw values (as decimal) read out of my sensor to plug into the temperature equations as a test. The result should be around 21C.

UT = 30814
AC5 = 22882
AC6 = 1368
MC = 48596
MD = 32777

mr.sneezy
- 11th May 2010, 05:18
UT = 30814
AC5 = 22882
AC6 = 1368
MC = 48596
MD = 32777
MC = -15828
MD = -9

A friend helped me use MS Excel to test the results I got out above. I missed that MC and MD are signed.
If MC is now -15828 and MD is now -9 then I get a result of T= 214 (+21.4C) in my lounge room...
So that would mean the MSB & LSB read out of the array IS the correct way around in my PIC code.

mr.sneezy
- 11th May 2010, 06:48
Ignore the cr@p I posted above. I thought I had it worked out but noooo.

PS. I hate the way you can't edit the post for more than a hour or so after putting up some info. What's with that anyway ?

mackrackit
- 11th May 2010, 07:20
PS. I hate the way you can't edit the post for more than a hour or so after putting up some info. What's with that anyway ?
Edits to post do not trigger a notification to those following a thread.

If edits were allowed to far back the whole context of the thread could be changed or useful information lost.

So there is really no reason to allow edits for more than a few minutes to correct spelling, grammar, or typos in general.

mr.sneezy
- 18th May 2010, 13:53
No the title is right....

I've just done some reading at Melabs about Longs in the recent versions of PBP and how they work with 18F series PIC's. I now think I may be doing sensor this the hard way with trying to use a 12F or 16F PIC.

A broad question: If the math involved in using this sensor only uses Longs and no floating point, can I use a 18FXXXX PIC to crunch the signed math, or is there a likely newbie Longs trap to fall into ?

I'd copy/paste the data sheets equations here to show you, but it's copy/paste protected. I'll attach it as a file.
It's only the last conversion from pressure to altitude that seems to use a float, and I can worry about that when I get that far (I hope). Page 12 is the guts of it.

BrianT
- 19th May 2010, 01:21
I have read the Bosch datasheet which is very similar to the Intersema MS5540 family. With the exception of absolute altitude, LONGs and a PIC18F part will handle those formulae easily.

The mathematical gymnastics of handling the Bosch 19 bit variables with 16 bit PBP will consume much code space thus ruling out the 12F series. You will get it into a 16F part on code space grounds but you will have to invent your own way to extend WORD variables up to 19 bits. Why bother?

The 18F series costs hardly any more, at least at hobby volumes, so cut your losses and go for a PIC18F part and take advantage of LONGs. This will automatically take care of negative temperatures which your altimeter will certainly need.

Absolute Altitude needs LOG functions to handle the power 1/5.255 so avoid that by using a lookup table which you can make as accurate as you want by adjusting the size of the table and the interpolation method.

HTH
BrianT

mr.sneezy
- 19th May 2010, 04:55
I have read the Bosch datasheet which is very similar to the Intersema MS5540 family. With the exception of absolute altitude, LONGs and a PIC18F part will handle those formulae easily.
HTH
BrianTHi Brian, yes that helps me, a good confidence boost at the very least.
Can I bother you a moment longer ? About two things in the datasheet that you may well understand without looking at it again.

First is that the equations for the temp and pressure conversions have in there a couple of times the value called 'oss', used with a binary shift I think. Do you know what that 'oss' means ?

Lastly, I've been reading the raw pressure value with my code as a 16 bit Word, but it occurred to me now that even if I don't specify the hi-res mode, that I should be reading the full 19bits (LSB being 000 I guess) not just 16. The data sheet doesn't make it clear either way (to me).

TIA,
Martin

BrianT
- 19th May 2010, 13:00
Looks to me the number of places you left or right shift is related to how many samples you take per reading. try and get hold of the C code and see if you can nut it out. In my Intersema code, I do the averaging by a simple sum of n readings divided by n at the end. Again, LONGs take the pain out of needing to know if the sum of 8 samples overflowed a 16 bit variable.

I have failed to find a copy of their C source code on the net. Seems you have to genuflect for one of their distributors to get it.

HTH
BrianT

mr.sneezy
- 19th May 2010, 14:11
Thanks Brian. Did I fail to RTFM :-) I hope not.

I studied a nicely done vario project here using the BMP085 and C30 compiler.
http://www.pixelproc.net/pic24bmp085lcd.html
Didn't mean much to me unfortunately as it's a very busy bit of work.

Yes, I like the simpler add many then divide way of averaging too, it always works well.
Martin

mr.sneezy
- 26th May 2010, 11:31
For anyone interested in the BMP085 barometric sensor I am now a little more sure that I've got a good set of calibration coefficients read out my BMP085, and also got the UT and UP raw values reading correctly.
I've set the BMP085 to it's highest resolution and over-sampling now (oss=3), and can use the 19bit size result in the Excel spreadsheet and get sensible results.
I did a test from the top of the building I work in, to the bottom, some 12 floors, and I get a altitude change of 63 meters which is about right. Then did one from the bottom to the top of the hill I live on and got a good result again.

While the code looks simple it turned out that it really needed to be using Longs and therefore a 18FXXXX micro. I had 18F1220 parts in my box so that's what I've used.
To display whats going on inside the PIC I use a PIC serial display, which I built many years ago (great bit of gear that). Mine has 20x4 LCD display rather than the usual 16x2 line.

I'll attach the Excel XLS file that my friend Andrew T made up using the calculations from the BMP085 datasheet. It processes the calibration data, temperature and pressure data the same way as I need my PIC too. So it's a good test comparison to see if my code is work right in each stage and has helped me greatly.


'PIC 18F1220 port/pin allocations
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
'PortA.0/Pin 1 = Serial TX
'PortA.1/Pin 2 = LED
'PortB.0/Pin 8 = I2C SCL clock
'PortB.1/Pin 9 = I2C SDA data

' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
'Config Directive settings for MPASM (fuses)

@ __CONFIG _CONFIG1H, _IESO_OFF_1H & _FSCM_OFF_1H & _INTIO2_OSC_1H
@ __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_27_2L
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_32K_2H
@ __CONFIG _CONFIG3H, _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVR_OFF_4L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
@ __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
@ __CONFIG _CONFIG7H, _EBTRB_OFF_7H

DEFINE OSC 8 '8Mhz clock used.

' Define some constants if needed

' Software Defines (variables and pins)
Cal_table var word[11] '11 word array to store calibration data
lUpres var long 'Long variable for Uncompensated Pressure
lTemp_Var var Long 'Long temporary variable
Temp_Var var byte 'Byte temp variable
Temp_Var2 var Word 'Word temp variable
Temp_Var3 var word 'Word temp variable
UTemp var word 'uncompensated temp reading
' UPres var word 'uncompensated pressure reading
i2c_Reg var Byte 'variable for target i2c register address

CPIN var PortB.0 ' I2C clock pin
DPIN var PortB.1 ' I2C data pin
SO Var PortA.0 'Serial out pin
LED var PortA.1 'Indicator LED, via 500ohm to +3.3V

'Alias's for calibration data in the sensor to match the Bosch parameter list names
AC1 var Cal_table[0] '
AC2 var Cal_table[1] 'BMP085 has 11 16bit values stored in EEPROM
AC3 var Cal_table[2] 'First byte is at $AA last at $BF, two bytes per cal value
AC4 var Cal_table[3] 'Lowbyte is MSB (e.g $AA), Highbyte is LSB (e.g. $AB)
AC5 var Cal_table[4] 'some values are signed (not AC4, AC5, AC6)
AC6 var Cal_table[5]
B1 var Cal_table[6]
B2 var Cal_table[7]
MB var Cal_table[8]
MC var Cal_table[9]
MD var Cal_table[10]

' Initialize Processor - check for each PIC type
' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
ADCON1 = %11111111 'Turn off all AD's
' OSCCON = %01100111 'set INTRC to 4 MHZ
OSCCON = %01110111 'set INTRC to 8 MHZ
' OSCTUNE = 0 'OSC trim set to Null

' Include "modedefs.bas" ' Include serial modes

' Set initial state of port pins as Input or Output

TRISA = %11111100 'Input(0 = output, 1 = Input)
TRISB = %11111100 '

' PIC initialization code
Low So 'Must start low, or you get rubbish on the LCD at PIC boot up.
Low LED 'LED on
pause 5000 'led on for x seconds
High LED 'LED off

Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
pause 10 ' wait for LCD to catch up
Serout2 SO,16780,[" FrSky Vario "] ' Serial print
Serout2 SO,16780,[$FE,$C0] ' Shift cursor to line2
Serout2 SO,16780,[" Development Jig "] ' Serial print
Pause 3000 'wait three seconds

i2c_Reg =$AA 'Start address of the BMP085 calibration data
I2CREAD DPIN,CPIN,$EF,I2C_REG,[STR Cal_table\11],cal_error 'Read 11 reversed words out of sensor

AC1 = (AC1.lowbyte<<8) + AC1.highbyte 'swap MSB and LSB of each to use in PBP (un-reverse then)
AC2 = (AC2.lowbyte<<8) + AC2.highbyte 'device stores the MSB in the Low byte, LSB in the High byte
AC3 = (AC3.lowbyte<<8) + AC3.highbyte
AC4 = (AC4.lowbyte<<8) + AC4.highbyte
AC5 = (AC5.lowbyte<<8) + AC5.highbyte
AC6 = (AC6.lowbyte<<8) + AC6.highbyte
B1 = (B1.lowbyte<<8) + B1.highbyte
B2 = (B2.lowbyte<<8) + B2.highbyte
MB = (MB.lowbyte<<8) + MB.highbyte
MC = (MC.lowbyte<<8) + MC.highbyte
MD = (MD.lowbyte<<8) + MD.highbyte

Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10 ' wait for LCD to catch up
'Main loop -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Main:
Serout2 SO,16780,[$FE,$02] 'home LCD cursor, not cleared.

Gosub Read_temp 'get Temp via I2C

lTemp_var = 0 'Clear the last pressure reading
For Temp_var = 0 to 9 'start of 10x averaging routine
Gosub Read_pres 'get Long uncompensated pressure via I2C
lTemp_var = ltemp_var + lUpres
Next Temp_var
lUpres = lTemp_Var / 10 'finish of 10x Averaging routine

Serout2 SO,16780,["UT=",DEC utemp," "] 'Send Word size number to LCD
Serout2 SO,16780,["UP=",DEC luPres," "] 'Send Word size number to LCD

'lets see whats in the cal data array for a checking math in Excel - Rem out Utemp and lUpres above
' Serout2 SO,16780,[$FE,$2] ' Shift cursor to line_1 (128+addr) Note-Rem out Utemp and lUpres above
' Serout2 SO,16780,[SDEC AC1," ",SDEC AC2," ",SDEC AC3] 'display three signed cal values
Serout2 SO,16780,[$FE,$C0] ' Shift cursor to line_2
Serout2 SO,16780,[DEC AC4," ",DEC AC5," ",DEC AC6] 'display three unsigned cal values
Serout2 SO,16780,[$FE,$94] ' Shift cursor to line_3
Serout2 SO,16780,[SDEC B1," ",SDEC B2] 'display two signed cal values
Serout2 SO,16780,[$FE,$D4] ' Shift cursor to line_4
Serout2 SO,16780,[SDEC MB," ",SDEC MC," ",SDEC MD] 'display three signed cal values
' pause 100
Toggle LED 'flash the 'im alive' LED
Goto main

'SUBROUTINES -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Read_pres:
i2c_Reg = $F4 '$F4 is the control register address
I2CWRITE DPIN,CPIN,$EE,I2C_REG,[$F4] ' Write $34+(oss << 6) to set pressure conversion
Pause 30 ' Delay 10ms after each write (30mS for HiRes results (oss=3))
i2c_Reg = $F6 '$F6 is the result register MSB
I2CREAD DPIN,CPIN,$EF,I2C_REG,[lUpres],I2C_error 'Read pressure MSB, LSB, XLSB, $F9(not needed).
lUpres = lUpres >> 13 'remove result from $F9 (>>8) + left shift result back to 19bits (>>5)
'it's because PBP reads four bytes if [Var] is a long...
return 'we only want top 19bits of the result.

Read_temp:
i2c_Reg = $F4 '$F4 is the control register address
I2CWRITE DPIN,CPIN,$EE,I2C_REG,[$2E] ' Write $2E to set temperature conversion
Pause 10 ' Delay 10ms after each write
i2c_Reg = $F6 '$F6 is the result register MSB
I2CREAD DPIN,CPIN,$EF,I2C_REG,[Utemp],I2C_error 'Read temperature MSB, LSB.
return

'trap and display I2C problems
I2C_error:
Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10 ' wait for LCD to catch up
Serout2 SO,16780,["i2c bus read error"] 'no ACK from I2C device
pause 2000
Toggle LED
Goto main

Cal_error:
Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10
Serout2 SO,16780,["i2c cal read error "] '

End

Now I have to convert this code below to PBPL and get a 'compensated' reading of the temperature and pressure.... Quite a few intermediate variables are needed.

//calculate the temperature
x1 = (ut - ac6) * ac5 >> 15;
x2 = ((int32_t) mc << 11) / (x1 + md);
b5 = x1 + x2;
temperature = (b5 + 8) >> 4;

//calculate the pressure
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;
b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;
x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
b7 = ((uint32_t) up - b3) * 50000;
p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;

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

I found this above C code elsewhere on the Web, it's in the datasheet more or less. I've also had PBP code help from a few forum members. Thank you all for the help so far :D

The journey continues...

mr.sneezy
- 28th May 2010, 13:38
Hmm...
I've written all the 32Bit calculation code now using PBPL and Longs, where they are needed (well nearly everywhere).
Right away I got a list of very strange compiler errors like this
c:/pbp/pbppi18l.lib 695 : Argument out of range ( 4168 not between 0 and 4095)

After having a look at line 695 of that file I still had no clue. So I took a punt that I might have run out of PIC code space, and yes that seems to be right. If I select a PIC in the same sub family with more code space the code complies error free....
Longs sure burn code space like it was endless resource.
Off to find a another bigger PIC again. This will be the 4th PIC tried for this project.


Onward and upwards !!

PS. Is there a simple to use utility, MCS add-on or method that will show me the amount of RAM space my code is using when compiled (as well as program space) ?

Acetronics2
- 28th May 2010, 13:49
Hmm...
I've written all the 32Bit calculation code now using PBPL and Longs, where they are needed (well nearly everywhere).
Right away I got a list of very strange compiler errors like this
c:/pbp/pbppi18l.lib 695 : Argument out of range ( 4168 not between 0 and 4095)

After having a look at line 695 of that file I still had no clue. So I took a punt that I might have run out of PIC code space, and yes that seems to be right. If I select a PIC in the same sub family with more code space the code complies error free....
Longs sure burn code space like it was endless resource.
Off to find a another bigger PIC again. This will be the 4th PIC tried for this project.


Onward and upwards !!

Hi,

Looks linked to too small a program memory ... in 18 pins ... the 1320 exists in 8k ...

Alain

mr.sneezy
- 28th May 2010, 14:21
Hi Alain,

Yes, it compiles OK if I select that one, at about 5200 bytes.

As I have to buy the next size PIC I might as well jump to the 18F2520 with huge code space and 28pins, although I really am only using a few I/O at the moment. Going to be lots of unused I/O's.

Martin

ScaleRobotics
- 28th May 2010, 14:57
PS. Is there a simple to use utility, MCS add-on or method that will show me the amount of RAM space my code is using when compiled (as well as program space) ?

Nice work on the sensor code!

MCS shows you how much code is being used at the bottom of the page after compliling. (Note it does need a successful compile to be able to tell you this.)

4460

You can also peek in the .lst file, and find code used vs left.



MEMORY USAGE MAP ('X' = Used, '-' = Unused)


0000 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
00C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0100 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0140 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0180 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXX-------
0200 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0240 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0280 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
02C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX ---------------- ----------------
2000 : -------X-------- ---------------- ---------------- ----------------

All other memory blocks unused.

Program Memory Words Used: 665
Program Memory Words Free: 359
Then there is also Darrel's CodeSpace utility here:
http://www.picbasic.co.uk/forum/showthread.php?t=2418

mr.sneezy
- 29th May 2010, 02:14
Nice work on the sensor code!


Thanks, although it's not complete just yet. I'll show you the main sensor code snip in case you are interested. It complies now (if selecting a bigger PIC) and I know the result of the lCTemp section is 100% correct (+ & - Deg C ). The UPres calculations are as of right now untested.
If you see any blindingly obvious code bloat in the calculations let me know...
I will post the complete code as soon as I know it works fine.

I did know what the code size used was telling me in MCS, I was more curious about RAM (variables etc) as I have been caught before going to a PIC with more code space, only to be quickly stumped by running out of variables...

All variables are signed Longs, except MD, AC5 and AC6 which are Words.

'Calculate temperature in 1/10ths of Deg C from lUTemp ' Note 2^15 = 32768 Dec or $8000
X1 = ((lUtemp - AC6) * AC5) / $8000 'find X1
X2 = (lMC << 11) / (X1 + MD) 'Find X2
B5 = X1 + X2 'Find B5 from X1 and X2
lCTemp = (B5 + 8) / 16 'Hey presto, lCTemp appears...

'Calculate pressure in Pa from lUpres (1/100th's of hPa's)
B6 = b5 - 4000
x1 = (b2 * (B6 * B6 / $1000)) / $800
x2 = (lac2 * B6) / $800
x3 = x1 + x2
B3 = ((lac1 * 4 + x3) << 5) / 4 'My OSS = 3 (might need to * here not <<)
x1 = (lac3 * b6) / $2000
x2 = (b1 * (b6 * b6 / $1000)) / $10000
x3 = ((x1 + x2) + 2) / 4
B4 = (lac4 * (x3 + 32768)) / $8000
B7 = (lUPres - B3) * 50000
If B7 < $80000000 then
lPres = (B7 * 2) / B4
Else
lPres = (B7 / B4) * 2
Endif
X1 = (lPres / 256) * (lPres / 256)
X1 = (X1 * 3038) / $10000
X2 = (-7357 * lPres) / $10000
lPres = lPres + ((X1 + X2 + 3791) / 16)

Serout2 SO,16780,["T=",DEC lCtemp," "] 'Send Word size number to LCD
Serout2 SO,16780,["P=",DEC lPres," "] 'Send Word size number to LCD

ScaleRobotics
- 29th May 2010, 04:33
Sorry I missed the RAM part (even though it was in capitals...)

If my memory serves me correctly, I think the only way to test your ram space is to create a large dummy array, and see how large you can make it. If you get an error, make it smaller, to see what you have left. Yes, it would be nice if MCS counted your RAM

rore85
- 31st May 2010, 05:26
Hi... I'm new in this forum and I need your help about how to manage data from BMP085 in assembler... I need test it in a PIC16f84...

ScaleRobotics
- 31st May 2010, 05:59
Hi... I'm new in this forum and I need your help about how to manage data from BMP085 in assembler... I need test it in a PIC16f84...

That sounds a bit like torture for most of us. The math is hard enough using the longs feature in PBP, and a more robust PIC18F device. You might try the Microchip forum, as they are into that kind of thing (assembly). Likely they will help, but not do it for you.

Good luck,

Walter

mr.sneezy
- 31st May 2010, 06:38
Hi... I'm new in this forum and I need your help about how to manage data from BMP085 in assembler... I need test it in a PIC16f84...Hi, If you can get a PIC16F84 to read and process the data from a BMP085 into true pressure and temperature I'll eat my shorts !!

My program has hit 5.5Kb in code size on an 18F PIC. Sure I know assembly is much much tighter, but by that much ?

I will soon post (I hope so) the complete code to use this sensor on a PIC18FXXXX device with PBP. You can use the ASM file I guess to see how blocks of it are done in assembly.
Cheers,
Martin

Acetronics2
- 31st May 2010, 20:09
Hi, Sneezzy

I Think , with little trickery, the 16F84 could fit ... :o

let's think ...

IF you calculate the linearisation OUTSIDE the Pic, and trunk it to the PRECISION claimed ( not the resolution, eh ...)
...

I'm sure a lookup table, or a couple of " ax+b " regressions could be used.

But that implies ... the sensor and the PIC are married for life !!! :D

Alain

mr.sneezy
- 1st June 2010, 07:07
Hi, Sneezzy

I Think , with little trickery, the 16F84 could fit ... :o

let's think ...

IF you calculate the linearisation OUTSIDE the Pic, and trunk it to the PRECISION claimed ( not the resolution, eh ...)
...

I'm sure a lookup table, or a couple of " ax+b " regressions could be used.

But that implies ... the sensor and the PIC are married for life !!! :D

AlainI did think of that early on. I think you need to map all possible pressure readings (at your needed precision) across your range, but then also map for every possible temperature change across all pressure readings in that range. I think it very quickly becomes an impressive size lookup table yes ?
I suspect my shorts are safe, but if the poster above can do it I'll listen :-)

Acetronics2
- 1st June 2010, 13:04
Hi, Martin

I had a look to your excel sheet and , of course, got THE problem ... ;)

solution was to unlock the sheet , select the "F16" place and click on " place a formula " ( Fx button ) ...

it automatically corrects the written formula and then it rolls fine !!! :p

Are the Calibration values in the sheet those of YOUR Sensor ???

Alain

mr.sneezy
- 1st June 2010, 14:28
Hi, Martin

I had a look to your excel sheet and , of course, got THE problem ... ;)

solution was to unlock the sheet , select the "F16" place and click on " place a formula " ( Fx button ) ...

it automatically corrects the written formula and then it rolls fine !!! :p

Are the Calibration values in the sheet those of YOUR Sensor ???

AlainHi Alain, I suspect my friend didn't tell me that so I couldn't fiddle with his sheet :D

Yes, that indeed is the calibration data out of my BMP085 sensor.

Good news.
Tonight I finished debugging the pressure calculations and got a correct result in Pascals. Boy it took some doing didn't it. :-)
Tomorrow I'll tidy up the code and post the whole job after doing a little field testing.

Now I need to find a sample of a 'good' way to do a look-up table to convert pressure to altitude without using Logs (as I understand is required)...

Martin

Acetronics2
- 1st June 2010, 17:01
Hi, Martin

Was an awful job to crack the sheet password ;) I had to wait for the second attempt to get it open ...

May be ...

an excel sheet could easily produce the retrieve table to include in the program ???

I already did that for a programmable electronic ignition project ...

Alain

rore85
- 1st June 2010, 21:48
Thanks for answer...
I wonder if the calibration coefficients of BMP085 depend on something ... as either light, or are the same constants for all?
And another thing, the uncompensated temperature varies a lot ... in the order of thousands or hundreds
Thanks

mr.sneezy
- 2nd June 2010, 00:57
Hi, Martin

Was an awful job to crack the sheet password ;) I had to wait for the second attempt to get it open ...

May be ...

an excel sheet could easily produce the retrieve table to include in the program ???

I already did that for a programmable electronic ignition project ...

AlainYes, I guess it could be done that way. I wonder how much data in the table is just enough, that might be hard to workout ?
Yes the sensor would be mated by the table to one PIC for life, and make it impossible to give the HEX file to anyone else to use for an open project (if they can't use PBP). Unless the table can be forced into a known place in code space perhaps... Messy at the very least.

mr.sneezy
- 2nd June 2010, 00:59
Thanks for answer...
I wonder if the calibration coefficients of BMP085 depend on something ... as either light, or are the same constants for all?
And another thing, the uncompensated temperature varies a lot ... in the order of thousands or hundreds
ThanksMainly temperature dependant. I've not been able to show much sensitivity to light yet (indoors).
Yes, the pressure reading is very 'active' so I used the maximum OSS and then 10x averaging as well. It could do with even more...

mr.sneezy
- 2nd June 2010, 01:07
Here it is. This works, and give you a corrected temperature and pressure reading from a Bosch BMP085 barometric pressure sensor.

It requires a PIC18FXXXX MCU and use of PBPL compiler option. You'll need to change the configs for whatever PIC you choose and change the Serout2 statements to LCDOUT or whatever you want to display data on.

The main point of this post is really to show the calculations and variable casting and manipulation required.


'************************************************* *****************************
'MR.SNEEZY - test code for FrSky using Bosch BMP085 baro sensor.
'This version is for PIC 18F4620
'
'ADD/Do
'
'NOTES -
'
'LAST ACTION - scratch my head...
'
'PIC 18F1220 port/pin alocations
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
'PortA.0/Pin 2 = Serial TX
'PortA.1/Pin 3 = LED
'PortB.0/Pin 33 = I2C SCL clock
'PortB.1/Pin 34 = I2C SDA data

' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
'Config Directive settings for MPASM (fuses) for 18F4620

@ __CONFIG _CONFIG1H, _IESO_OFF_1H & _FCMEN_OFF_1H & _OSC_INTIO7_1H
@ __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOREN_OFF_2L
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
@ __CONFIG _CONFIG3H, _MCLRE_OFF_3H & _PBADEN_OFF_3H
@ __CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
@ __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
@ __CONFIG _CONFIG7H, _EBTRB_OFF_7H

DEFINE OSC 8 '8Mhz clock used.

' Define some constants if needed

' Software Defines (variables and pins)
Cal_table var word[11] '11 word array to store calibration data
lUpres var long 'Long variable for Uncompensated Pressure
lPres var Long 'Long variable for Compensated Pressure
lTemp_Var1 Var long 'Long temporary variable
X1 var Long
X2 var Long
X3 var Long
B3 var long
B4 var long
B5 var long
B6 var Long
B7 var long

lAC1 var Long 'Long variables for cal values actually negative in my sensor
lAC2 var long 'These are 'cast' from the Word vars into Long vars in code below
lAC3 var Long
lAC4 var Long
lMB var Long
lMC var Long

bTemp_Var1 var byte 'Byte temp variable
wTemp_Var1 var Word 'Word temp variable
wTemp_Var2 var word 'Word temp variable
lUTemp var long 'Uncompensated temperature reading from sensor
lCTemp var Long 'Compensated (real) temperature x10 (1/10th of C) from sensor
i2c_Reg var Byte 'variable for target i2c register address

CPIN var PortB.0 ' I2C clock pin
DPIN var PortB.1 ' I2C data pin
SO Var PortA.0 'Serial out pin
LED var PortA.1 'Indicator LED, via 500ohm to +3.3V

OSS con $3 'This value is the Over Sampling Setting for the BMP085
'0 = minimum, 3 = maximum. Also change value in Read_pres if you alter OSS

'Alias's for calibration data in the sensor to match the Bosch parameter list names
AC1 var Cal_table[0] '
AC2 var Cal_table[1] 'BMP085 has 11 16bit values stored in EEPROM
AC3 var Cal_table[2] 'First byte is at $AA last at $BF, two bytes per cal value
AC4 var Cal_table[3] 'Lowbyte is MSB (e.g $AA), Highbyte is LSB (e.g. $AB)
AC5 var Cal_table[4] '
AC6 var Cal_table[5]
B1 var Cal_table[6] 'Warning - AC4, AC5, AC6 are UNSIGNED values, the rest are SIGNED
B2 var Cal_table[7]
MB var Cal_table[8]
MC var Cal_table[9]
MD var Cal_table[10]

' Initialise Processor - check for each PIC type
' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
ADCON1 = %00001111 'Turn off all AD's
' OSCCON = %01100111 'set INTRC to 4 MHZ
OSCCON = %01110111 'set INTRC to 8 MHZ
' OSCTUNE = 0 'OSC trim set to Null

' Set initial state of port pins as Input or Output if needed
' TRISA = %11111100 'Input(0 = output, 1 = Input)
' TRISB = %11111100 '
' TRISC = %11111111
' TRISD = %11111110
' TRISE = %11111111

' PIC initialization code
' Low So 'Start low, or you get rubbish on the LCD at PIC boot up.
Gosub Alive 'Go prove the PIC is running via LED

Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
pause 10 ' wait for LCD to catch up
Serout2 SO,16780,[" FrSky Vario "] ' Serial print
Serout2 SO,16780,[$FE,$C0] ' Shift cursor to line2
Serout2 SO,16780,[" Development Jig "] ' Serial print
Pause 2000

i2c_Reg =$AA 'Start address of the BMP085 calibration data
I2CREAD DPIN,CPIN,$EF,I2C_REG,[STR Cal_table\11],cal_error 'Read 11 reversed words out of sensor

AC1 = (AC1.lowbyte<<8) + AC1.highbyte 'swap MSB and LSB of each to use in PBP (un-reverse then)
AC2 = (AC2.lowbyte<<8) + AC2.highbyte 'device stores the MSB in the Low byte, LSB in the High byte
AC3 = (AC3.lowbyte<<8) + AC3.highbyte
AC4 = (AC4.lowbyte<<8) + AC4.highbyte
AC5 = (AC5.lowbyte<<8) + AC5.highbyte
AC6 = (AC6.lowbyte<<8) + AC6.highbyte
B1 = (B1.lowbyte<<8) + B1.highbyte
B2 = (B2.lowbyte<<8) + B2.highbyte
MB = (MB.lowbyte<<8) + MB.highbyte
MC = (MC.lowbyte<<8) + MC.highbyte
MD = (MD.lowbyte<<8) + MD.highbyte

'Cast (convert) signed PBP Word vars to signed PBP Long vars where needed by math routines below
lAC1 = AC1 'copy word to long
if AC1.15 then lAC1.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lAC2 = AC2 'copy word to long
if AC2.15 then lAC2.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lAC3 = AC3 'copy word to long
if AC3.15 then lAC3.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lMB = MB 'copy word to long
if MB.15 then lMB.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lMC = MC 'copy word to long
if MC.15 then lMC.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

'Cast (convert) UN-signed PBP Word var to UN-signed PBP Long var for math routines below
lAC4 = AC4 'copy word to long, both unsigned

Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10 ' wait for LCD to catch up

'Main loop -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Main:
Serout2 SO,16780,[$FE,$02] 'home LCD cursor, LCD not cleared.

Gosub Read_temp 'get Temp via I2C

Serout2 SO,16780,["UT=",SDEC lUtemp," "] 'Send Word size number to LCD

lTemp_Var1 = 0 'Clear the last pressure reading
For bTemp_Var1 = 0 to 9 'Start of 10x averaging routine
Gosub Read_pres 'get Long uncompensated pressure via I2C
lTemp_Var1 = lTemp_Var1 + lUpres
Next bTemp_Var1
lUpres = lTemp_Var1 / 10 'finish of the 10x Averaging routine

Serout2 SO,16780,["UP=",SDEC lUpres," "] 'Send Word size number to LCD

'Calculate temperature in 1/10ths of Deg C from lUTemp ' Note 2^15 = 32768 Dec or $8000
X1 = ((lUtemp - AC6) * AC5) / $8000 'find X1.
X2 = (lMC * $800) / (X1 + MD) 'Find X2. Note:- math rounding results in X2 being in error by 1 ?
B5 = X1 + X2 'Find B5 from X1 and X2.
lCTemp = (B5 + 8) / 16 'Hey presto, lCTemp appears...

'DISPLAY true temperature in C
X1 = lCTemp / 10 'find value above decimal point
Serout2 SO,16780,[$FE,$C0] ' Shift cursor to line_2
Serout2 SO,16780,["Temp= ",DEC X1,"."] 'Send Word size number to LCD
X1 = lCTemp // 10 'Find decimal value
Serout2 SO,16780,[DEC X1," "] 'Send Word size number to LCD

'Calculate pressure in Pascals from uncompensated pressure lUpres (1/100th's of hPa's)
B6 = b5 - 4000

x1 = (b2 * (B6 * B6 / $1000)) / $800
x2 = (lac2 * B6) / $800
x3 = x1 + x2
B3 = ((lac1 * 4 + x3) << OSS + 2) / 4 'OSS = Over Sampling constant set above

x1 = (lac3 * b6) / $2000
x2 = (b1 * (b6 * b6 / $1000)) / $10000
x3 = ((x1 + x2) + 2) / 4
B4 = (lac4 * (x3 + 32768)) / $8000 'Find B4, note lAC4 is an unsigned Long

B7 = (lUPres - B3) * (50000 >> OSS) 'OSS = Over Sampling constant set above

If B7 < $80000000 then 'branch if value is above or below range
lPres = (B7 * 2) / B4
Else
lPres = (B7 / B4) * 2
Endif

X1 = (lPres / 256) * (lPres / 256)
X1 = (X1 * 3038) / $10000 '$10000 = 2^16
X2 = (-7357 * lPres) / $10000
lPres = lPres + (X1 + X2 + 3791) / 16 'lPres is the true pressure in Pa

'DISPLAY true pressure in hPa
X1 = lPres / 100 'find value above decimal point
Serout2 SO,16780,[$FE,$94] 'Shift cursor to line_3
Serout2 SO,16780,["hPa= ",DEC X1,"."] 'Send Word size number to LCD
X1 = lPres // 100 'find value below decimal point
Serout2 SO,16780,[DEC X1," "] 'Send Word size number to LCD

pause 1000
Toggle LED 'flash the 'im alive' LED
Goto main

'SUBROUTINES -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Read_pres:
i2c_Reg = $F4 '$F4 is the control register address
I2CWRITE DPIN,CPIN,$EE,I2C_REG,[$F4] ' Write $34+(oss << 6) to set pressure conversion
Pause 30 ' Delay 10ms after each write (30mS for HiRes results (oss=3))
i2c_Reg = $F6 '$F6 is the result register MSB
I2CREAD DPIN,CPIN,$EF,I2C_REG,[lUpres],I2C_error 'Read pressure MSB, LSB, XLSB, $F9 ($F9 not actually wanted).
lUpres = lUpres >> (16 - oss) 'remove $F9 from result (>>8), and left shift result back to 16 to 19 Bits (OSS value dependant)
'it's because PBP reads four bytes if [Var] is a long...
return 'we only want top 19bits of the result.

Read_temp:
i2c_Reg = $F4 '$F4 is the control register address
I2CWRITE DPIN,CPIN,$EE,I2C_REG,[$2E] ' Write $2E to set temperature conversion
Pause 10 ' Delay 10ms after each write
i2c_Reg = $F6 '$F6 is the result register MSB
I2CREAD DPIN,CPIN,$EF,I2C_REG,[wTemp_Var1],I2C_error 'Read temperature MSB, LSB.
lUTemp = wTemp_Var1 'copy word to long. Note BMP085 UT is NOT a signed value
return

'Prove it's alive
Alive:
High LED 'flash LED routine
For btemp_var1 = 10 to 110 step 10
Low LED
Pause bTemp_Var1
High LED
Pause bTemp_Var1
Next bTemp_Var1

Return

'trap and display I2C problems
I2C_error:
Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10 ' wait for LCD to catch up
Serout2 SO,16780,["i2c bus read error"] 'no ACK from I2C device
pause 2000
Toggle LED
Goto main

Cal_error:
Serout2 SO,16780,[$FE,$01] ' Clear LCD & home LCD cursor.
Pause 10
Serout2 SO,16780,["i2c cal read error "] '

End

rore85
- 6th June 2010, 22:40
Thanks for answer...
I wonder if the calibration coefficients of BMP085 depend on something ... as either light, or are the same constants for all?
And another thing, the uncompensated temperature varies a lot ... in the order of thousands or hundreds
Thanks

Hi everybody...
The program in assembler works but I have problems generated in a division ratio, ie, it is rounded to an integer and the final value of the temperature goes too far in the real value, almost 80 degrees more ...
Someone had the same problem?
Thanks in advance!

ScaleRobotics
- 7th June 2010, 15:00
Here are some multi byte division functions for assembly: http://avtanski.net/projects/math/

eab123
- 2nd August 2010, 14:27
Hi Martin-
Thanks for sharing the Bosch code with us- some undertaking.
I'm just about to start a small project that could use this device and thought I'd just check I can compile it correctly using your posted code for the 18F4620 before proceeding further.

Unfortunately I'm getting compile errors ("overwriting previous address contents 0000 to 0007 locations") and just wondering if you could give me the versions of Microstudio and PBP you are running- I'm running Microstudio 3.0.0.5 and PBP 2.50L (with the pbpl box checked!)
Thanks for your time.
Edward

mackrackit
- 2nd August 2010, 14:36
You need to set the configs correctly
http://www.picbasic.co.uk/forum/showthread.php?t=543

eab123
- 3rd August 2010, 10:15
Thanks- all ok now.

mr.sneezy
- 3rd August 2010, 10:32
just wondering if you could give me the versions of Microstudio and PBP you are running- I'm running Microstudio 3.0.0.5 and PBP 2.50L (with the pbpl box checked!)
Thanks for your time.
EdwardPBP 2.60 and MCS 4.0.0.0

Martin
PS. If you do something interesting with the code please let us in on it :-)

flotulopex
- 3rd January 2012, 13:23
Hello,

I was wondering if someone did make a piece of PB code for converting the pressure to altitude?

I'm far too bad in maths......

flotulopex
- 7th January 2012, 12:43
Hi there,

I have played around with mr.sneezy's code and came up with that one hereunder. Appart from the temperature,I use only raw data for my tests (makes the code a little smaller).

The serial comm settings have been changed to connect to a pc-terminal (i.e. Serial Communicator in MCS) instead of a serial LCD display to make it more handy to store data into an EXCEL sheet for analysis.

I'm using three sampling methods:
1.- all measured values added and divided by the number of measurements ("16/16")
2.- keep 8 middle measurements out of sixteen and average them ("Mid8/16")
3.- keep 4 lowest (Bottom) and 4 highest (Top) measurements out of sixteen and average them ("B4+T4/16")

The "Diff" shows the variation +/- with the previous value to have a rought idea about the result of each sampling method.

Question: I'm wondering what precision I can expect from the BOSCH sensor. I'm not used to what one can expect from that type of sensor. While my sensor is "sitting" on my table,the values are bouncing up and down. I this correct?

As a parglider pilot, I use an alti-variometer from FlyTec 4010 (http://www.flytec.com/Products/Variometers/4010.htm) and the ascent/descent speed (precision is up to 0,1m per second) does not vary if the instruments isn't moved up or down. How can I reach the same behaviour from my sensor (no "bouncing" or no wrong ascent/descent indication)?

6213



'************************************************* *****************************
'MR.SNEEZY - test code for FrSky using Bosch BMP085 baro sensor.
'This version is for PIC 18F4620
'
'PIC 18F4620 port/pin alocations
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
'PortA.0/Pin 2 = Serial TX
'PortA.1/Pin 3 = LED
'PortB.0/Pin 33 = I2C SCL clock
'PortB.1/Pin 34 = I2C SDA data


'Config Directive settings for MPASM (fuses) for 18F4620
@ __CONFIG _CONFIG1H, _IESO_OFF_1H & _FCMEN_OFF_1H & _OSC_INTIO7_1H
@ __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOREN_OFF_2L
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
@ __CONFIG _CONFIG3H, _MCLRE_OFF_3H & _PBADEN_OFF_3H
@ __CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
@ __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
@ __CONFIG _CONFIG7H, _EBTRB_OFF_7H

'Registers
ADCON1 = 001111 'Turn off all AD's
OSCCON = 110111 'set INTRC to 8 MHZ

DEFINE OSC 8 '8Mhz clock used.

' SO_pinftware Defines (variables and pins)
Cal_table VAR WORD[11] '11 word array to store calibration data
lUpres VAR LONG 'Uncompensated Pressure
lPres VAR LONG 'Compensated Pressure
DataA VAR LONG 'or WORD - as needed
ArraySize CON 16
RawData VAR LONG[ArraySize] 'or WORD - as needed
X1 VAR LONG
X01 VAR LONG
X2 VAR LONG
X3 VAR LONG
B3 VAR LONG
B4 VAR LONG
B5 VAR LONG
B6 VAR LONG
B7 VAR LONG
lAC1 VAR LONG 'cal values actually negative in my sensor
lAC2 VAR LONG 'These are 'cast' from the Word vars into Long vars in code below
lAC3 VAR LONG
lAC4 VAR LONG
lMB VAR LONG
lMC VAR LONG
bTemp_Var1 VAR BYTE 'temp variable
wTemp_Var1 VAR WORD 'temp variable
wTemp_Var2 VAR WORD 'temp variable
lUTemp VAR LONG 'Uncompensated temperature reading from sensor
lCTemp VAR LONG 'Compensated (real) temperature x10 (1/10th of C) from sensor
lTemp_Var1 VAR LONG
lTemp_Var2 VAR LONG
lTemp_Var3 VAR LONG
Tempo1 VAR LONG
Tempo2 VAR LONG
Tempo3 VAR LONG
I2C_Reg VAR BYTE 'target i2c register address
Counter VAR WORD 'loop counter to show on display
Counter = 0
S_Bd_Rate VAR WORD
S_Bd_Rate = 84 '9600DTN
LF CON 10 'Line Feed (for use with Serial Terminal like Hyperterminal)
CR CON 13 'Carriage Return (for use with Serial Terminal like Hyperterminal)
OSS_Res CON $3 'Over Sampling Setting for the BMP085
OSS_Time CON 30 'in ms for OSS_Res 0 = 10ms, ..., 3 = 25ms (see BMP085 datasheet)

I2C_SCL VAR PortB.0 'I2C clock pin
I2C_SDA VAR PortB.1 'I2C data pin
S_TX VAR PortA.0 'Serial Tx) out pin
LED VAR PortA.1 'Indicator LED, via 500ohm to +3.3V


'Aliases for calibration data in the senS_TXr to match the Bosch parameter list names
AC1 VAR Cal_table[0] '
AC2 VAR Cal_table[1] 'BMP085 has 11 16bit values stored in EEPROM
AC3 VAR Cal_table[2] 'First byte is at $AA last at $BF, two bytes per cal value
AC4 VAR Cal_table[3] 'Lowbyte is MSB (e.g $AA), Highbyte is LSB (e.g. $AB)
AC5 VAR Cal_table[4] '
AC6 VAR Cal_table[5]
B1 VAR Cal_table[6] 'Warning - AC4, AC5, AC6 are UNSIGNED values, the rest are SIGNED
B2 VAR Cal_table[7]
MB VAR Cal_table[8]
MC VAR Cal_table[9]
MD VAR Cal_table[10]


I2C_Reg =$AA 'Start address of the BMP085 calibration data
I2CREAD I2C_SDA,I2C_SCL,$EF,I2C_Reg,[STR Cal_table\11],Cal_error 'Read 11 reversed words out of sensor
AC1 = (AC1.LOWBYTE<<8) + AC1.HIGHBYTE 'swap MSB and LSB of each to use in PBP (un-reverse then)
AC2 = (AC2.LOWBYTE<<8) + AC2.HIGHBYTE 'device stores the MSB in the Low byte, LSB in the High byte
AC3 = (AC3.LOWBYTE<<8) + AC3.HIGHBYTE
AC4 = (AC4.LOWBYTE<<8) + AC4.HIGHBYTE
AC5 = (AC5.LOWBYTE<<8) + AC5.HIGHBYTE
AC6 = (AC6.LOWBYTE<<8) + AC6.HIGHBYTE
B1 = (B1.LOWBYTE<<8) + B1.HIGHBYTE
B2 = (B2.LOWBYTE<<8) + B2.HIGHBYTE
MB = (MB.LOWBYTE<<8) + MB.HIGHBYTE
MC = (MC.LOWBYTE<<8) + MC.HIGHBYTE
MD = (MD.LOWBYTE<<8) + MD.HIGHBYTE

'Cast (convert) signed PBP Word vars to signed PBP Long vars where needed by math routines below
lAC1 = AC1 'copy word to long
IF AC1.15 THEN lAC1.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lAC2 = AC2 'copy word to long
IF AC2.15 THEN lAC2.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lAC3 = AC3 'copy word to long
IF AC3.15 THEN lAC3.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lMB = MB 'copy word to long
IF MB.15 THEN lMB.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

lMC = MC 'copy word to long
IF MC.15 THEN lMC.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

'Cast (convert) UN-signed PBP Word var to UN-signed PBP Long var for math routines below
lAC4 = AC4 'copy word to long, both unsigned


'Main loop
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
MAIN:

'Get Temp via I2C
I2C_Reg = $F4 '$F4 is the control register address
I2CWRITE I2C_SDA,I2C_SCL,$EE,I2C_Reg,[$2E] 'Write $2E to set temperature conversion
PAUSE 10 'Delay 10ms after each write
I2C_Reg = $F6 '$F6 is the result register MSB
I2CREAD I2C_SDA,I2C_SCL,$EF,I2C_Reg,[wTemp_Var1],I2C_error'Read temperature MSB, LSB.
lUTemp = wTemp_Var1 'copy word to long. Note BMP085 UT is NOT a signed value

'Calculate temperature in 1/10ths of Deg °C from lUTemp ' Note 2^15 = 32768 Dec or $8000
X1 = ((lUTemp - AC6) * AC5) / $8000 'Find X1.
X2 = (lMC * $800) / (X1 + MD) 'Find X2. Note:- math rounding results in X2 being in error by 1 ?
B5 = X1 + X2 'Find B5 from X1 and X2.
lCTemp = (B5 + 8) / 16 'Hey presto, lCTemp appears...

'Assign true temperature in °C in "x.x" format
X1 = lCTemp / 10 'find value above decimal point
X01 = lCTemp // 10 'Find decimal value


'Take 16 measures from the BMP085
lTemp_Var1 = 0 'Clear the last pressure reading
FOR bTemp_Var1 = 0 TO 15 'Start of 16x averaging routine
I2C_Reg = $F4 '$F4 is the control register address
I2CWRITE I2C_SDA,I2C_SCL,$EE,I2C_Reg,[$F4] 'Write $34+(oss << 6) to set pressure conversion
PAUSE OSS_Time 'Delay 10ms after each write (30mS for HiRes results (oss=3))
I2C_Reg = $F6 '$F6 is the result register MSB
I2CREAD I2C_SDA,I2C_SCL,$EF,I2C_Reg,[lUpres],I2C_error 'Read pressure MSB, LSB, XLSB, $F9 ($F9 not actually wanted).
lUpres = lUpres >> (16 - OSS_Res) 'remove $F9 from result (>>8), and left shift result back to 16 to 19 Bits (OSS value dependant)
lTemp_Var1 = lTemp_Var1 + lUpres
RawData(bTemp_Var1) = lUpres 'fill-up array for sorting & averaging
NEXT bTemp_Var1
lUpres = lTemp_Var1 / 16 'finish of the 10x Averaging routine


'Melanie's "sorting number" algorythm - ordonate data
bTemp_Var1 = 0
SortLoop:
IF RawData(bTemp_Var1 + 1) < RawData(bTemp_Var1) THEN
DataA = RawData(bTemp_Var1)
RawData(bTemp_Var1) = RawData(bTemp_Var1 + 1)
RawData(bTemp_Var1 + 1) = DataA
IF bTemp_Var1 > 0 THEN bTemp_Var1 = bTemp_Var1-2
ENDIF
bTemp_Var1 = bTemp_Var1 + 1
IF bTemp_Var1 < (ArraySize -1) THEN GOTO SortLoop
'display data array
'for bTemp_Var1 = 0 to (ArraySize -1)
' Serout2 S_TX,S_Bd_Rate,[dec2 bTemp_Var1, " ", dec rawdata(bTemp_Var1),LF]
'next


'**** Additional SAMPLING METHODS ****

'keep the eight middle values and average them
lTemp_Var2 = 0
FOR bTemp_Var1 = 4 TO 11
lTemp_Var2 = lTemp_Var2 + RawData(bTemp_Var1)
NEXT bTemp_Var1
lTemp_Var2 = lTemp_Var2 / 8


'keep Bottom 4 (B4) and top 4 (T4) and average them
lTemp_Var3 = 0
FOR bTemp_Var1 = 0 TO 3
lTemp_Var3 = lTemp_Var3 + RawData(bTemp_Var1)
NEXT bTemp_Var1
FOR bTemp_Var1 = 12 TO 15
lTemp_Var3 = lTemp_Var3 + RawData(bTemp_Var1)
NEXT bTemp_Var1
lTemp_Var3 = lTemp_Var3 / 8


'find the differences with the previous values
IF lUpres > Tempo1 THEN
Tempo1 = lUpres - Tempo1
ELSE
Tempo1 = Tempo1 - lUpres
ENDIF

IF lTemp_Var2 > Tempo2 THEN
Tempo2 = lTemp_Var2 - Tempo2
ELSE
Tempo2 = Tempo2 - lTemp_Var2
ENDIF

IF lTemp_Var3 > Tempo3 THEN
Tempo3 = lTemp_Var3 - Tempo3
ELSE
Tempo3 = Tempo3 - lTemp_Var3
ENDIF


'Display all data
SEROUT2 S_TX,S_Bd_Rate,["16/16 = ",DEC lUpres," Diff = ",DEC Tempo1, LF]
SEROUT2 S_TX,S_Bd_Rate,["Mid8/16 = ",DEC lTemp_Var2," Diff = ",DEC Tempo2, LF]
SEROUT2 S_TX,S_Bd_Rate,["B4+T4/16 = ",DEC lTemp_Var3," Diff = ",DEC Tempo3, LF]
SEROUT2 S_TX,S_Bd_Rate,["Temp = ",DEC X1,".",DEC X01,"°C",LF]
SEROUT2 S_TX,S_Bd_Rate,["Counter = ",DEC Counter,LF,CR]
PAUSE 1000

Tempo1 = lUpres
Tempo2 = lTemp_Var2
Tempo3 = lTemp_Var3
Counter = Counter + 1
TOGGLE LED 'flash the 'im alive' LED
GOTO MAIN


'Trap and display I2C problems
I2C_error:
SEROUT2 S_TX,S_Bd_Rate,["i2c bus read error",LF,CR]
PAUSE 2000
TOGGLE LED
GOTO MAIN:

Cal_error:
SEROUT2 S_TX,S_Bd_Rate,["i2c cal read error ",LF,CR]
PAUSE 2000
TOGGLE LED
GOTO MAIN:

END


...yes, it's quite cold in my lab :wink:

flotulopex
- 11th January 2012, 06:14
Here is the latest BMP085's datasheet (rev 1.3 - August 22nd 2011) (http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-06.pdf).

I need to understand how one can use this sensor and have a stable 0,1m reading. I just don't get it :dispirited:

Furthermore, what's the "rms noise" meaning?
6220

flotulopex
- 17th February 2012, 14:50
...really nobody can help?