Hello!
We built an ultrasonic sensor attached to an Arduino Uno that sleeps and wake every 1 minute to measure distance by the minute. However, results show that the loop ends at 00:59:00 (59th minute) regardless of the date and the hour. This happens both when the Arduino is connected to the computer, and to a separate power source. Attached is our code below.
If you have any ideas to prevent the code from ending the loop and instead continuing indefinitely, please inform us.
Thanks in advance!
//-------------PIN ASSIGNMENTS----------------
/*
SD CARD:
MOSI: PIN 11
MISO: PIN 12
CLK: PIN 13
CS: PIN 4
ULTRASONIC SENSOR:
TRIGGER: PIN 7
ECHO: PIN 6
RTC:
SQW: PIN 2
SCL: PIN A5
SDA: PIN A4
*/
//----------------SLEEP CODE------------------
#include <avr/sleep.h> //this AVR library contains the methods that controls the sleep modes
#define interruptPin 2 //Pin we are going to use to wake up the Arduino
#include <DS3232RTC.h> //RTC Library https://github.com/JChristensen/DS3232RTC
const int time_interval = 1; // Sets the wakeup intervall in minutes
//----------------RTC CODE--------------------
#include <Wire.h>
#include "RTClib.h" // Date and time functions using a DS3231 RTC connected via I2C and Wire lib
RTC_DS3231 rtc;
//char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//-----------ULTRASONIC SENSOR CODE-----------
const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor
//--------------SD LIBRARIES------------
#include <SPI.h>
#include <SD.h>
char fname[] = "trial.txt";
void setup() {
Serial.begin(9600);//Start Serial Comunication
pinMode(LED_BUILTIN, OUTPUT); //We use the led on pin 13 to indecate when Arduino is A sleep
pinMode(interruptPin, INPUT_PULLUP); //Set pin d2 to input using the builtin pullup resistor
digitalWrite(LED_BUILTIN, HIGH); //turning LED on
//------------INITIALIZE SD CARD------------
Serial.print("Initializing SD card...");
if (!SD.begin()) {
Serial.println("Initialization failed!");
while (1);
}
Serial.println("SD card initialized.");
//------------INITIALIZE RTC------------
#ifndef ESP8266
while (!Serial); // for Leonardo/Micro/Zero
#endif
delay(1000); // wait for console opening
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
//------------INITIALIZE SLEEP-WAKE-----------
// initialize the alarms to known values, clear the alarm flags, clear the alarm interrupt flags
RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1);
RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
RTC.alarm(ALARM_1);
RTC.alarm(ALARM_2);
RTC.alarmInterrupt(ALARM_1, false);
RTC.alarmInterrupt(ALARM_2, false);
RTC.squareWave(SQWAVE_NONE);
time_t t; //create a temporary time variable so we can set the time and read the time from the RTC
t = RTC.get(); //Gets the current time of the RTC
RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t) + time_interval, 0, 0); // Setting alarm 1 to go off 5 minutes from now
// clear the alarm flag
RTC.alarm(ALARM_1);
// configure the INT/SQW pin for "interrupt" operation (disable square wave output)
RTC.squareWave(SQWAVE_NONE);
// enable interrupt output for Alarm 1
RTC.alarmInterrupt(ALARM_1, true);
///----------------
}
void loop() {
delay(1000);//wait 5 seconds before going to sleep. In real senairio keep this as small as posible
Going_To_Sleep();
}
//---------------SLEEP FXN-------------------
void Going_To_Sleep() {
sleep_enable(); //Enabling sleep mode
attachInterrupt(0, wakeUp, LOW); //attaching a interrupt to pin d2
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Setting the sleep mode, in our case full sleep
digitalWrite(LED_BUILTIN, LOW); //turning LED off
time_t t; // creates temp time variable
t = RTC.get(); //gets current time from rtc
Serial.println("Sleep Time: " + String(hour(t)) + ":" + String(minute(t)) + ":" + String(second(t))); //prints time stamp on serial monitor
delay(1000); //wait a second to allow the led to be turned off before going to sleep
sleep_cpu(); //activating sleep mode
Serial.println("Just woke up!");//next line of code executed after the interrupt
digitalWrite(LED_BUILTIN, HIGH); //turning LED on
uSonic(); //includes real-time, data, and file saving.
t = RTC.get();
Serial.println("WakeUp Time: " + String(hour(t)) + ":" + String(minute(t)) + ":" + String(second(t))); //Prints time stamp
//Set New Alarm
RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t) + time_interval, 0, 0);
// clear the alarm flag
RTC.alarm(ALARM_1);
}
//-----------------WAKE UP FXN-----------------
void wakeUp() {
Serial.println("Interrrupt Fired");//Print message to serial monitor
sleep_disable(); //Disable sleep mode
detachInterrupt(0); //Removes the interrupt from pin 2;
}
void uSonic() {
//------------GET REAL TIME FXN-------------
String dataString = "";
String dTime = "";
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.print("\t");
//--------------GET DISTANCE FXN---------------
long duration, inches, cm;
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(cm);
Serial.print("cm");
Serial.println();
//--------------FILE SAVING--------------------
File dataFile = SD.open(fname, FILE_WRITE);
if (dataFile) {
dataFile.print(now.year(), DEC);
dataFile.print('/');
dataFile.print(now.month(), DEC);
dataFile.print('/');
dataFile.print(now.day(), DEC);
dataFile.print(" ");
dataFile.print(" ");
dataFile.print(now.hour(), DEC);
dataFile.print(':');
dataFile.print(now.minute(), DEC);
dataFile.print(':');
dataFile.print(now.second(), DEC);
dataFile.print("\t");
dataFile.println(cm);
dataFile.close();
}
else {
Serial.print("Error opening");
Serial.print(fname);
}
}
//--------------CONVERT ms TO cm---------------
long microsecondsToCentimeters(long microseconds) {
return microseconds / 28 / 2;
}