// Include seperate arduino libraries
#include <DS3232RTC.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
// Defines pin numbers
const int button = A2;
const int ledPin = A3;
const int CS = 10;
const int trigPin = 5;
const int echoPin = 4;
const int rs = 2,
en = 3,
d4 = 6,
d5 = 7,
d6 = 8,
d7 = 9;
// Defines variables
long duration;
int distance;
int safetyDistance;
int currentButtonState;
int lastButtonState;
int a,
b,
c,
d;
// Sets up LCD
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Define Real Time Clock device
DS3232RTC RTC;
// Define the SD card file
File myFile;
void setup() {
// Define Pin modes
pinMode(echoPin, INPUT);
pinMode(button, INPUT);
pinMode(trigPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(CS, OUTPUT);
Serial.begin(115200);
lcd.begin(16, 2);
RTC.begin();
setSyncProvider(RTC.get);
// If the time is wrong then set time with https://www.youtube.com/watch?v=Z-66x-9-7T0
// Initiate RTC
if (timeStatus() != timeSet) {
lcd.setCursor(0, 0);
lcd.print("RTC sync failed");
delay(2000);
lcd.clear();
}
else {
while (!Serial) {
;
}
if (SD.begin()) {
lcd.setCursor(0, 0);
lcd.print("RTC synced");
lcd.setCursor(0, 1);
lcd.print("SD card ready");
myFile = SD.open("test.csv", FILE_WRITE);
delay(3000);
lcd.clear();
myFile.close();
}
else {
lcd.setCursor(0, 0);
lcd.print("SD card missing");
delay(3000);
lcd.clear();
}
}
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
safetyDistance = distance;
// If the mower docks
if (safetyDistance <= 10) {
// Displays timestamp for mower docking on the LCD
lcd.setCursor(0, 0);
lcd.print("Mower docked:");
lcd.setCursor(0, 1);
digitalClockDisplay();
digitalTimeStampSet();
// Displays timestamp for mower docking on SD card
myFile = SD.open("test.csv", FILE_WRITE);
if (myFile) {
myFile.print("Mower docked:");
myFileClockDisplay();
myFile.close();
}
else {
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SD card failed");
}
delay(5000);
lcd.clear();
// Wait until the mower undocks
while (safetyDistance <= 10) {
lastButtonState = currentButtonState;
currentButtonState = digitalRead(button);
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
safetyDistance = distance;
// Recalls the timestamp for when the mower docked
if (lastButtonState == LOW && currentButtonState == HIGH) {
digitalWrite(ledPin, HIGH);
lcd.setCursor(0, 0);
lcd.print("Mower docked:");
lcd.setCursor(0, 1);
digitalTimeStamp();
delay(5000);
digitalWrite(ledPin, LOW);
lcd.clear();
}
delay(100);
}
// Displays the timestamp for the mower undocking on LCD
digitalWrite(ledPin, LOW);
lcd.setCursor(0, 0);
lcd.print("Mower undocked:");
lcd.setCursor(0, 1);
digitalClockDisplay();
digitalTimeStampSet();
// Displays the timestamp for the mower undocking on the SD card
myFile = SD.open("test.csv", FILE_WRITE);
if (myFile) {
myFile.print("Mower undocked:");
myFileClockDisplay();
myFile.close();
}
else {
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SD card failed");
}
delay(5000);
lcd.clear();
}
// When the mower is out in the garden
else if (safetyDistance > 10) {
lastButtonState = currentButtonState;
currentButtonState = digitalRead(button);
digitalWrite(ledPin, LOW);
if (lastButtonState == LOW && currentButtonState == HIGH) {
digitalWrite(ledPin, HIGH);
lcd.setCursor(0, 0);
lcd.print("Mower undocked:");
lcd.setCursor(0, 1);
digitalTimeStamp();
delay(5000);
digitalWrite(ledPin, LOW);
lcd.clear();
}
}
}
void digitalTimeStampSet() {
a = hour();
b = minute();
c = second();
d = day();
}
void digitalTimeStamp() {
lcd.print(a);
digitalPrintDigits(b);
digitalPrintDigits(c);
lcd.print(' ');
lcdPrintMonth();
lcd.print(d);
lcd.print(' ');
lcd.print(' ');
lcd.print(' ');
lcd.println();
}
void digitalClockDisplay() {
lcd.print(hour());
digitalPrintDigits(minute());
digitalPrintDigits(second());
lcd.print(' ');
lcdPrintMonth();
lcd.print(day());
lcd.print(' ');
lcd.print(' ');
lcd.print(' ');
lcd.println();
}
void digitalPrintDigits(int digits) {
lcd.print(':');
if (digits < 10) {
lcd.print('0');
}
lcd.print(digits);
}
void myFileClockDisplay() {
myFile.print(',');
myFile.print(hour());
myFilePrintDigits(minute());
myFilePrintDigits(second());
myFile.print(',');
myFilePrintMonth();
myFile.print(day());
myFile.println();
myFile.println();
}
void myFilePrintDigits(int digits) {
myFile.print(':');
if (digits < 10) {
myFile.print('0');
}
myFile.print(digits);
}
void lcdPrintMonth() {
String monthName;
switch (month()) {
case 1:
monthName = "Jan";
break;
case 2:
monthName = "Feb";
break;
case 3:
monthName = "Mar";
break;
case 4:
monthName = "Apr";
break;
case 5:
monthName = "May";
break;
case 6:
monthName = "Jun";
break;
case 7:
monthName = "Jul";
break;
case 8:
monthName = "Aug";
break;
case 9:
monthName = "Sep";
break;
case 10:
monthName = "Oct";
break;
case 11:
monthName = "Nov";
break;
case 12:
monthName = "Dec";
break;
}
lcd.print(monthName);
lcd.print(' ');
}
void myFilePrintMonth() {
String monthName;
switch (month()) {
case 1:
monthName = "Jan";
break;
case 2:
monthName = "Feb";
break;
case 3:
monthName = "Mar";
break;
case 4:
monthName = "Apr";
break;
case 5:
monthName = "May";
break;
case 6:
monthName = "Jun";
break;
case 7:
monthName = "Jul";
break;
case 8:
monthName = "Aug";
break;
case 9:
monthName = "Sep";
break;
case 10:
monthName = "Oct";
break;
case 11:
monthName = "Nov";
break;
case 12:
monthName = "Dec";
break;
}
myFile.print(monthName);
myFile.print(' ');
}