Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 14:39 02 May 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 : Micromite MK2: BMP180 pressure sensor

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 04:12am 19 Nov 2014
Copy link to clipboard 
Print this post

I'm converting a bunch of code from picaxe to micromite. Basically, given the new features in the micromite version 4.6, I'm going to give up using the larger picaxe chips. The smaller 08M2 and 14M2 will still have a use but I can no longer see any reason to use any of the bigger ones.
Given that I will slowly convert some of my picaxe code across. To handle the BMP180 pressure and temperature sensor on the picaxe required writing a multiple precision integer library for it (works but slow). On the micromite it is trivial .
If is is useful I will post code as I convert, but please let me know if I am just jamming up the board. I think it would be useful to have a separate forum for code snippets and complete programs - any chance?

I've used a couple of trivial cFunctions in the code (really just because they are available, the c code is included as comments) but it could easily have been done just in basic.

Best Regards

Peter

cpu 48
OPTION EXPLICIT
OPTION DEFAULT INTEGER
const i2caddr=&B1110111
const MS7=7 'set default wait period
const signed=1
const unsigned=0
'
dim i2cin$ length 8 'max size for integer conversion
dim UT,UP,i,j
dim ac1,ac2,ac3,ac4,ac5,ac6,b1,b2,mb,mc,md 'bmp180 parameters
dim x1,x2,b5,b6,x3,b3,b4,b7,OSS
dim temperature,pressure
DIM altitude as float
dim OSSdata(4)
dim OSSscale(4)
I2C OPEN 100,1000
init:
OSS=1 'set oversampling ratio
' OSS=0 ' Uncomment this line to check algorithm against datasheet
OSSdata(0)=&H34
OSSdata(1)=&H74
OSSdata(2)=&HB4
OSSdata(3)=&HF4
OSSscale(0)=1
OSSscale(1)=2
OSSscale(2)=4
OSSscale(3)=8
I2C WRITE i2caddr,1,1,&HAA 'send read calibration data command
I2C READ i2caddr,0,22,i2cin$() 'read in calibration data
ac1=intconv(mid$(i2cin$,1,2),signed)
ac2=intconv(mid$(i2cin$,3,2),signed)
ac3=intconv(mid$(i2cin$,5,2),signed)
ac4=intconv(mid$(i2cin$,7,2),unsigned)
ac5=intconv(mid$(i2cin$,9,2),unsigned)
ac6=intconv(mid$(i2cin$,11,2),unsigned)
b1=intconv(mid$(i2cin$,13,2),signed)
b2=intconv(mid$(i2cin$,15,2),signed)
mb=intconv(mid$(i2cin$,17,2),signed)
mc=intconv(mid$(i2cin$,19,2),signed)
md=intconv(right$(i2cin$,2),signed)
'
' Uncomment this block to check algorithm against datasheet
'
' AC1=408
' AC2=-72
' AC3=-14383
' AC4=32741
' AC5=32757
' AC6=23153
' B1=6190
' B2=4
' MB=-32768
' MC=-8711
' MD=2868

main:
I2C WRITE i2caddr,0,2,&HF4,&H2E 'send temp conversion
pause MS7 'wait for temperature conversion
I2C WRITE i2caddr,1,1,&HF6 'send read data
I2C READ i2caddr,0,2,i2cin$() 'read 2 bytes
UT=intconv(i2cin$,unsigned)
' UT=27898 ' Uncomment this line to check algorithm against datasheet
I2C WRITE i2caddr,0,2,&HF4,ossdata(oss) 'send pressure conversion
pause (oss+1)*ms7 'wait for the pressure conversion
I2C WRITE i2caddr,1,1,&HF6 'send read data
I2C READ i2caddr,0,3,i2cin$() 'read 3 bytes
UP=intconv(i2cin$,unsigned)
up=up>>(8-oss) 'scale the output by the number of unused bits in the xlsb byte
' UP=23843' Uncomment this line to check algorithm against datasheet
calc_temp
calc_pressure
print "Temperature = ",str$(temperature/10,4,1),"Deg C"
print "Local Pressure = ",str$(pressure/100,4,1),"Hectopascal/Mb"
input "Altitude in meters? ",Altitude
print "Sea level pressure = ",str$(pressure/((1-(altitude/44330))^5.255)/100,4,1),"Hecto pascal/Mb"
end
'
' calc_temperature: calculate the temperature from the raw temperature given the calibration parameters
'
sub calc_temp:
X1=(UT-AC6)*AC5\powerof2(15)
X2=MC*powerof2(11)/(X1+MD) 'This needs to be a floating divide to match the datasheet
B5=X1+X2
temperature=(B5+8)\powerof2(4)
end sub
'
' calc_pressure: calculate the pressure from the raw pressure given the calibration parameters and temperature output
'
sub calc_pressure:
B6=b5-4000
x1=(b2*(b6*b6/powerof2(12)))\powerof2(11)
x2=ac2*b6\powerof2(11)
x3=x1+x2
b3=(((ac1*4+x3)*ossscale(oss))+2)\4
X1=AC3*B6\POWEROF2(13)
X2=(B1*(B6*B6/POWEROF2(12)))\POWEROF2(16)
x3=((x1+x2)+2)\4
b4=ac4*(abs(x3+32768))\powerof2(15)
b7=abs(up-b3)*(50000\ossscale(oss))
pressure=(b7*2)\b4
x1=(pressure\powerof2(8))*(pressure\powerof2(8))
x1=(x1*3038)\powerof2(16)
x2=(-7357*pressure)\powerof2(16)
pressure=pressure+(x1+x2+3791)\powerof2(4)
end sub
'
'cFunctions source and binary
'
'unsigned long long intconv(unsigned char innumber[],unsigned int *signednum){
' int i,j;
' union utype{
' unsigned long long b;
' unsigned char a[8];
' }u;
' u.b=0;
' j=innumber[0];//get the number of bytes
' for(i=1;i<=innumber[0];i++)u.a[j-i] =innumber;
' if (*signednum){i=u.a[j-1] & 0x80;//get the top bit
' if(i){
' for( ;j<=7;j++)u.a[j]=0xFF;//sign extend
' }
' }
' return u.b;
'}
'unsigned long long powerof2(unsigned int *power){
' int octet,place;
' union utype{
' unsigned long long b;
' unsigned char a[8];
' }u;
' u.b=0;
' octet=*power/8;
' place=*power-(octet*8);
' u.a[octet]=1<<place;
' return u.b;
'}'
CFunction intconv
00000000
27bdfff8 00001021 00001821 afa20000 afa30004 90880000 1900000b 01003821
2503ffff 03a31821 24020001 00823021 90c60000 a0660000 24420001 00e2302a
10c0fffa 2463ffff 8ca20000 1040000d 03a81021 9042ffff 30420080 10400009
29020008 10400007 03a81021 27a40008 2403ffff a0430000 24420001 5444fffe
a0430000 8fa20000 8fa30004 03e00008 27bd0008
End CFunction
'
CFunction powerof2
00000000
27bdfff8 00001021 00001821 afa20000 afa30004 8c820000 000218c2 03a32021
000318c0 00431023 24030001 00431004 a0820000 8fa20000 8fa30004 03e00008
27bd0008
End CFunction
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 05:03am 19 Nov 2014
Copy link to clipboard 
Print this post

Go for it. The more code there is in the public domain, the better.

Peter
The only Konstant is Change
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1133
Posted: 05:12am 19 Nov 2014
Copy link to clipboard 
Print this post

Hello PeterM,

I didn't try, but the code looks good! Well done!
I think many (!) people appreciate your examples.
If I had a wish free, then I would have a separate forum for bug reporting only. (beta testers).

Regards
Michael

Edit:
@Peter C., full ack!Edited by twofingers 2014-11-20
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1328
Posted: 01:14am 20 Nov 2014
Copy link to clipboard 
Print this post

@matherp,
I've just ordered a BMP180 module Peter and I'm looking forward to be able to give your code a go when the module arrives - unfortunately that's usually 3 or 4 weeks away. At least it'll give me time to (hopefully) get my head around the conversion to altitude because I'd like to check it against the altimeter in my brother-in-law' light plane when I visit them early next year.

Greg
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 12:33am 22 Nov 2014
Copy link to clipboard 
Print this post

paceman

The routines for converting measured pressure (Hpa) to altitude (in feet) given a known sea-level pressure are:


function calcaltitude(sealevelpressure, localpressure)
calcaltitude=((10^(log10(localpressure/sealevelpressure)/5.2 558797))-1)/-6.8755856 *1000000
end function
'
function log10(x)
log10=log(x)/2.302585093
end function



You will see that the calcaltitude function is independent of the pressure units as it only relies on the ratio of pressures.

There is bug in 4.6b21 that Geoff knows about relating to passing floats to functions when OPTION DEFAULT INTEGER is defined so these routines can only currently be used if the default datatype is FLOAT

To get round this I've modified the original program to work by explicitly defining all the integer variables using the % syntax. I've also included the altitude calculation code and the program now derives your altitude from the current sea-level pressure (in aviation this is known as QNH). This is attached below.

This should be more useful for your test

Best Regards

Peter

cpu 48
OPTION EXPLICIT
OPTION DEFAULT FLOAT
const i2caddr=&b1110111
const MS7=7 'set default wait period
const signed=1
const unsigned=0
'
dim i2cin$ length 8 'max size for integer conversion
dim UT%,UP%
dim ac1%,ac2%,ac3,ac4%,ac5%,ac6%,b1%,b2%,mb%,mc%,md% 'bmp180 parameters
dim x1%,x2%,b5%,b6%,x3,b3%,b4%,b7%,OSS%
dim temperature%,pressure%
DIM altitude,QNH,pressureinHpa
dim OSSdata%(4)
dim OSSscale%(4)
I2C OPEN 400,1000
init:
OSS%=1 'set oversampling ratio
' OSS%=0 ' Uncomment this line to check algorithm against datasheet
OSSdata%(0)=&H34 'commands to sample pressure% with different levels of oversampling
OSSdata%(1)=&H74
OSSdata%(2)=&Hb4
OSSdata%(3)=&HF4
OSSscale%(0)=1 'scale factors for calcs when oversampled
OSSscale%(1)=2
OSSscale%(2)=4
OSSscale%(3)=8
'
I2C WRITE i2caddr,1,1,&HAA 'send read calibration data command
I2C READ i2caddr,0,22,i2cin$() 'read in calibration data
ac1%=intconv(mid$(i2cin$,1,2),signed)
ac2%=intconv(mid$(i2cin$,3,2),signed)
ac3=intconv(mid$(i2cin$,5,2),signed)
ac4%=intconv(mid$(i2cin$,7,2),unsigned)
ac5%=intconv(mid$(i2cin$,9,2),unsigned)
ac6%=intconv(mid$(i2cin$,11,2),unsigned)
b1%=intconv(mid$(i2cin$,13,2),signed)
b2%=intconv(mid$(i2cin$,15,2),signed)
mb%=intconv(mid$(i2cin$,17,2),signed)
mc%=intconv(mid$(i2cin$,19,2),signed)
md%=intconv(right$(i2cin$,2),signed)
'
' Uncomment this block to check algorithm against datasheet
'
' ac1%=408
' ac2%=-72
' AC3=-14383
' ac4%=32741
' ac5%=32757
' ac6%=23153
' b1%=6190
' b2%=4
' mb%=-32768
' mc%=-8711
' md%=2868

main:
I2C WRITE i2caddr,0,2,&HF4,&H2E 'send temp conversion
pause MS7 'wait for temperature% conversion
I2C WRITE i2caddr,1,1,&HF6 'send read data
I2C READ i2caddr,0,2,i2cin$() 'read 2 bytes
UT%=intconv(i2cin$,unsigned)
' UT%=27898 ' Uncomment this line to check algorithm against datasheet
I2C WRITE i2caddr,0,2,&HF4,ossdata%(oss%) 'send pressure% conversion
pause (oss%+1)*ms7 'wait for the p ressure% conversion
I2C WRITE i2caddr,1,1,&HF6 'send read data
I2C READ i2caddr,0,3,i2cin$() 'read 3 bytes
UP%=intconv(i2cin$,unsigned)
UP%=UP%>>(8-oss%) 'scale the oUT%pUT% by the numb%er of unused bits in the xlsb byte
' UP%=23843' Uncomment this line to check algorithm against datasheet
calc_temp
calc_pressure
pressureinHpa=pressure%/100
print "Temperature = ",str$(temperature%/10,4,1),"Deg C"
print "Local pressure = ",str$(pressure%/100,4,1),"Hectopascal/mb"
inpUT "QNH in Hpa/Mb ? ",QNH
altitude=calcaltitude(QNH,pressureinHpa)
print "Current altitude in feet = ",altitude
print "Reverse calculate Sea level pressure = ",calcQNH(altitude,pressureinHpa),"Hectopascal/mb"
end
'
' calc_temperature%: calculate the temperature% from the raw temperature% given the calibration parameters
'
sub calc_temp:
x1%=(UT%-ac6%)*ac5%\powerof2(15)
x2%=mc%*powerof2(11)/(x1%+md%) 'This needs to be a floating divide to match the datasheet
b5%=x1%+x2%
temperature%=(b5%+8)\powerof2(4)
end sub
'
' calc_pressure: calculate the pressure% from the raw pressure% given the calibration parameters and temperature% oUT%pUT%
'
sub calc_pressure
b6%=b5%-4000
x1%=(b2%*(b6%*b6%/powerof2(12)))\powerof2(11)
x2%=ac2%*b6%\powerof2(11)
x3=x1%+x2%
b3%=(((ac1%*4+x3)*ossscale%(oss%))+2)\4
x1%=AC3*b6%\POWEROF2(13)
x2%=(b1%*(b6%*b6%/POWEROF2(12)))\POWEROF2(16)
x3=((x1%+x2%)+2)\4
b4%=ac4%*(abs(x3+32768))\powerof2(15)
b7%=abs(UP%-b3%)*(50000\ossscale%(oss%))
pressure%=(b7%*2)\b4%
x1%=(pressure%\powerof2(8))*(pressure%\powerof2(8))
x1%=(x1%*3038)\powerof2(16)
x2%=(-7357*pressure%)\powerof2(16)
pressure%=pressure%+(x1%+x2%+3791)\powerof2(4)
end sub
'
FUNCTION calcQNH(currentaltitude,localpressure)
calcQNH=(localpressure*100)/((1-(currentaltitude*0.3048/4433 0))^5.255)/100
end function
'
function log10(x)
log10=log(x)/2.302585093
end function
'
function calcaltitude(sealevelpressure, localpressure)
local a as float, b as float
calcaltitude=((10^(log10(localpressure/sealevelpressure)/5.2 558797))-1)/-6.8755856 *1000000
end function
'
'cFunctions source and binary
'
'unsigned long long intconv(unsigned char innumb%er[],unsigned int *signednum){
' int i,j;
' union UT%ype{
' unsigned long long b;
' unsigned char a[8];
' }u;
' u.b=0;
' j=innumb%er[0];//get the numb%er of bytes
' for(i=1;i<=innumb%er[0];i++)u.a[j-i] =innumb%er;
' if (*signednum){i=u.a[j-1] & 0x80;//get the top bit
' if(i){
' for( ;j<=7;j++)u.a[j]=0xFF;//sign extend
' }
' }
' return u.b;
'}
'unsigned long long powerof2(unsigned int *power){
' int octet,place;
' union UT%ype{
' unsigned long long b;
' unsigned char a[8];
' }u;
' u.b=0;
' octet=*power/8;
' place=*power-(octet*8);
' u.a[octet]=1<<place;
' return u.b;
'}'
CFunction intconv
00000000
27bdfff8 00001021 00001821 afa20000 afa30004 90880000 1900000b 01003821
2503ffff 03a31821 24020001 00823021 90c60000 a0660000 24420001 00e2302a
10c0fffa 2463ffff 8ca20000 1040000d 03a81021 9042ffff 30420080 10400009
29020008 10400007 03a81021 27a40008 2403ffff a0430000 24420001 5444fffe
a0430000 8fa20000 8fa30004 03e00008 27bd0008
End CFunction
'
CFunction powerof2
00000000
27bdfff8 00001021 00001821 afa20000 afa30004 8c820000 000218c2 03a32021
000318c0 00431023 24030001 00431004 a0820000 8fa20000 8fa30004 03e00008
27bd0008
End CFunction
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1328
Posted: 04:06am 22 Nov 2014
Copy link to clipboard 
Print this post


Excellent Peter, that'll save me some serious headaches. Do you know how much QNH might typically change on say a one hour flight at 100 knots. I'm thinking of one airfield in Tasmania (42oS) to another. Do altimeters have a real time update of QNH from met stations via GPS coordinates e.g.

Greg
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 04:32am 22 Nov 2014
Copy link to clipboard 
Print this post

QNH is typically reported by each airfield you talk to on route and it is up to the pilot to update the alimeter. Normal days, within 1 hour, you are unlikely to see it move by more than 1 or 2Hpa. If a front is approaching you may see more but you probably shouldn't be flying in the first place! In terms of user interface, two switches for up and down would be ideal. Press both together to set 1013.25 which is what you fly at in the "flight levels". In the UK this would be above what is called the transition altitude or 3000ft. I don't know the height of the transition altitude in Tasmania so can't help on that.

Best Regards

Peter
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 09:01am 22 Nov 2014
Copy link to clipboard 
Print this post

  paceman said  
Excellent Peter, that'll save me some serious headaches. Do you know how much QNH might typically change on say a one hour flight at 100 knots. I'm thinking of one airfield in Tasmania (42oS) to another. Do altimeters have a real time update of QNH from met stations via GPS coordinates e.g.

Greg

Greg

Even if you don't get reports from the airfield you can get some info about the area you are flying by looking here. http://www.bom.gov.au/tas/observations/tasall.shtml
On that page you can click on a location and that will take you to a details page which includes QNH and MSL calculations. Most of these readings are every 30 minutes so you can see the trend. READ THE HELP so you will understand what it all means.

Another useful set of pages are the weather radar. http://www.bom.gov.au/products/national_radar_sat.loop.shtml As you can see, Tasmania has two radar stations. Click on the one that interests you and zoom in or out as needed. On this page tick the box for Weather Observations. It will give you local (somewhat) wind strength and direction.

If you want the big picture then see this one. http://www.bom.gov.au/australia/charts/synoptic_col.shtml Use the toolbar just above the map to see the progress of the weather fronts.

There are similar reports for many parts of Australia.

Bob

Edit: for those who may be interested in weather on a large scale this may be useful http://earth.nullschool.net/#current/wind/surface/level/orth ographic=149.26,-41.86,3000 You can zoom in and out. Click on the word EARTH for options. Drag it to your part of the world.
Edited by BobD 2014-11-23
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5909
Posted: 12:00pm 22 Nov 2014
Copy link to clipboard 
Print this post

  paceman said  
Excellent Peter, that'll save me some serious headaches. Do you know how much QNH might typically change on say a one hour flight at 100 knots. I'm thinking of one airfield in Tasmania (42oS) to another. Do altimeters have a real time update of QNH from met stations via GPS coordinates e.g.

Greg


I used to listen to the beacons transmitted by the local airports. They gave the up-to-date weather info. It's been a while and they might have been replaced with something more high tech by now.
I think if you check the destination airport before taking off, not a lot will change by the time you arrive.

The BMP180 is identical to the BMP085 code wise. The only difference I can see is better accuracy for pressure with the BMP180.

The code I use for the BMP085 is on my micromite test server at tassyjim.ddns.net port 3002.

It was written well before we had integers to play with.

I use metres for altitude.

FUNCTION myAlt(p, p0)
' given local pressure (p) and pressure at sea level (p0)
' returns altitude in metres
myAlt = 44330*(1-(p/p0)^0.1903)
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


Jim

VK7JH
MMedit   MMBasic Help
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5909
Posted: 01:19pm 22 Nov 2014
Copy link to clipboard 
Print this post

I forgot to mention that the test micromite mentioned above is accessed by Telnet, not http.

Use TeraTerm or MM Edit.

There is a difference in temperature of about 2 degrees between the BMP085 and the DHT22. I believe the DHT22.

If you are using MMEdit, you can easily download the program, using TeraTerm, ^C then LIST.

Jim
VK7JH
MMedit   MMBasic Help
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1328
Posted: 02:17am 23 Nov 2014
Copy link to clipboard 
Print this post


@matherp,
OK - but talking to the airfields often won't be an option because a lot of the Tassie airfields we might use won't be manned. In fact the one we'll leave from is a levelled paddock at the back of a house - sometimes with sheep on it! Fronts are a pretty common thing in Tassie too (good ol' roaring 40's) but you're right, stay home if one's coming.
Re the 'transition level' etc - the pilot/owner-builder is my brother-in-law and he'll know all that stuff - hopefully I might query him about it first and not go if the answers don't seem convincing!
Thanks for the suggestion re just up/down switches - that makes it pretty simple.

@BobD,
Yes, the bom.gov.au site was where I thought I'd be chasing it up. The Packet Weather app on the smartphone feeds BOM info including the radars in real time, and you can get real time wind speed/direction for whatever met station you set. Not sure what 3G/4G reception would be like in the 'plane but there's always the radio and no doubt the bigger airports, Launceston, Devonport etc could fill you in.

@TassyJim,
I'd forgotten about beacons Jim - we used to listen to them during yacht races in Bass Strait and navigate with them using an RDF unit. That was the early 70's I think, or maybe late-ish 60's I'll have a go at downloading from your Telnet ddns, I've been intending to try that for awhile and hadn't gotten around to it.

Greg
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5909
Posted: 10:39am 23 Nov 2014
Copy link to clipboard 
Print this post

  paceman said  
I'll have a go at downloading from your Telnet ddns, I've been intending to try that for awhile and hadn't gotten around to it.

Greg

The code is also here:
http://www.thebackshed.com/forum/forum_posts.asp?TID=7080&PN =4


@matherp,
It is really good to see your posts. It helps to see code converted from other versions of Basic (and C etc). It is usually easier to adapt someones working code than it is to start from nothing.
So if you have any more devices you are talking to.....

JimEdited by TassyJim 2014-11-24
VK7JH
MMedit   MMBasic Help
 
Print this page


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

© JAQ Software 2024