Created
February 13, 2019 19:48
-
-
Save glyons/98ab899738b86a6cbc3fec7644a3f176 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Display | |
#include <ESP_SSD1306.h> // Modification of Adafruit_SSD1306 for ESP8266 compatibility | |
#include <Adafruit_GFX.h> // Needs a little change in original Adafruit library (See README.txt file) | |
#include <SPI.h> // For SPI comm (needed for not getting compile error) | |
#include <Wire.h> // For I2C comm, but needed for not getting compile error | |
// Add Encoder Support | |
#include <Encoder.h> | |
// PIN Definitions | |
// ======================================= | |
#define OLED_RESET 16 // Pin 15 -RESET digital signal | |
#define BEEPER_PIN D4 | |
// Change these two numbers to the pins connected to your encoder. | |
// Best Performance: both pins have interrupt capability | |
// Good Performance: only the first pin has interrupt capability | |
// Low Performance: neither pin has interrupt capability | |
#define ENCODER_PINA D5 | |
#define ENCODER_PINB D6 | |
#define ENCODER_PINBUTTON D3 | |
#define RELAY D8 | |
ESP_SSD1306 display(OLED_RESET); // FOR I2C Display | |
Encoder myEnc(ENCODER_PINA, ENCODER_PINB); | |
// Timer | |
// https://playground.arduino.cc/Main/CountDownTimer | |
unsigned long Watch, _micro, timeMicros = micros(); | |
unsigned int Clock = 0, R_clock; | |
boolean Reset = false, Stop = false, Paused = false; | |
volatile boolean timeFlag = false; | |
int INITIAL_DURATION =30; // duration of development in seconds | |
int TIMER_INCREMENT = 1; // seconds | |
int TIMER_INCREMENT2 = 15; // seconds | |
int duration = 0; | |
// Encoder Values | |
long encoderPrevValue = 0; | |
long encoderValue = 0; | |
bool buttonConfirm = false; | |
bool SetupTimerMode = true; | |
void setup() | |
{ | |
// Start Serial | |
Serial.begin(115200); | |
// SSD1306 Init | |
display.begin(SSD1306_SWITCHCAPVCC); // Switch OLED | |
pinMode(RELAY, OUTPUT); | |
StartUpDisplay(); | |
// myservo.attach(SERVO_PIN); // attaches the servo on D8 to the servo object | |
StartUpSound(); | |
} | |
void loop() | |
{ | |
CheckButtonPress(); | |
if (SetupTimerMode) | |
{ | |
digitalWrite(RELAY, LOW); | |
duration = SetupCountdownTimer(INITIAL_DURATION, TIMER_INCREMENT); | |
SetTimer(duration); | |
} | |
else | |
{ | |
CountDownTimer(); // Run Timer | |
} | |
int seconds = ShowSeconds(); | |
int minutes = ShowMinutes(); | |
if (!Stop) | |
{ | |
digitalWrite(RELAY, HIGH); | |
if (TimeHasChanged()) | |
{ | |
UpdateDisplay(minutes, seconds, true); | |
} | |
// Interval Tasks | |
DoIntervalTask(minutes, seconds); | |
if (minutes==0 && seconds==59) | |
{ | |
LastminuteSound(); | |
} | |
} | |
else // Finished | |
{ | |
digitalWrite(RELAY, LOW); | |
if (!buttonConfirm) | |
{ | |
MiddleTextDisplay("Finished!"); | |
// BeepSound(); | |
Clock=0; | |
//Reset Encoder | |
// myEnc.write(duration/TIMER_INCREMENT); | |
} | |
} | |
} | |
// ENCODER | |
// ========================== | |
int GetEncoderValue() | |
{ | |
long _newPosition = myEnc.read(); | |
if (_newPosition != encoderPrevValue) { | |
encoderPrevValue = _newPosition; | |
Serial.println(_newPosition); | |
encoderValue=_newPosition/4; | |
encoderValue=abs(encoderValue); | |
} | |
return encoderValue; | |
} | |
// BUTTON | |
// ========================== | |
void CheckButtonPress() | |
{ | |
int buttonState = digitalRead(ENCODER_PINBUTTON); | |
if (buttonState == LOW) { | |
DoButtonLogic(); | |
} | |
} | |
void DoButtonLogic() | |
{ | |
if (SetupTimerMode) | |
{ | |
BeepSound(); | |
InitTimer(); | |
SetupTimerMode=false; // Start timer; | |
} | |
else | |
{ | |
// Running Mode | |
if (Stop) | |
{ | |
// Finished | |
InitTimer(); | |
buttonConfirm=true; | |
SetupTimerMode =true; | |
delay(500); | |
buttonConfirm=false; | |
} | |
else | |
{ | |
// Pause / Play | |
// Paused = !Paused; | |
if (Paused) | |
{ | |
BeepSound(); | |
} | |
delay(500); | |
} | |
} | |
} | |
int SetupCountdownTimer(int initDuration, int increment) | |
{ | |
int totalSeconds = GetEncoderValue()*increment; | |
int mins = (totalSeconds / 60) % 60; | |
int secs= totalSeconds - mins*60; | |
UpdateDisplay(mins, secs, false); | |
return totalSeconds; | |
} | |
// BEEPER SOUNDS | |
// ========================== | |
// Play tune on start up | |
void StartUpSound() | |
{ | |
tone(BEEPER_PIN, 2000, 400); | |
delay(600); | |
tone(BEEPER_PIN, 800, 400); | |
delay(600); | |
tone(BEEPER_PIN, 2000, 400); | |
} | |
void LastminuteSound() | |
{ | |
tone(D4,3000, 200); | |
} | |
// Default Beep | |
void BeepSound() | |
{ | |
tone(D4, 4200, 100); | |
} | |
// DISPLAY | |
// ========================== | |
void StartUpDisplay() | |
{ | |
// Show image buffer on the display hardware. | |
// Since the buffer is intialized with an Adafruit splashscreen | |
// internally, this will display the splashscreen. | |
display.display(); | |
// Clear the buffer. | |
display.clearDisplay(); | |
display.setTextSize(1); | |
display.setTextColor(WHITE); | |
display.setCursor(0,0); | |
display.println("Darkroom Timer V1.0"); | |
display.setTextSize(1); | |
display.println("blog.glyons.at"); | |
display.display(); | |
} | |
// Display the Countdown Time | |
void UpdateDisplay(int minutes, int seconds, bool showArrows) | |
{ | |
// Debug | |
Serial.print(ShowHours()); | |
Serial.print(":"); | |
Serial.print(minutes); | |
Serial.print(":"); | |
Serial.print(seconds); | |
Serial.print(":"); | |
Serial.print(ShowMilliSeconds()); | |
Serial.print(":"); | |
Serial.println(ShowMicroSeconds()); | |
int cursorY=20; | |
display.clearDisplay(); | |
if (minutes==0) | |
{ | |
display.setCursor(30,cursorY); | |
display.setTextSize(4); | |
display.print(seconds); | |
display.println("s"); | |
} | |
else | |
{ | |
display.setCursor(10,cursorY); | |
display.setTextSize(3); | |
display.print(minutes); | |
display.setTextSize(2); | |
display.print("m "); | |
display.setTextSize(3); | |
display.print(seconds); | |
display.setTextSize(2); | |
display.println("s"); | |
} | |
if (showArrows) | |
{ | |
if (!Paused) | |
{ | |
} | |
} | |
if (Paused) | |
{ | |
MiddleTextDisplay("Reset ?"); | |
} | |
display.display(); | |
} | |
void BottomTextDisplay(char* Text) | |
{ | |
display.setTextSize(2); | |
display.setCursor(10,50); | |
display.println(Text); | |
} | |
void MiddleTextDisplay(char* Text) | |
{ | |
display.clearDisplay(); | |
display.setCursor(10,20); | |
display.setTextSize(2); | |
display.println(Text); | |
display.display(); | |
} | |
// Tasks | |
// ========================== | |
// Change servo direction on every interval | |
void DoIntervalTask(int minutes, int seconds) | |
{ | |
// Add Interval Code in here | |
} | |
// Timer | |
// ========================== | |
boolean CountDownTimer() | |
{ | |
static unsigned long duration = 1000000; // 1 second | |
timeFlag = false; | |
if (!Stop && !Paused) // if not Stopped or Paused, run timer | |
{ | |
// check the time difference and see if 1 second has elapsed | |
if ((_micro = micros()) - timeMicros > duration ) | |
{ | |
Clock--; | |
timeFlag = true; | |
if (Clock == 0) // check to see if the clock is 0 | |
Stop = true; // If so, stop the timer | |
// check to see if micros() has rolled over, if not, | |
// then increment "timeMicros" by duration | |
_micro < timeMicros ? timeMicros = _micro : timeMicros += duration; | |
} | |
} | |
return !Stop; // return the state of the timer | |
} | |
void ResetTimer() | |
{ | |
SetTimer(R_clock); | |
Stop = false; | |
} | |
void InitTimer() | |
{ | |
Watch = micros(); // get the initial microseconds at the start of the timer | |
timeMicros = micros(); // hwd added so timer will reset if stopped and then started | |
Stop = false; | |
Paused = false; | |
} | |
void StopTimer() | |
{ | |
Stop = true; | |
} | |
void StopTimerAt(unsigned int hours, unsigned int minutes, unsigned int seconds) | |
{ | |
if (TimeCheck(hours, minutes, seconds) ) | |
Stop = true; | |
} | |
void PauseTimer() | |
{ | |
Paused = true; | |
} | |
void ResumeTimer() // You can resume the timer if you ever stop it. | |
{ | |
Paused = false; | |
} | |
void SetTimer(unsigned int seconds) | |
{ | |
// StartTimer(seconds / 3600, (seconds / 3600) / 60, seconds % 60); | |
Clock = seconds; | |
R_clock = Clock; | |
Stop = false; | |
} | |
int ShowHours() | |
{ | |
return Clock / 3600; | |
} | |
int ShowMinutes() | |
{ | |
return (Clock / 60) % 60; | |
} | |
int ShowSeconds() | |
{ | |
return Clock % 60; | |
} | |
unsigned long ShowMilliSeconds() | |
{ | |
return (_micro - Watch)/ 1000.0; | |
} | |
unsigned long ShowMicroSeconds() | |
{ | |
return _micro - Watch; | |
} | |
boolean TimeHasChanged() | |
{ | |
return timeFlag; | |
} | |
// output true if timer equals requested time | |
boolean TimeCheck(unsigned int hours, unsigned int minutes, unsigned int seconds) | |
{ | |
return (hours == ShowHours() && minutes == ShowMinutes() && seconds == ShowSeconds()); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment