I had the fortune to spend a half an uninterrupted day attempting to interface a Bosch BMP085 Barometric sensor to my Uno.
Along the way I encountered several issues some mine through lack of experience both with the sketch and with the interface.
Finallly however I had one last issue and that was my understanding of both the sketch, its components and a mistake.
The Sketch uses a header file for the BMP085 and this is where the problem is, I think. The primary issue is that the Sensor
is a 3 volt device and the Uno is a 5 volt device, where it becomes the main issue is that the master in an interconnection...
interface is that the 5 volt device must not pull the clock or data lines high, the pull-ups must not be over-ridden by the 5 volt
source as they will pull-up the 3.3 volt source to 5 volts I =E/R 5 -3.3 = 1.7 /4700 (2 10k pull-ups to 3.3 volt source) = 361 uA
enough to do the main problem here which was to pull up the 3.3 volt Vcc for the BMP085 to 5 volts damage the sensor?
I don't know as I didn't write the sketch, I modified the serial routines as I was using a Serial LCD (Backpack) and I changed
some character spacing, nothing more. I am a real noob to the Uni but I was an engineer for 20 years before I retired.
The thing that I think is missing is a caveat about the 3.3 volt source Not being capable of Sinking current. No common
regulator and few except servo'd ones can.
The real fix is, I think to fix the support files for the BMP085, to in the case of that sensor to not assert the CLK and DTA pins on the
IIc bus because it must work interchangeably between 5 volt and 3.3 volt devices. The devices must each control the pull-up resistors.
I finally realized what was going on and put a TIL431 on the 3.3 volt source and 'clamped' it to 3.3 volts. When I did that most of the
'noise' in my display went away I have a slowly rhythmic variation that seems (I think) to be an artifact to the CLK and DTA lines
being asserted by the Processor. Possibly some damage to the sensor but that is the cost of education and a small price to pay for
an interesting Sunday morning.
I think you made your point, and I agree with you. The I2C lines for a device at 3.3V while using internal pull-up resistors to +5V is not elegant. In every schematic I can found there are two external pull-up resistors to 3.3V. Or did you find a (very bad) schematic with two pull-up resistors to +5V ?
Please pardon the LONG windy post, I will try to do better in the future. No, I used a TIL431 to clamp the 3.3V source @3.3 V it doesn't however fix the issue. The pull-up information came from something I read from the Jeelabs??? site, I purchased the BMP085 from there. as to the pull ups it doesn't make sense to pull up a 3.3V device to 5 volts. I "Think" that if the Arduino was 'intended' to interface to 3.3V devices it can't assert the pins high for 'other' devices to pull low as required. The bus must "IMO" be pulled up externally and the devices pull down the DTA and CLK pins as required, The Arduino I/O should (again IMO) be passive pulling down the CLK line as required and the (in this case) BMP085 pull down the DTA line. At this point I want to point out that I an a complete IDIOT as far as sketches go, I make many mistakes and greatly enjoy figuring out how to do it right.
I am however an old (66 years and going strong) electronics engineer and I have a good bit of experience in analog and digital electronics. I was amazed that the Arduino Technical information didn't have that caveat about interfacing 5v and 3.3v devices. I used the sketch from my IDE samples by "// by Filipe Vieira" and frankly I don'r see how it could work, mine didn't. I drug out my Fluke 179 and started to examine what I had in front of me. I am using that "PHI Breakout" board so things are easily examined and modified. An examination with my Tektronics 2213 was even more enlightening. A 3.3V zener diode would have fixed the problem nicely, I didn't have one so I used a TIL431 however it still apparently doesn't do much more than band-aid the real issue. It is very possible that the sensor is damaged as the altitude measurements indicate that my house is 'Floating on a cloud and different than yesterday although the temp and baro are within 5% with the high def... measurements enabled in the sketch. Perhaps when I modified the sketch to use SoftwareSerial I did something wrong but other than formatting the printed data to fit on a 4X20 serial LCD Backpack at 19K baud, the temp and baro data track and are close (+/-5%). So now I need to go figure a solution. Perhaps the quickest way way would be schottky diodes 1N5711 or the HP 5082-... series of schottky diodes. Mosfets are are an issue for me as I don't own any that work well at 3.3V on the gate and then the data is inverted. No there are level translators that are called for here, a 74C906 is probably the preferred part, an open drain non inverting buffer with it's Vcc at 3.3V, at least the data sheet says so (no diode clamps on the outputs).
I have again gone on for far too long, again. However this is my information so far... Any Input???
Me again... the reference, http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1275738825 deals with it well. How can I modify my sketch and supporting files to do the same. I am using the includes in the original sketch, BMP085.h, wire.h and SoftwareSerial.h. Would posting the sketch help, as I said before I added the Software Serial and shortened up some lines of text and then added a 2 second delay at the end of the serial print statements so that the 'varying' data was readable, then loop() is resumed. I don't think the sketch is an issue here as it doesn't work now and when it was 'composed' there was something very different as I can't imagine it not being tested... Well.
For general information the TIL431 is an adjustable zener diode that will sink 100 ma from 1.25 to 36 Volts, only needs a 10K pot from cathode to ground wiper to the ref pin and a current limiting resistor from cathode to Vsupply, anode is grounded. It's a good general purpose part... not really for an electronics noob though.
Without level shifters, the digital inputs should be able to read from a 3.3V sensor.
Did you connect the sensor to the +3.3V of the Arduino ?
If you did, you can just add two pull-up resistors of about 10k to the +3.3V.
But you might change the sketch or the library to comment out the internal pull-up resistors of the Arduino. Or if that's not possible you might use an electronic clamping.
It would be helpful, if you upload a schematic of that.
But if you did connect the sensor to the +5V, it might be damaged.
Here is someone with the same problem for the I2C bus: Arduino Forum
I don't know what sketch you are referring to. Can you use more links so we know what you are referring to?
Just write the http link as text between spaces and without anything else.
I used the "Sample" from the Arduino IDE and I used the pull ups to the 3.3V 'reference" the real issue here is that there are 'protection' diodes from the I/O that go to the sensor Vcc... This pulls up the 3.3 Volt 'reference' to 5 Volts as the reference cannot sink current, only source 50 ma. I will try to include the sketch, I am not too sure about how to do it... Here Goes
// BMP085_test1
// by Filipe Vieira
// Simple test of BMP085 output using default settings.
// This example requires AUTO_UPDATE_TEMPERATURE to be true in bmp085.h otherwise temperature will not update.
// IMPORTANT!! To get correct values you MUST CHANGE init() parameters, in // Yes I know.
// Modified by R. K. Johnson Sr. 4/29/3012 this example I've set 82m based on Weather Station Altitude data for my location.
//
//
// #include <SoftwareSerial.h> // my addition #include <Wire.h> // this one is I think where the pull up occurs but I don't know enough yet to fix it #include <[BMP085.h>
//
BMP085 dps = BMP085(); // Digital Pressure Sensor
SoftwareSerial mySerial(2, 3);
Temperature = 0, Pressure = 0, Altitude = 0, Far =0, Pres = 0; // vars Far(enheit) and (Pres)sure added for conversions later
//
void setup(void) {
mySerial.begin(19200); // my addition.
Wire.begin();
delay(1000); wait for wire?
mySerial.print('\f''); // clear the screen
//
// uncomment for different initialization settings //dps.init(); // QFE (Field Elevation above ground level) is set to 0 meters.
// same as init(MODE_STANDARD, 0, true); //dps.init(MODE_STANDARD, 101850, false); // 101850Pa = 1018.50hPa, false = using Pa units
// this initialization is useful for normalizing pressure to specific datum.
// OR setting current local hPa information from a weather station/local airport (QNH).
dps.init(MODE_ULTRA_HIGHRES,8200, true); // 82 meters, true = using meter units (177')
// this initialization is useful if current altitude is...
// pressure will be calculated based on TruePressure and known altitude.
// note: use zeroCal only after initialization.
dps.zeroCal(101800, 0);
}
void loop(void) {
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
dps.getTemperature(&Temperature); // added as I begin to understand what is giong on
Far = (((Temperature * 1.8) + 32) / 10); // clumsy attempt to convert units... doesn't work as I intended
Pres = (.002953 * Pressure); // convert to IN/Hg? did I mess this thing up here?
mySerial.print[('\f''); // clear screen
mySerial.print("Alt (Cm):"); // formatted from original.
mySerial.print(Altitude); //This Bombs. the data is WAY out of line
mySerial.print('\n'); //again a clumsy fix...
mySerial.print("Pressure (In/Hg):"); // re formatted from original
mySerial. print (Pres);
mySerial. print ( "Temp (Deg. F):" );// re formatted from original
mySerial.print(Far);
delay(2000); // enough time to read the 'data'
}
This is the sketch I used and my changes are commented. I know there will be flames due to my lack of experience... I think that is the way we learn.
So Go for it... What did I do wrong.
I'm Sorry, I should have read ALL the references, I didn't, I have some 2N7000's they should do the job nicely But the clamp stays... for the foreseeable future, can't hurt.
For I2C level shifting this circuit from Philips is great: App note AN10441.pdf and an97055.pdf. I built one a while back and it's working well. Two 5 cent mosfets, 4 resistors, done. I used 2N7002P mosfets, 3.3K pull-ups on the 3.3V side and 4.7K pull-ups on the 5V side.
Yes Very Well Too, Thank You for the help. It's a Level translator like the input of an old TTL Logic gate. I had to look at it for a second before I saw how and the 'body' diode in TR2 was used for. Then I read the write-up. I haven't put it on the Arduino's 3.3v source yet... that's next but there is no way that it won't work. Now if I can figure out how to fix the jumping data, therm is Ok +/- 1 deg baro slowly changes around .5 millibars but the altimeter function is questionable I set the base altitude to about 50 meters below my real altitude... 100 meters so I would have something to look at... I get high... looking at how much my house is floating +/- 100 meters and I am beginning to think that the rough baro information needs some smoothing for noise, small random fluctuations are the cause of it all. I can understand a sketch well enough to work with it, frequently making errors... but I am not nearly good enough to 'figure' out how to do that as if as I suspect the altitude measurement is due to unfiltered baro data then it won't be can't be fixed in the sketch.
I do have to point out that it isn't Arduino's responsibility to provide marketable code, rather the opposite if this is to be a place of learning.
Finally I remember being on the Bosch site and this topic was mentioned, smoothing the baro data before calculating altitude, That was last year, December and I am an old man , my memory 'sometimes' takes a day or so to catch up.
Thank you One and ALL for the great Help.
Thank You Sir. That one "Condition is ALL that is really in the way of "Painless" interfacing... You can imagine how I felt when I found the 3V3 "Source" Floating @ about 5V... It would go a long way towards making things easier for those that don't have the equipment or skills necessary to find and "Fix" that issue and Particularly the NON 5V tolerant devices.