Program fails after importing the Wire library

I am building a data logger for a weather balloon and I have been having software issues. My setup takes data from an Adafruit GPS board, a DHT22 (temperature/humidity sensor), and a BMP180 (pressure sensor), then logs it to an SD card. Everything worked as expected without the BMP180, but when I tried to make my program collect data from it, it started acting strangely. For example, it would skip lines of code or suddenly restart the program. After some debugging, I realized that the errors did not occur unless I imported the Wire library. Even without the rest of the code for the BMP180, importing this library caused these errors. All of these sensors work independently, but I cannot get this program to work with all of them at once. I initially thought that this was a memory issue, but I tracked the RAM usage and there is no shortage of space.

The program itself is large and complicated, so here is an explanation of how it works. The Arduino communicates with the GPS and DHT22 via serial connections. The BMP180 uses I2C communication. Since working with these sensors can be complex, so I use libraries to interface with them. After the data is collected, it is written to an SD card.

First you need paste your code. If code is very large split it.

Since you are telling you facing problem for BMP180 device.Have you tested your code alone with BMP180?? First try alone BMP Device. If you facing let us know

Please share trial code for BMP & wire library alone & screenshot so we can understand problem. Also share us wire library you used here.

First of all, the BMP180 does work on its own. I tested it using the bmp180_test program attached to this post. However the BMP180 is not really the problem. The data logging software that I have now fails when I import the Wire library (the built-in library for I2C communication), even without trying to read from the BMP180. The most common problem is that the program restarts in the middle of the loop. This program only reads from the GPS and temperature/humidity sensors (both using serial connections), then logs it to an SD card (via SPI). Nothing here even uses the Wire library. Here is the code. It is large and kind of complicated, but I did add some comments.

//import libraries
#include <DHT.h> //for communicating with the temperature/humidity sensor
#include <SD.h> //for communicating with the SD card
#include <Wire.h> //this is for I2C
#include <Adafruit_GPS.h> //this is for working with the GOS
#include <SoftwareSerial.h> //this is for serial communication
#define DHTPIN 2
#define DHTTYPE DHT22   
#define GPSECHO  false
DHT dht(DHTPIN, DHTTYPE);
const int chipSelect = 4;
SoftwareSerial mySerial(5, 3);
Adafruit_GPS GPS(&mySerial);
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

void setup() {
  Serial.begin(9600); 
  GPS.begin(9600);
  pinMode(10, OUTPUT);
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  else {
    Serial.println("card found");
  }
  //set up GPS
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PGCMD_ANTENNA);
  useInterrupt(true);
  delay(1000);
  mySerial.println(PMTK_Q_RELEASE);
  //start collecting temp. and humidity
  dht.begin();
}

SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();

//Memory function, checks available RAM
int freeRam() {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

//GPS function (just returns latitude for now)
float location() {
  char c = GPS.read();
  if (GPS.newNMEAreceived()) 
    if (!GPS.parse(GPS.lastNMEA())) {  // this also sets the newNMEAreceived() flag to false
      Serial.println("no GPS");
      return 0.0;  // we can fail to parse a sentence in which case we should just wait for another
    }
    else {
      return GPS.latitude;
    }
}

void loop() {
  // Wait a few seconds between measurements.
  delay(5000);
  Serial.println(freeRam()); //check available RAM
  float lat = location();
  float lon = 72.5; //this will also come from location()
  delay(1000);
  // Read humidity
  float h = dht.readHumidity();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  Serial.println(freeRam()); //check RAM
  delay(1000);
  Serial.println("done collecting data");
  
  //log data to sd card
  if (true) {
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    Serial.println(freeRam()); //check RAM
    Serial.println("writing");
    Serial.println(dataFile);
    // if the file is available, write to it:
    if (dataFile) {
      dataFile.println(String(lat) + "," + String(lon) + "," + String(f) + "," + String(h));
      dataFile.close();
      Serial.print("done");
    }
    else {
      Serial.println("logging unsuccessful");
    }
  }
  
}

bmp180_test.ino (448 Bytes)

I thought you said the code was large? That's not large. Don't you need to call Wire.begin(); in setup?

This program does not even use the Wire library. All I am saying is that importing the library causes problems. I can not continue developing until this problem is resolved. P.S. Forget what I said about this program being too large. I have not had very much experience with Arduino; this is just one of the largest Arduino programs I have written (which does not say much).

I also noticed that this problem only occurs if the program is trying to write to an SD card. If I am not writing to an SD card, then it does not matter if I import the Wire library.

You can share your completed code ZIP file. Please don't divert topic. Initially mentioned wire problem later you saying software problem. Please be clarify what exact problem you facing

This program only reads from the GPS and temperature/humidity sensors (both using serial connections), then logs it to an SD card (via SPI)

SD is going to require at least 512 bytes of RAM. What is your freeRAM reporting?

Initially mentioned wire problem later you saying software problem.

?

The available RAM is about 125 bytes before the SD card is accessed. It seems that this is the point where the program fails and restarts. Here is the exact line:

File dataFile = SD.open("datalog.txt", FILE_WRITE);

This might explain the issue, but I did some testing in a separate sketch and accessing the card (by opening my data file) only consumed about 31 bytes. I checked the available RAM before and after opening the file. I also noticed that simply importing the Wire library gobbles up a few hundred bytes. I am dangerously close to the memory limits, but I should not be running out. If it is a memory issue after all, I could modify the library for the Adafruit GPS to use less RAM (this is the worst offender), but I would not know how to go about this.

P.S. I thought this was a software problem. This has nothing to do with the way my setup is wired, it is an issue with the way my program operates.

Instead of this
#include <SD.h> //for communicating with the SD card

try the SDfat.h library that fat16lib maintains, tests, updates.

I decided that I am just going to use an Arduino Mega (I am using an Uno now). Even if I can save enough RAM to make the program work as it is, I plan on adding more sensors (and libraries to go with them).