BMP180 and EEPROM chip on i2c with pro mini problems

I have been working on an altimeter for my son's science fair project. I mocked the project up on a uno knock-off setting the board voltage at 3.3 volts, and a proto shield. I can hook the bmp180 and the EEPROM chip to the i2c bus and everything functions correctly. So I built a custom board to piggy back on the pro mini running at 3.3 volts and hook up the gnd, vcc, scl, and sda lines. With some test code I can write and read from the EEPROM but the sensor always reads the same pressure and temp no matter what. I have run the i2c scanner and it finds both devices. I thought my first attempt at the custom board was a bit mucky so I created a second board and it does the same thing.

I am wiring the custom board with 30awg kynar wire, do I need a larger gauge wire to handle the current and signal lines?

If the I2c scanner finds the devices does it mean the scl and sda lines are connected correctly?

There are resistors on the BMP180 sensor board but the sensor says that it will work with both 3.3 and 5v. Could the resistors be the issue? It seems not as I was running my proto board at 3.3 volts.

I am pulling my hair out. I even removed the sensor and replaced it with a second one I have, same issue. I then took the original sensor and put it back in my test rig and all worked fine.

Any suggestions

If the i2c scanner finds the devices, then the I2C bus is working.

To be able to pinpoint the problem, we need to know about everything: show us the sketch between code tags; can you make a photo of it ? which libraries do you use ? how did you install the libraries ? can you give a link to the modules that you use ? you have a Pro Mini running at 8MHz and 3.3V ? And you have selected that board in the Arduino IDE ?

The sketch I am using to test the bmp180 is below. It is code I copied from another forum post. It only uses the wire.h library. When I use this on my test bed the pressure reading changes when vacuum is applied. When I run the same sketch on the pro mini I get a constant pressure and wacky temperature numbers. I have switched up the scl and sda lines and it changes the reading but it is still constant wierd. I don't remember if I ran i2c scanner with the lines switched.

I am thinking about removing my custom board with both eeprom and bmp180 and attaching the bmp180 only to the ic2 and see if that helps.

I have conciously been choosing the pro mini at 3.3v when uploading the sketch but I have done this so many times and switched back and forth between the test bed and my pro mini that it is possible that I forgot one time and that is the issue. I will check that tonight.

/**********************************************************
Bosch Pressure Sensor BMP085 / BMP180 readout routine
for the Arduino platform.

Compiled by Leo Nutz

**********************************************************/

#include <Wire.h>

#define ADDRESS_SENSOR 0x77 // Sensor address

int16_t ac1, ac2, ac3, b1, b2, mb, mc, md; // Store sensor PROM values from BMP180
uint16_t ac4, ac5, ac6; // Store sensor PROM values from BMP180
// Ultra Low Power OSS = 0, OSD = 5ms
// Standard OSS = 1, OSD = 8ms
// High OSS = 2, OSD = 14ms
// Ultra High Resolution OSS = 3, OSD = 26ms
const uint8_t oss = 3; // Set oversampling setting
const uint8_t osd = 26; // with corresponding oversampling delay

float T, P; // Set global variables for temperature and pressure

void setup()
{
Serial.begin(9600); // Set up serial port
while(!Serial){;} // waith until leonardo serial port ready
delay(5000);
Wire.begin(); // Activate I2C

init_SENSOR(); // Initialize baro sensor variables
delay(100);
}

void loop()
{
int32_t b5;

b5 = temperature(); // Read and calculate temperature (T)

Serial.print("Temperature: ");
Serial.print(T, 2);
Serial.print(" C, ");
Serial.print(1.8 * T + 32.0, 2);
Serial.println(" F");

P = pressure(b5); // Read and calculate pressure (P)

Serial.print("Pressure: ");
Serial.print(P, 2);
Serial.print(" mbar, ");
Serial.print(P * 0.0295299830714, 2);
Serial.println(" inHg");
Serial.println("");

delay(500); // Delay between each readout

}

/**********************************************
Initialize sensor variables
**********************************************/
void init_SENSOR()
{
ac1 = read_2_bytes(0xAA);
ac2 = read_2_bytes(0xAC);
ac3 = read_2_bytes(0xAE);
ac4 = read_2_bytes(0xB0);
ac5 = read_2_bytes(0xB2);
ac6 = read_2_bytes(0xB4);
b1 = read_2_bytes(0xB6);
b2 = read_2_bytes(0xB8);
mb = read_2_bytes(0xBA);
mc = read_2_bytes(0xBC);
md = read_2_bytes(0xBE);

Serial.println("");
Serial.println("Sensor calibration data:");
Serial.print(F("AC1 = ")); Serial.println(ac1);
Serial.print(F("AC2 = ")); Serial.println(ac2);
Serial.print(F("AC3 = ")); Serial.println(ac3);
Serial.print(F("AC4 = ")); Serial.println(ac4);
Serial.print(F("AC5 = ")); Serial.println(ac5);
Serial.print(F("AC6 = ")); Serial.println(ac6);
Serial.print(F("B1 = ")); Serial.println(b1);
Serial.print(F("B2 = ")); Serial.println(b2);
Serial.print(F("MB = ")); Serial.println(mb);
Serial.print(F("MC = ")); Serial.println(mc);
Serial.print(F("MD = ")); Serial.println(md);
Serial.println("");
}

/**********************************************
Calcualte pressure readings
**********************************************/
float pressure(int32_t b5)
{
int32_t x1, x2, x3, b3, b6, p, UP;
uint32_t b4, b7;

UP = read_pressure(); // Read raw pressure

b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;
b3 = (((uint32_t)(ac1 * 4 + x3) << oss) + 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 >> oss);
if(b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } // or p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
return (p + ((x1 + x2 + 3791) >> 4)) / 100.0f; // Return pressure in mbar
}

/**********************************************
Read uncompensated temperature
**********************************************/
int32_t temperature()
{
int32_t x1, x2, b5, UT;

Wire.beginTransmission(ADDRESS_SENSOR); // Start transmission to device
Wire.write(0xf4); // Sends register address
Wire.write(0x2e); // Write data
Wire.endTransmission(); // End transmission
delay(5); // Datasheet suggests 4.5 ms

UT = read_2_bytes(0xf6); // Read uncompensated TEMPERATURE value

// Calculate true temperature
x1 = (UT - (int32_t)ac6) * (int32_t)ac5 >> 15;
x2 = ((int32_t)mc << 11) / (x1 + (int32_t)md);
b5 = x1 + x2;
T = (b5 + 8) >> 4;
T = T / 10.0; // Temperature in celsius
return b5;
}

/**********************************************
Read uncompensated pressure value
**********************************************/
int32_t read_pressure()
{
int32_t value;
Wire.beginTransmission(ADDRESS_SENSOR); // Start transmission to device
Wire.write(0xf4); // Sends register address to read from
Wire.write(0x34 + (oss << 6)); // Write data
Wire.endTransmission(); // SEd transmission
delay(osd); // Oversampling setting delay
Wire.beginTransmission(ADDRESS_SENSOR);
Wire.write(0xf6); // Register to read
Wire.endTransmission();
Wire.requestFrom(ADDRESS_SENSOR, 3); // Request three bytes
if(Wire.available() >= 3)
{
value = (((int32_t)Wire.read() << 16) | ((int32_t)Wire.read() << 8) | ((int32_t)Wire.read())) >> (8 - oss);
}
return value; // Return value
}

/**********************************************
Read 1 byte from the BMP sensor
**********************************************/
uint8_t read_1_byte(uint8_t code)
{
uint8_t value;
Wire.beginTransmission(ADDRESS_SENSOR); // Start transmission to device
Wire.write(code); // Sends register address to read from
Wire.endTransmission(); // End transmission
Wire.requestFrom(ADDRESS_SENSOR, 1); // Request data for 1 byte to be read
if(Wire.available() >= 1)
{
value = Wire.read(); // Get 1 byte of data
}
return value; // Return value
}

/**********************************************
Read 2 bytes from the BMP sensor
**********************************************/
uint16_t read_2_bytes(uint8_t code)
{
uint16_t value;
Wire.beginTransmission(ADDRESS_SENSOR); // Start transmission to device
Wire.write(code); // Sends register address to read from
Wire.endTransmission(); // End transmission
Wire.requestFrom(ADDRESS_SENSOR, 2); // Request 2 bytes from device
if(Wire.available() >= 2)
{
value = (Wire.read() << 8) | Wire.read(); // Get 2 bytes of data
}
return value; // Return value
}

What do you mean, you switched up the scl and sda lines ?

I don't know if the code is good, and it does not check for a bus or sensor error. If something is wrong, the 'value' is still returned by the function, and in that case it could be anything, even the previous contents of 'value'.
All those numbers and shifting has to be done perfectly right. I can not verify that your code is okay.

To help more, I would like answers to my questions in my Reply #1, and I have more questions after that :o

You could print an error if there is I2C problem for every Wire.requestFrom(), like this:

Wire.requestFrom(ADDRESS_SENSOR, 1);            // Request data for 1 byte to be read
  if(Wire.available() >= 1)
  {
    value = Wire.read();                          // Get 1 byte of data
  }
  else
  {
    Serial.println("Wire.requestFrom error!");   // this should never happen
  }

Number 7 on this page is about code tags : http://forum.arduino.cc/index.php/topic,148850.0.html
After you made a change, I would still like to see the whole sketch again.

Ok

So I found my problem. I started by using the example code in the adafruit library and compiling it using different settings. My knock off pro mini has selectable voltage and even though the jumpers are set for 3.3v I didn't get correct results until i compiled it using the 328 5v 16Mhz setting. Once compiled correctly my real program began yielding the results I expected. I have also run the pro-mini with my 3.7v battery source and get the same results.

This was a learning experience, I didn't know the compiler settings would have this effect.

So the bottom line is that my custom board works perfectly both the eeprom and the altitude sensor and I am well on the way to getting my code debugged and functioning correctly.

It was your comment about knowing how I compiled the code that got me to trying different settings. Thanks for the help.

My current code is a significant modification of the code for the Bear Alti-Multi found here

Well yes, if code is compiled for 8MHz and run at 16MHz (or vice versa) it probably won't run very well or not at all. The official Pro Mini is either 16MHz 5V or else 8MHz 3.3V.

I hope you do not use the "Rocket Flight Logger", and don't use it as an example. I don't see decoupling capacitors of 100nF. The first rule for designing electronics with microcontrollers is using 100nF decoupling capacitor(s).

Can you post a link of where you got your pro-mini? If it has a select switch, does it also have two crystals?