Everything in my project works well except that it doesn't seem to be going into sleep mode (it takes nearly constant readings-I want to be able to determine the interval, preferably 12 hours with deep sleep between readings)
Here is the code, sorry it isn't pretty...
Thanks if anyone can help.
- Code: Select all | TOGGLE FULL SIZE
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include "DHT.h"
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <wd.h>
#define ECHO_TO_SERIAL 1 // echo data to serial port
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define DHTPIN 3
#define DHTTYPE DHT11
#define trigPin 4
#define echoPin 2
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;
const int StepTime = 60; // seconds between logs.
const int TimingTolerance = 8;
const int chipSelect = 10;
DateTime now;
uint32_t NextTime;
uint32_t NowTime;
uint32_t RemainingTime;
int SleepTimeIndex;
float SleepTime;
volatile boolean f_wdt=1;
File logfile;
void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
while(1);
}
void setup(void)
{
Serial.begin(9600);
Serial.println();
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Sleep mode
cbi( SMCR,SE ); // sleep enable, power down mode
cbi( SMCR,SM0 ); // power down mode
sbi( SMCR,SM1 ); // power down mode
cbi( SMCR,SM2 ); // power down mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
// Times
now = RTC.now();
NowTime = now.unixtime();
NextTime = NowTime + 10000;
Serial.print("Initializing SD card...");
pinMode(10, OUTPUT);
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
return;
}
Serial.println("card initialized.");
char filename[] = "LOGGER00.csv";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
logfile = SD.open(filename, FILE_WRITE);
break;
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
logfile.println("date, time, humidty %, temp *C, distance mm");
#if ECHO_TO_SERIAL
Serial.println("date, time, humidity %, temp *C, distance mm ");
#endif
Wire.begin();
if (!RTC.begin()) {
logfile.println("RTC failed");
#if ECHO_TO_SERIAL
Serial.println("RTC failed");
#endif
}
}
void loop(){
now = RTC.now();
NowTime = now.unixtime();
if (NextTime > NowTime)
{
RemainingTime = NextTime - NowTime;
SleepTimeIndex = GetSleepTimeIndex(RemainingTime);
SetupWatchdog(SleepTimeIndex);
GoToSleep();
}
else
DateTime now = RTC.now();
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
logfile.print(" , ");
#if ECHO_TO_SERIAL
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
Serial.print(" , ");
#endif
float h = dht.readHumidity();
float t = dht.readTemperature();
delayMicroseconds(1000);
if (isnan(t) || isnan(h)) {
logfile.println("Failed to read from DHT");
}
else {
logfile.print(h);
logfile.print(" , ");
logfile.print(t);
logfile.print(" , ");
}
#if ECHO_TO_SERIAL
if (isnan(t) || isnan(h)) {
Serial.println("Failed to read from DHT");
}
else {
Serial.print(h);
Serial.print(" , ");
Serial.print(t);
Serial.print(" , ");
}
#endif
{
int duration, distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 2.91;
if (distance >= 2000 || distance <= 0){
logfile.println("Out of range");
}
else {
logfile.println(distance);
}
#if ECHO_TO_SERIAL
if (distance >= 2000 || distance <= 0){
Serial.println("Out of range");
}
else {
Serial.println(distance);
}
#endif
delay(500);
}
logfile.flush();
NextTime = NextTime + StepTime;
}
void GoToSleep()
{
cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON
}
///////////////////
// SetupWatchdog //
///////////////////
void SetupWatchdog (int SleepTimeIndex)
{
byte bb;
int ww;
if (SleepTimeIndex > 9 ) SleepTimeIndex=9;
bb=SleepTimeIndex & 7;
if (SleepTimeIndex > 7) bb|= (1<<5);
bb|= (1<<WDCE);
ww=bb;
MCUSR &= ~(1<<WDRF);
// start timed sequence
WDTCSR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCSR = bb;
WDTCSR |= _BV(WDIE);
}
/////////
// ISR //
/////////
// Watchdog Interrupt Service: executed when watchdog timed out
ISR(WDT_vect)
{
f_wdt=1; // set global flag
}
///////////////////////
// GetSleepTimeIndex //
///////////////////////
int GetSleepTimeIndex(uint32_t TargetTime)
{
// Sets the SleepTimeIndex to go to sleep for as long as possible without sleeping too long
int SleepTimeIndex;
if (TargetTime > 8)
{
SleepTimeIndex = 9;
}
else if (TargetTime > 4)
{
SleepTimeIndex = 8;
}
else if (TargetTime > 2)
{
SleepTimeIndex = 7;
}
else if (TargetTime > 1)
{
SleepTimeIndex = 6;
}
else
{
SleepTimeIndex = TimingTolerance;
}
return SleepTimeIndex;
}
//////////////////
// GetSleepTime //
//////////////////
float GetSleepTime(int SleepTimeIndex)
{
float SleepTimes[] = {0.016, 0.032, 0.064, 0.128, 0.250, 0.500, 1, 2, 4, 8};
float SleepTime;
SleepTime = SleepTimes[SleepTimeIndex];
return SleepTime;
}