I2C with realtime clock DS1307 and Barometric Pressure Sensor - BMP085

orjanjan

New Member
Hi

I'm currently using the real time clock chip DS1307 on my weather station. I use the Picaxe 28x2 together with some temperature sensors and humidity. The clock communicates with I2C bus, and the whole system runs on 5v.
I just received a Barometric Pressure Sensor - BMP085 that i want to implement to the project, but I see that this chip requiers 3v.

- 1. How can I wire this? Is it possible to just reduce the power supply to the barometric pressure using a resistor, and then wire the I2C bus together with the clock?
- 2. Can anyone tell me ho to communicate with the barometric chip?


Thanks
 

g6ejd

Senior Member
Most of those chips are mounted on a duaghter board with 3.3and 5v inputs, is yours a bare chip. I run mine on a 5v system and it's running at 3.3 volts from a voltage regulator, it works fine as the switching threshold is well within the 3.3 v output spec. of the bmp085. There are some good examples of suitable code on this site, it looks complicated but when you get down to it is quite straightforward, you will need plenty of programme space though.

As the power consumption is so low you could utilise a couple of R to reduce 5 down to 3.3 with a capacitor at their junction to lower the source impedance.

Btw mine is on the same i2c bus as a 1307 but I'm using Arduino. It works fine. You will be using SCL and SDA linked together the addresses for the devices are preassigned at manufacture. Everything in parallel then.

Bmp085 has a very accurate temperature device too which can be handy.
 

westaust55

Moderator
I concur with JimPerry in the use of a couple of FETs for level shifting as per the Philips/NXP application note.

I have used this method successfully with two 2N7000 FETs.
 

orjanjan

New Member
Logic Level Converter

Simple FET level shifting would do the job see attached paper from Phillips. :D
Thanks for good information.
I found a page on internet "http://myquadcopterbuild.blogspot.no/2012/01/logic-level-converter-for-quadcopter.html" where the problem with different power consumption is addressed.
I'm not sure if i need resistors to tie down the bus, or if this is done on the chip.

Seams that one problem is about to be solved, but I still have not found any program code for the barometric pressure chip. The only code I find is C-code.
Does anyone know how to use this with picaxe and basic?

Thanks
 
Greetings forum members,
I have also purchased a BMP085 breakout board from Adafruit. And I also have a very similar setup as this gentleman Ørjan. The reason why I write to you is the following question: based on my searches of the forum:

1) Barometric-Pressure-sensor-BMP085-wrong-readings
2) BMP085-pressure-and-temperature-readings-via-a-28X2
3) ...and this one,

...I have concluded that nobody is using a smaller Picaxe than a 28x2 to tackle a BMP085. In your experience, is it possible to make it work with a 18X? Should I attempt it? Or would I be wasting my time?

Thank you all for your time.

Cheers!
Andrés
 
I found a page on internet "http://myquadcopterbuild.blogspot.no/2012/01/logic-level-converter-for-quadcopter.html" where the problem with different power consumption is addressed.
I'm not sure if i need resistors to tie down the bus, or if this is done on the chip.
I was going to suggest you use these: Sparkfun´s logic-level-converters They are very inexpensive but extremely helpful. However read the datasheet thouroughly. Not both lines (Tx and Rx) are bidirectional. However, they look the same as the one from the quadcopter blog.

Answering your question: I believe you need the pullup resistors for the bus regardless of the breakout board.

Cheers,
Andrés
 

BillBWann

Member
...I have concluded that nobody is using a smaller Picaxe than a 28x2 to tackle a BMP085. In your experience, is it possible to make it work with a 18X? Should I attempt it? Or would I be wasting my time?

Thank you all for your time.

Cheers!
Andrés
I have written the attached code for an 18M2. It doesn't use Jeremy Leach's 32 bit maths routines and only uses extended bit maths when required which is then hard coded. The code hasn't been fully tested (the code still contains the commented out debug lines) but it appears to work OK in practice (gives values similar to Excel) and does return the values used in the worked example in the BMP085 documentation sheet. It only uses 703 bytes but it does use more than 14 byte variables so wouldn't run on an 18X as is. The code wasn't optimized to minimize the variable count but it would probably be difficult to keep it below 14 - possibly use peek/pokes but could get pretty messy.

Code:
#rem
Reads the BMP085 breakout board and converts the readings to temperature & pressure.  The raw value of UT & UP are also displayed (order UT,T,UP,P).
#endrem


#terminal 4800
#picaxe 18m2
#no_data


hi2csetup i2cmaster, %11101110, i2cslow_8, i2cbyte  ; set up bmp085 i2c device
pause 100

'hi2cin $AA,(b3,b2) : sertxd("AA=",#w1,cr,lf)

lp:
'w1=23153	'ac6  -----------------------------------------------------
hi2cin $B4,(b3,b2)
pause 10
'w2=27898	'ut  -----------------------------------------------------
hi2cout $F4,($2E)
pause 50
hi2cin $F6,(b5,b4)
pause 10
'w2=24730	'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sertxd(#w2,", ")
'w3=32757	'ac5  -----------------------------------------------------
hi2cin $B2,(b7,b6)
pause 10
w4=w2-w1*2**w3
'sertxd("X1=",#w4,cr,lf)

'w1=-8711	'mc  -----------------------------------------------------
hi2cin $BC,(b3,b2)
pause 10
if w1>32768 then: w1=0-w1: endif

'w2=2868	'md --------------------------------------------------------
hi2cin $BE,(b5,b4)	'2432
pause 10

w2=w4+w2	'(x1+MD)
w3=w1/w2
for b0=1 to 11
	w3=w3*2
	w1=w1//w2*2
	w3=w1/w2+w3
next b0
'w3=w3+1/2	'round up last digit
'w1=-8711	'mc  -----------------------------------------------------
hi2cin $BC,(b3,b2)
pause 10
if w1>32768 then: w3=0-w3: endif
'sertxd("X2=",#w3,cr,lf)

w2=w3+w4
'sertxd("b5=",#w2,cr,lf)

w1=w2+8/16
sertxd(#w1,", ")
' --------------------------------------------
w3=w2-4000
'sertxd("b6=",#w3,cr,lf)

w5=w3
if w5>32768 then: w5=0-w5: endif
w5=w5*4
w5=w5**w5
w5=w5*4
'w6=4	'b2 ------------------------------------------------------------
hi2cin $B8,(b13,b12)
pause 10
w5=8*w6**w5
'sertxd("X1=",#w5,cr,lf)

'w4=-72	'ac2 ---------------------------------------------------------
hi2cin $AC,(b9,b8)
pause 10
w7=w4
if w4>32768 then: w7=0-w7: endif
w6=w3
if w6>32768 then: w6=0-w6: endif
w7=w7*8
w6=4*w6**w7
if w4<32768 or w3<32768 then: w6=0-w6: endif	'if either is positive then negate
'sertxd("X2=",#w6,cr,lf)

w7=w5+w6
'sertxd("X3=",#w7,cr,lf)

'w8=408	'ac1 ----------------------------------------------------------
hi2cin $AA,(b17,b16)
pause 10
w8=w8*4+w5+w6+2/4
'sertxd("B3=",#w8,cr,lf)

'w9=-14383	'ac3 ------------------------------------------------------
hi2cin $AE,(b19,b18)
pause 10
w9=0-w9	'assumes that this will always be negative
w10=w3
if w10>32768 then: w10=0-w10: endif
w5=w10*8**w9
'sertxd("X1=",#w5,cr,lf)

w9=w10*4
'w10=6190	'b1 ------------------------------------------------------------
hi2cin $B6,(b21,b20)
pause 10
w6=w9**w9**w10
'sertxd("X2=",#w6,cr,lf)

w7=w5+w6+2/4
'sertxd("X3=",#w7,cr,lf)

'w10=32741	'ac4 -------------------------------------------------------------
hi2cin $B0,(b21,b20)
pause 10
w9=32768+w7
w11=w9**w10
w10=w9*w10
w9=w11*2
w10=w10/32768
w9=w9+w10
'sertxd("B4=",#w9,cr,lf)

'w10=23843	'UP ----------------------------------------------------------------

'24730	213	40204	95329

hi2cout $F4,($F4)
pause 100
hi2cin $F6,(b21,b20)
pause 10
sertxd(#w10,", ")
'w10=40204	'++++++++++++++++++++++++++++++++++++++++++++++++++++++
w10=w10-w8
w8=w10**50000	'high word of B7
w7=w10*50000	'low word of B7
'sertxd("B7=",#w8," : ",#w7,cr,lf)

if w9>32768 then	'need to be able to double the divisor so halve it now
	w9=w9/2
	b1=1
else
	if w8<32768 then	'if can double B7 now, can maintain a higher accuracy
		b1=1
		w8=w8*2
		if w7<32768 then
			w7=w7*2
		else
			w7=w7*2
			w8=w8+1
		endif
	else
		b1=0	'remember that doubling hasn't happened so do it later
	endif
endif

'w2 will be the LS word of p, w3 will be the MS word
w3=0
w2=w8/w9
for b0=1 to 16
'sertxd ("B7/ ",#w8,", ",#w7,", ",#w3,", ",#w2,cr,lf)
	w3=w3*2
	if w2>32768 then: w3=w3+1: endif
	w2=w2*2
	w8=w8//w9*2
	if w7>32767 then: w8=w8+1: endif
	w7=w7*2
	w2=w8/w9+w2
next b0
'sertxd ("B7/ ",#w8,", ",#w7,", ",#w3,", ",#w2,cr,lf)

if b1=0 then
	w3=w3*2
	if w2<32768 then
		w2=w2*2
	else
		w2=w2*2
		w3=w3+1
	endif
endif

'sertxd("p=",#w3," : ",#w2,cr,lf)

b9=b6
b8=b5
w5=w4**w4
w4=w4*w4
'sertxd("X1=",#w5," : ",#w4,cr,lf)

w5=w5*3038
w5=w4**3038+w5
'sertxd("X1=",#w5,cr,lf)
	
w6=w3*7357
w6=w2**7357+w6
'w7=w2*7357
'sertxd ("low=",#w7,cr,lf)
'if w7<32768 then: w6=w6+1: endif	'because its a neg no, it trunctes opposite way

'sertxd("X2=",#w6,cr,lf)
	
w5=w5-w6+3791
'sertxd("W5=",#w5,cr,lf)

w7=w3
if w5>32768 then
	w5=0-w5/16
	w6=w2-w5
	if w6>w2 then: w7=w7-1: endif
else
	w5=w5/16
	w6=w2+w5
	if w6<w2 then: w7=w7+1: endif
endif
'sertxd("p=",#w7," : ",#w6,cr,lf)

b7=b14
b6=b13
b4=b12

bptr=28
b5=w3//10
@bptrinc=w2//10
w2=w2/10
w3=w3/10
b5=b6

do until w2=0
@bptrinc=w2//10
w2=w2/10
loop

bptr=bptr-1
'sertxd ("Pressure (Pa)= ")
do until bptr <28
sertxd (#@bptrdec)
loop
sertxd (",  ",#b24,cr,lf)
b24=b24+1
if b24=60 then: b24=0: endif
b25=b24//30
if b25=0 then
	sertxd ("--------------",cr,lf)
endif
'sertxd (cr,lf)
'sertxd (cr,lf)

'pause 500
goto lp
 
I have written the attached code for an 18M2.
[...]
It only uses 703 bytes but it does use more than 14 byte variables so wouldn't run on an 18X as is. The code wasn't optimized to minimize the variable count but it would probably be difficult to keep it below 14 - possibly use peek/pokes but could get pretty messy.
Hello Bill,
Thanks for sharing your code with me. So basically, YES it can be done with a smaller chip than the 28X2 but NO, not with a 18X due to limited variables. Cool. I will not get involved with peek/pokes because of my lack of proficiency with them. However, I have some 14M2 on their way home. I might try to get your code to work with one of them. If I make any progress I will let you know.
Cheers!
Andrés
 

westaust55

Moderator
It should be possible to use a 18X chip by some Judicial saving of byte variable values while other math is performed and re-use of the same set of 14 byte variables.
I did a similar programming excercise with a different (HopeRF) barometric pressure sensor using an 18X some time ago.
 
Last edited:

BillBWann

Member
I don’t know if anyone is currently using a variation of my program in #10 of this thread for extracting the temperature and pressure values from a BMP085 module but I’ve recently found a bug in it that makes the calculation wrong when the temperature is above 25 degrees.

To correct the program, search for the line of code “w5=w10*8**w9” and then copy

“if w3<=32768 then: w5=0-w5: endif” and paste it to the line below so that you end up with

Code:
w5=w10*8**w9
if w3<=32768 then: w5=0-w5: endif
Then search for the line of code "w7=w5+w6+2/4" which is only a couple of lines further down and REPLACE it with the 7 lines

Code:
w7=w5+w6+2
if w7>32768 then
	w7=0-w7/4
	w7=0-w7
else
	w7=w7/4
endif
For anyone starting out using one of these pressure modules, I’d recommend that you look at Alan’s thread here which appears to be thoroughly investigated by Alan and of course covers the more recently available modules.
 

hippy

Senior Member
Code:
w7=w5+w6+2
if w7>32768 then
	w7=0-w7/4
	w7=0-w7
else
	w7=w7/4
endif
If that is attempting to divide a positive or negative two's complement number by four, then the comparison should be "w7 >= 32768", "w7 >= $8000".

This is where #DEFINE macros can come in useful ...

Code:
#Define Negative(wVar) wVar >= $8000
#Define Positive(wVar) wVar <  $8000

If Negative(w7) Then
  w7 = -w7 / 4
  w7 = -w7
Else
  w7 = w7 / 4
End If
Likewise, if that -

Code:
w5=w10*8**w9
if w3<=32768 then: w5=0-w5: endif
is negating a positive two's complement value it should be <= 32767, < 32768, < $8000 ...

Code:
If Positive(w3) Then
  w5 = -w5
End If
There may be similar issues elsewhere in the earlier code.

You can, as above, just use "var = -var" rather than "var = 0-var" to do negation these days. That saves a little on memory space and increases execution speed.
 
Last edited:

BillBWann

Member
Thanks Hippy for all your example code but I’m concerned that I might be missing a point you’re trying to make.

I certainly get your points about negation not requiring a “0-”, about using macros if I was using PE6 (which I’m not at the moment) and that $8000 is a clearer representation of the median point of all 16 bit numbers than 32768. However you also seem to be suggesting that I might have a problem with both my new code and my existing code because I’m being a bit vague about when a number crosses from being positive to negative ( ie using < when it should be <= etc).

I really don’t think that this is a problem as I don’t expect any of these variables to ever be within cooee (an Australian expression) of 32768. If they were, the two’s complement variable would suddenly change from a very large positive number to a very large negative one (and vice versa) which would clearly be a problem in practice. In that situation, more than 16 bits would be required to represent the variable to stop that from occurring.

Have I missed something?
 

hippy

Senior Member
I really don&#8217;t think that this is a problem as I don&#8217;t expect any of these variables to ever be within cooee (an Australian expression) of 32768. If they were, the two&#8217;s complement variable would suddenly change from a very large positive number to a very large negative one (and vice versa) which would clearly be a problem in practice. In that situation, more than 16 bits would be required to represent the variable to stop that from occurring.

Have I missed something?
You are probably right; you will only encounter problems if your numbers were large positive or large negative values and if you won't ever have those it won't be problematic in practice.

It's more that it's "wrong" and it's generally best not to let wrongness persist.

That can particularly be the case for code put into the public domain as example code. In a couple of years time someone may ask what that code's doing, is it right ? And while someone may figure out it doesn't actually mater, that it's wrong can lead to doubt about the correctness of the rest.

There's also a risk that others may perpetuate that wrongness, do the same because that's how they saw it done somewhere else, when it does matter.
 
Top