#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SD.h>
#include <SPI.h>
// Rotary Encoder Setup
const int clkPin = 2;
const int dtPin = 3;
const int buttonPin = 4;
const float PPT = 100.0; // Pulses Per Turn (adjust this value)
// DS1307 RTC Setup
RTC_DS1307 rtc;
// ILI9341 Screen Setup
#define TFT_CS 9
#define TFT_DC 8
#define TFT_RST -1
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// EEPROM Setup
const int depthAddress = 0; // Address in EEPROM to store depth value
// Reset Switch Setup
const int resetSwitchPin = 5; // Pin for the reset switch
bool resetSwitchState = HIGH; // Assuming the button is not pressed initially
bool lastResetSwitchState = HIGH;
bool resetConfirmation = false;
// SD Card Setup
const int chipSelect = 10;
// Log File Setup
File logFile;
// Variables
volatile int encoderCount = 0;
volatile int lastEncoderCount = 0;
unsigned long lastScreenUpdateTime = 0;
const int screenRefreshInterval = 300; // Set the refresh interval in milliseconds
void rotaryCallback() {
int clkState = digitalRead(clkPin);
int dtState = digitalRead(dtPin);
if (clkState == dtState) {
encoderCount++;
} else {
encoderCount--;
}
}
String twoDigits(int digits) {
if (digits < 10) {
return "0" + String(digits);
} else {
return String(digits);
}
}
String getTimestamp() {
unsigned long currentMillis = millis();
DateTime now = rtc.now();
return twoDigits(now.hour()) + ":" +
twoDigits(now.minute()) + ":" +
twoDigits(now.second()) + "." +
twoDigits(currentMillis % 1000 / 10); // Two decimal places for milliseconds
}
void displayDepthOnScreen() {
// Set the font size and color
tft.setTextSize(3);
tft.setTextColor(ILI9341_WHITE);
// Erase the previous depth value (black rectangle)
tft.fillRect(0, 0, tft.width(), 100, ILI9341_BLACK);
// Calculate depth using calibration factor
float depthMeters = encoderCount / PPT;
// Display the new depth value
tft.setCursor(30, 60);
tft.print("Depth:");
tft.print(depthMeters, 2); // Display with two decimal places
tft.println("m");
}
void saveDepthToEEPROM(float depth) {
// Not using EEPROM with SD card implementation
}
float readDepthFromEEPROM() {
// Not using EEPROM with SD card implementation
return 0.0; // Placeholder, as we're not using EEPROM
}
void checkResetSwitch() {
resetSwitchState = digitalRead(resetSwitchPin);
if (resetSwitchState == LOW && lastResetSwitchState == HIGH) {
// Switch has been pressed
resetConfirmation = true;
}
if (resetConfirmation) {
// If the button is pressed again within 10 seconds, reset the depth
unsigned long currentTime = millis();
if (resetSwitchState == LOW && currentTime - lastScreenUpdateTime > 10000) {
encoderCount = 0;
resetConfirmation = false;
}
}
lastResetSwitchState = resetSwitchState;
}
void setup() {
Serial.begin(9600);
pinMode(clkPin, INPUT);
pinMode(dtPin, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(clkPin), rotaryCallback, CHANGE);
Wire.begin();
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (!rtc.isrunning()) {
Serial.println("RTC is not running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
tft.begin();
tft.setRotation(1);
pinMode(resetSwitchPin, INPUT_PULLUP);
// Initialize SD card
if (SD.begin(chipSelect)) {
Serial.println("SD card initialized.");
} else {
Serial.println("Error initializing SD card.");
}
// Open the log file
logFile = SD.open("log.txt", FILE_WRITE);
if (logFile) {
logFile.println("Timestamp,Depth (m)");
logFile.close();
} else {
Serial.println("Error opening log file.");
}
}
void loop() {
checkResetSwitch();
unsigned long currentTime = millis();
if (lastEncoderCount != encoderCount && (currentTime - lastScreenUpdateTime) >= screenRefreshInterval) {
displayDepthOnScreen();
// Save depth to EEPROM every second
if (currentTime % 1000 == 0) {
float depthMeters = encoderCount / PPT;
// Log data to SD card
logFile = SD.open("log.txt", FILE_WRITE);
if (logFile) {
logFile.print(getTimestamp());
logFile.print(",");
logFile.println(depthMeters, 2);
logFile.close();
Serial.println("Data saved to log file.");
} else {
Serial.println("Error opening log file.");
}
}
String timestamp = getTimestamp();
String data = timestamp + ": Encoder Count: " + String(encoderCount);
Serial.println(data);
lastScreenUpdateTime = currentTime;
lastEncoderCount = encoderCount;
}
// Adjust this delay to control the overall loop rate
delay(10);
}