I am putting together a data logging rain gauge - basic hardware details here - http://interestingto.me.uk/Open%20Source/low-cost-low-power-datalogger. Basically there is an RTC (DS1305) that trigger an alarm interrupt to wake up the Atmega328 and take a reading. I am using a BMP085 pressure sensor and the Adafruit library to read it - GitHub - adafruit/Adafruit-BMP085-Library: A powerful but easy to use BMP085/BMP180 Arduino library (I KNOW this is an old version but it ought to do the job).
The Adafruit library in turn uses Wire to read the BP085 over I2C and it works OK if I run the example. But if I run the code below it reads on the first pass but then hangs and never returns anything again. If I use the attached code as shown with the BMP085 code commented out it works fine. Do I need to initialize/reinitialize the Wire library between sleeps or something to stop this hanging. I have tried a variety of things but can see why it hangs. Any help appreciated.
#include <DS1305.h>
#include <avr/sleep.h>
#include <SD.h>
//BMP085 pressure/temp sensor
#include <Wire.h>
#include <Adafruit_BMP085.h>
//Send debug info to serial
#define DEBUG
#ifdef DEBUG
#define DEBUGPRINT(x) Serial.print(x);
#define DEBUGPRINTLN(x) Serial.println(x);
#else
#define DEBUGPRINT(x)
#define DEBUGPRINTLN(x)
#endif
//Pins
#define LED 7
#define SD_CS SS
#define RTC_CS 9
//Actions
#define ACT_SETUP B00000001
#define ACT_INT0 B00000010
#define ACT_INT1 B00000100
//the file to write to on the SD card
#define FILENAME "Logger.txt"
//Setup has a loop to allow the user to set things, this stores
//millis to exit that loop
unsigned long initialMilli;
//variables for reading the date/time
char serialBuf[6]; //the longest string to be read at one time is the year - 2013
int serBufIdx = 0;
int datetime[9];
int dtIdx = 0;
int rtcSetting = 0;
char prevch = ' ';
//a set of flags to indicate what action to take
//first bit = starting up
//second bit = Interrupt on 0 (pin 2)
//third bit = Interrupt on 1 (pin 3)
byte actionFlags;
//SD File
File myFile;
boolean sdUp;
// Create a new object to interact with the RTC
DS1305 rtc;
//BMP085 pressure/temp sensor
//Adafruit_BMP085 bmp;
/*****************************************************************
Put code here that is called when interrupt 0 is triggered
*****************************************************************/
void intZeroAction(char* datebuf) {
/*DEBUGPRINT("Initializing BMP085 Sensor");
if (bmp.begin()) {
Serial.print("Temperature = ");
Serial.print(bmp.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bmp.readPressure());
Serial.println(" Pa");
}
else {
Serial.println("Could not find a valid BMP085 sensor, check wiring!");
}*/
}
/*****************************************************************
Put code here that is called when interrupt 1 is triggered
*****************************************************************/
void intOneAction(char* datebuf) {
//writeSDData(datebuf, "Int 1");
}
/*****************************************************************
Interrupt handler for interrupt 0 - external
*****************************************************************/
void irqZeroHandler()
{
// cancel sleep as a precaution
sleep_disable();
// must do this as the pin will probably stay low for a while
detachInterrupt (0);
rtc.clearAlarmState(0);
actionFlags |= ACT_INT0;
DEBUGPRINTLN("** irq 0 triggered! **");
}
/*****************************************************************
Interrupt handler for interrupt 1 (RTC alarm)
*****************************************************************/
void irqOneHandler()
{
// cancel sleep as a precaution
sleep_disable();
// must do this as the pin will probably stay low for a while
detachInterrupt (1);
actionFlags |= ACT_INT1;
DEBUGPRINTLN("** irq 1 triggered! **");
}
/*****************************************************************
Write Data to SD
*****************************************************************/
void writeSDData(char* datebuf, char* message) {
if(sdUp) {
myFile = SD.open(FILENAME, FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
myFile.print(datebuf);
myFile.print("; ");
myFile.println(message);
// close the file:
DEBUGPRINTLN("Wrote to SD.");
} else {
// if the file didn't open, print an error:
DEBUGPRINT("error opening " ); DEBUGPRINT(FILENAME);
}
myFile.close();
}
}
/******************************************************************
Standard setup routine
******************************************************************/
void setup()
{
actionFlags = ACT_SETUP;
// disable ADC
ADCSRA = 0;
int prevMilli;
initialMilli = prevMilli = millis();
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
// Initialize RTC
// Assumes that RTC select line is pin 13
rtc.init(RTC_CS);
//start serial for reading user input date/time
Serial.begin(9600);
Serial.println("Set time and alarm, YY/MM/DD DOW HH:MM:SS or DOW H24 M S use * for any." );
Serial.println("DOW is 1 based, 1=Sunday");
Serial.println("e.g. * * 30 * would set an alarm to go off 30 mins past each hour" );
int ledState = LOW;
while(millis() - initialMilli < 20000) {
//rapid blink of LED for setup
if((millis() - prevMilli) > 100 ) {
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
prevMilli = millis();
}
digitalWrite(LED, ledState);
readSerialSetup();
}
//Set up interrupt pins
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
DEBUGPRINT("Initializing SD card...");
//Chip Select for the SD card on pin 8
pinMode(SD_CS, OUTPUT);
if (!SD.begin(SD_CS)) {
sdUp = false;
DEBUGPRINTLN("initialization failed!");
}
else {
sdUp = true;
DEBUGPRINTLN("SD initialization OK.");
}
/*DEBUGPRINT("Initializing BMP085 Sensor");
if (!bmp.begin()) {
Serial.println("Could not find a valid BMP085 sensor, check wiring!");
}*/
//close serial
Serial.end();
digitalWrite(LED, LOW);
delay(500);
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
}
/******************************************************************
Standard loop routine
******************************************************************/
void loop()
{
// Get the time
ds1305time t;
rtc.getTime(&t);
// Format time
char datebuf[128];
snprintf(datebuf, 128, "%02d/%02d/%02d %d:%02d:%02d",
t.year,
t.month,
t.day,
t.hours,
t.minutes,
t.seconds
);
#ifdef DEBUG
Serial.begin(9600);
#endif
// Output time
DEBUGPRINTLN(datebuf);
if((actionFlags & ACT_SETUP) == ACT_SETUP) {
DEBUGPRINTLN("Start up");
writeSDData(datebuf, "Start Up");
//unset the flag
actionFlags = actionFlags & ~ACT_SETUP;
}
if((actionFlags & ACT_INT0) == ACT_INT0) {
DEBUGPRINTLN("Int 0 Flagged");
intZeroAction(datebuf);
//unset the flag
actionFlags = actionFlags & ~ACT_INT0;
}
if((actionFlags & ACT_INT1) == ACT_INT1) {
DEBUGPRINTLN("Int 1 Flagged");
intOneAction(datebuf);
//unset the flag
actionFlags = actionFlags & ~ACT_INT1;
}
#ifdef DEBUG
Serial.print("Flags: ");
Serial.print(actionFlags); Serial.print(" ");
Serial.print(actionFlags & ACT_INT0, BIN); Serial.print(" ");
Serial.println(actionFlags, BIN);
Serial.end();
delay(1000);
#endif
//if(false) {
if(actionFlags == 0) {
#ifdef DEBUG
Serial.begin(9600);
Serial.println("Going to sleep");
Serial.end();
#endif
//no more actions raised, go to sleep
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
// Do not interrupt before we go to sleep, or the
// ISR will detach interrupts and we won't wake.
noInterrupts ();
attachInterrupt(0, irqZeroHandler, FALLING);
attachInterrupt(1, irqOneHandler, FALLING);
// We are guaranteed that the sleep_cpu call will be done
// as the processor executes the next instruction after
// interrupts are turned on.
interrupts (); // one cycle
sleep_cpu (); // one cycle
}
else {
//notify that we are not sleeping
digitalWrite(LED, HIGH);
delay(200);
digitalWrite(LED, LOW);
}
}
/*****************************************************************
Read Date/time from serial to set clock
*****************************************************************/
void readSerialSetup() {
... removed due to posting limit
}//readSerialSetup
/**********************************************************
Append an int to the date array and clear the serial buffer
**********************************************************/
void appendDateInt() {
... removed due to posting limit
}