#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <Fonts/FreeSans9pt7b.h>
#include <RTClib.h>
#include <LedControl.h>
//MATRIX DISPLAY
byte devices = 1;
LedControl lc = LedControl(4, 5, 6, devices); //DIN, CLK, CS, count of displays
RTC_DS3231 rtc;
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int redPin = 8; // D5
const int yellowPin = 9; // D6
const int greenPin = 10; // D7
//const int dimRed = 11;
//const int dimYellow = 31;
//const int dimGreen = 255;
const int dimRed = 255;
const int dimYellow = 255;
const int dimGreen = 255;
float tPC;
unsigned long initialHighTide; // Initial high tide timestamp
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000
};
void setup() {
Serial.begin(115200);
// Start Wire library for I2C
Wire.begin();
lc.shutdown(0, false); // Wake up MAX7219
lc.setIntensity(0, 8); // Set brightness (0-15)
lc.clearDisplay(0); // Clear display
// initialize OLED with I2C addr 0x3C
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(greenPin, OUTPUT);
// Set initial high tide time (replace with actual values)
// Format: Year, Month, Day, Hour, Minute, Second
initialHighTide = DateTime(2025, 2, 22, 4, 57, 0).unixtime();
}
void loop() {
DateTime now = rtc.now();
unsigned long currentTime = now.unixtime();
unsigned long elapsedTime = (currentTime - initialHighTide) % 44700;
if (elapsedTime >= 22350 && elapsedTime < 44700) {
tPC = elapsedTime - 22350;
tPC = tPC / 22350;
tPC = tPC * 100;
updateDisplay(tPC, true);
}
if (elapsedTime >= 0 && elapsedTime < 22350) {
tPC = 22350 - elapsedTime;
tPC = tPC / 22350;
tPC = tPC * 100;
updateDisplay(tPC, false);
}
Serial.print("Current time: ");
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.println();
//Serial.print("Initial High Tide: ");
//Serial.println(initialHighTide);
Serial.print("Tide height: ");
Serial.print(tPC);
Serial.println("%");
Serial.print("Elapsed Time: ");
Serial.println(elapsedTime);
// Clear the buffer
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
//display.setFont(&FreeSans9pt7b);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
display.println("Current time: ");
display.print(now.year(), DEC);
display.print('/');
display.print(now.month(), DEC);
display.print('/');
display.print(now.day(), DEC);
display.print(" ");
display.print(now.hour(), DEC);
display.print(':');
display.print(now.minute(), DEC);
display.print(':');
display.print(now.second(), DEC);
display.println();
display.println();
//display.println("Initial High Tide: ");
//display.println(initialHighTide);
display.println("Tide height: ");
display.print(tPC);
display.println("%");
display.println();
display.println("Elapsed Time: ");
display.println(elapsedTime);
if (elapsedTime >= 41906.5 && elapsedTime < 44700) {
setLights(true, false, false); // High Tide (Red)
Serial.println("High Tide");
//display.println(F("High Tide"));
}
else if (elapsedTime >= 25143.5 && elapsedTime < 41906.5) {
setLights(true, true, false); // Rising Tide (Red + Yellow)
Serial.println("Rising Tide");
//display.println(F("Rising Tide"));
}
else if (elapsedTime >= 19556.5 && elapsedTime < 25143.5) {
setLights(false, false, true); // Low Tide (Green)
Serial.println("Low Tide");
//display.println(F("Low Tide"));
}
else if (elapsedTime >= 2793.5 && elapsedTime < 19556.5) {
setLights(false, true, true); // Falling Tide (Green + Yellow)
Serial.println("Falling Tide");
//display.println(F("Falling Tide"));
}
else if (elapsedTime >= 0 && elapsedTime < 2793.5) {
setLights(true, false, false); // High Tide (Red)
Serial.println("High Tide");
//display.println(F("High Tide"));
}
else {
setLights(false, false, false);
Serial.println("Something's wrong");
//display.println(F("Something's wrong"));
}
display.display();
delay(3000);
}
void setLights(bool red, bool yellow, bool green) {
analogWrite(redPin, red ? dimRed : LOW);
analogWrite(yellowPin, yellow ? dimYellow : LOW);
analogWrite(greenPin, green ? dimGreen : LOW);
}
void updateDisplay(float percentage, bool rising) {
//lc.clearDisplay(0); // Clear display before updating
int numRows = map(percentage, 0, 100, 1, 7); // Map percentage to 1-7 rows
/*
for (int device = 0; device < 4; device++) { // Loop through all 4 displays
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < 8; col++) {
lc.setLed(device, row, col, true); // Light up the row across all devices
}
}
}
// Control the top row (7th row) based on rising/falling across all devices
for (int device = 0; device < 4; device++) {
for (int col = 0; col < 8; col++) {
lc.setLed(device, 7, col, rising);
}
}
*/
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < 8; col++) {
lc.setLed(0, row, col, true); // Light up the row
}
}
// Control the top row (7th row) based on rising/falling
for (int col = 0; col < 8; col++) {
lc.setLed(0, 7, col, rising);
}
}