I try to wake up my device from deep sleep mode by using the SWQ pin of DS3231 as an interrupt on pin 2 of chip atmega328p. At the moment the device is able to wake up at the first time -> doing some stuff -> back to sleep -> can not wake up for second time. I can not see where is the mistake about the logic. Can someone please help me figure out the problem with it
I am using the RTClibExtended library. Here is the code :
#include <SPI.h>
#include <RTClibExtended.h>
#include <Wire.h>
#include <LowPower.h>
#include <SD.h>
#include <stdlib.h>
#include <avr/interrupt.h> // library for interrupts handling
#include <avr/sleep.h> // library for sleep
#include <avr/power.h> // library for power control
//----------------------------------------------------
#define LOG_INTERVAL 2000//1s
#define SYNC_INTERVAL 2000
//----------------------------------------------------
#define wakePin 2 //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
#define ledPin A0 //debugging LED
#define mosfet 9 //motor pin
#define power 8 //peripheral control pin
#define chipSelect 10 //SS pin for MicroSD card module
//-----------------------Error Message----------------
File logfile;
void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
while(1);
}
//RTC----
byte AlarmFlag = 0;
int sec_log = 60;
int sec_cnt = 0;
int sec_log2 = 60;
int sec_cnt2 = 0;
int motor_flag = 0;
//-----
//---------------Ultrasonic Sensor Pins---------------
const int trigPin1 = 4;
const int echoPin1 = 5;
long duration1;
int distance1;
const int trigPin2 = 6;
const int echoPin2 = 7;
long duration2;
int distance2;
//-----------------RTC declaration--------------------
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int interval_sec=4; //An alarm every 4 sec
int i=1;
//----------------------------------------------------
void setup () {
Wire.begin(); //start the I2C bus
Serial.begin(9600); //start the Serial module
//delay(3000); // wait for console opening
/**RTC**/
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//set RTC date and time to compile time
//----------------------------
pinMode(power, OUTPUT);
pinMode(mosfet, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(mosfet, LOW);
//-----Ultrasonic Sensors------
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
//-----SD card module----------
Serial.println("Initializing SD card...");
pinMode(chipSelect, OUTPUT);
if(!SD.begin(chipSelect))
{
error("Card failed or not present");
}
Serial.println("Card Initialized.");
char filename[] = "DATA00.CSV";
for (uint8_t i = 0; i<100; i++)
{
filename[4] = i/10 + '0';
filename[5] = 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);
//------------------------------
/**INTERRUPT**/
//Set pin D2 as INPUT for accepting the interrupt signal from DS3231
pinMode(wakePin, INPUT);
//-----
digitalWrite(ledPin, HIGH);//switch on the LED for 1s for indicating that the sketch is ok and running
delay(1000);
//-----
//clear any pending alarms
rtc.armAlarm(1, false);
rtc.clearAlarm(1);
rtc.alarmInterrupt(1, false);
rtc.armAlarm(2, false);
rtc.clearAlarm(2);
rtc.alarmInterrupt(2, false);
//Set SQW pin to OFF
//The output of the DS3231 INT pin is connected to this pin
//connected to arduino D2 pin for wake-up
rtc.writeSqwPinMode(DS3231_OFF);
//---
DateTime now = rtc.now();
DateTime nextAlarm = now + TimeSpan(0, 0, 0, interval_sec);
rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.second(), nextAlarm.minute(), nextAlarm.hour(), 1); //set your wake-up time here
rtc.alarmInterrupt(1, true);
//-----
Serial.println("Initialisation complete.");
delay(100); //Allow for serial print to complete.
}
void loop () {
DateTime now = rtc.now();
attachInterrupt(0, wakeUp, LOW);//use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
digitalWrite(ledPin, LOW); //turn of the LED for indicating that we enter the sleep mode
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);//arduino enters sleep mode here
detachInterrupt(0); //execution resumes from here after wake up
if(AlarmFlag >= 1){
restartroutine();
Serial.print("TESTING");
Serial.println();
}
else if(AlarmFlag == 0){
//alarm triggered, runs sensors to scan the object within 1 hours
while (now.minute()>0 && now.minute() < 55){
now = rtc.now();//check time again
distance1 = range(trigPin1, echoPin1, power);
distance2 = range(trigPin2, echoPin2, power);
Serial.print("Distance 1:");
Serial.print( distance1);
Serial.print(" Distance 2:");
Serial.println( distance2);
if(distance1<10 && distance2<10){
motor_flag=1; //run motor when object within the certain range
}
if (motor_flag==1){
motorrunroutine();
}
else if(motor_flag==2){
motor_flag=0;
// Serial.print(AlarmFlag);
// Serial.println();
break;
}
}
}
//when exiting the sleep mode we clear the alarm
rtc.armAlarm(1, false);
rtc.clearAlarm(1);
rtc.alarmInterrupt(1, false);
}
//log date and time when motor runs into sd card
void logmotor(){
DateTime now = rtc.now();
logfile.print('"');
logfile.print(now.day(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.year(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
logfile.print('"');
logfile.flush();
logfile.print("\n");
logfile.close();
}
//function to make motor runs only for 4s and also log data into sd card
void motorrunroutine(){
DateTime now = rtc.now();
if(sec_cnt<4){
digitalWrite(mosfet, HIGH);//motor runs only for 4s
}
else{
logmotor();
AlarmFlag++;
motor_flag = 2;
sec_cnt=0;
stopmotor();
}
if(sec_log!=now.second()){
sec_cnt++;
sec_log=now.second();
}
}
//function used to set the alarm flag back to 0 after 4s
void restartroutine(){
DateTime now = rtc.now();
if(sec_log2!=now.second()){
sec_cnt2++;
sec_log2=now.second();
}
if(sec_cnt2>=4){
AlarmFlag=0;
sec_cnt2=0;
}
}
//stop motor function
void stopmotor(){
digitalWrite(mosfet, LOW);
}
//ultrasonic sensor control
unsigned long range(byte trigPin, byte echoPin, byte vcc)
{
digitalWrite(vcc, LOW);
delay(50);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
unsigned long duration = pulseIn(echoPin, HIGH);
digitalWrite(vcc, HIGH);
delay(100);
return duration * 0.034 / 2;
}
// here the interrupt is handled after wakeup
void wakeUp()
{
}
The process of the system is: wake up at the first time -> activate ultrasonic sensor to scan object -> when object is detected -> run motor -> log the time when motor runs into sd card -> back to sleep -> wake up second time.
