// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "AiEsp32RotaryEncoder.h"
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SHUTTER_PIN 13
#define SHUTTER_OPEN 255
#define SHUTTER_CLOSED 0
#define ROTARY_ENCODER_A_PIN 32
#define ROTARY_ENCODER_B_PIN 35
#define ROTARY_ENCODER_BUTTON_PIN 25
#define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
//depending on your encoder - try 1,2 or 4 to get expected behaviour
//#define ROTARY_ENCODER_STEPS 1
//#define ROTARY_ENCODER_STEPS 2
#define ROTARY_ENCODER_STEPS 4
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
TimeSpan exposureTime = TimeSpan(0);
TimeSpan exposureDuration = TimeSpan(0);
AiEsp32RotaryEncoder durationEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
void IRAM_ATTR readEncoderISR()
{
durationEncoder.readEncoder_ISR();
}
void setup () {
Serial.begin(115200);
Serial.println("hello");
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// 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));
} else {
Serial.println("RTC started successfully");
}
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(2, 2);
// Display static text
display.println("starting...");
display.display();
pinMode(SHUTTER_PIN, OUTPUT);
durationEncoder.begin();
durationEncoder.setup(readEncoderISR);
bool circleValues = true;
durationEncoder.setBoundaries(0, 86400, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
durationEncoder.setAcceleration(25000); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
}
boolean shouldBeOpen(TimeSpan time) {
int exposureTimeSeconds = exposureTime.totalseconds();
int timeSeconds = time.totalseconds();
int exposureDurationSeconds = exposureDuration.totalseconds();
return exposureTime.totalseconds() > time.totalseconds() && exposureTime.totalseconds() + exposureDuration.totalseconds() < time.totalseconds();
}
void doScreenStuff (TimeSpan now) {
display.clearDisplay();
display.setCursor(0,2);
display.print(" Time: ");
display.print(now.hours());
display.print(":");
display.print(now.minutes());
display.print(":");
display.println(now.seconds());
display.print(" Shoot: ");
display.print(exposureTime.hours());
display.print(":");
display.print(exposureTime.minutes());
display.print(":");
display.println(exposureTime.seconds());
display.print(" Duration: ");
display.print(exposureDuration.hours());
display.print(":");
display.print(exposureDuration.minutes());
display.print(":");
display.println(exposureDuration.seconds());
display.print(" Shutter: ");
display.println(shouldBeOpen(now) ? "open" : "closed");
display.display();
}
void encoderLoop(){
if (durationEncoder.encoderChanged())
{
exposureDuration = TimeSpan(durationEncoder.readEncoder());
}
}
void loop () {
DateTime now = rtc.now();
TimeSpan time = TimeSpan(0, now.hour(), now.minute(), now.second());
encoderLoop();
doScreenStuff(time);
}