#include "pitches.h"
#include <LiquidCrystal_I2C.h> // Library for LCD
#include <RTClib.h>
//#include "InputDebounce.h"
#define VERSION "0.01"
#define SPEAKER_PIN 8
#define LID_BTN_PIN 2
#define MAN_BTN_PIN 3
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows
RTC_DS1307 rtc;
// state
#define ERROR 0
#define RUNNING 1
#define PAUSED 2
int state = ERROR;
bool lid_open = false;
int lid_state = LOW;
template<int PIN>
bool readButton(int & buttonState) {
static int lastButtonState = 0; // the previous reading from the input pin
static unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
static unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
// read the state of the switch into a local variable:
int reading = digitalRead(PIN);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
lastButtonState = reading;
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
return true;
}
return false;
}
}
volatile auto lid_event = 0;
void lid_btn_isr(){
lid_event = true;
}
void set_lid_state(){
static auto last_mils = 0;
Serial.print("set_lid_state(): ");
Serial.print(last_mils, DEC);
Serial.print("-");
Serial.println(millis(), DEC);
if(abs(millis() - last_mils) > 100) {
lid_open = digitalRead(LID_BTN_PIN) == HIGH;
Serial.println((lid_open ? "lid open" : "lid closed"));
}
last_mils = millis();
}
void set_man_state(bool pressed){
Serial.print("set_man_state() - ");
Serial.println(pressed, DEC);
if(state == RUNNING){
state = PAUSED;
}
else if(state == PAUSED){
state = RUNNING;
}
}
void man_btn_isr(){
Serial.println("man_btn_isr()");
static auto last_mils = millis();
if(millis() == last_mils || abs(millis() - last_mils) > 100)
set_man_state(digitalRead(LID_BTN_PIN) == HIGH);
}
void setup()
{
Serial.begin(9600);
Serial.println("Pillbox v" VERSION);
pinMode(LID_BTN_PIN, INPUT_PULLUP);
//attachInterrupt(digitalPinToInterrupt(LID_BTN_PIN), lid_btn_isr, CHANGE);
pinMode(MAN_BTN_PIN, INPUT_PULLUP);
//attachInterrupt(digitalPinToInterrupt(MAN_BTN_PIN), man_btn_isr, CHANGE);
pinMode(SPEAKER_PIN, OUTPUT);
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight
lcd.setCursor(0,0);
lcd.print("take your pill" VERSION);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
lid_open = digitalRead(LID_BTN_PIN) == HIGH;
state = PAUSED;
}
void print_time(){
DateTime now = rtc.now();
Serial.print("Now: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
// Serial.print(" (");
// Serial.print(now.dayOfTheWeek());
// Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.println(now.second(), DEC);
lcd.setCursor(1,0);
lcd.print("Now: ");
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
// lcd.print(" (");
// lcd.print(now.dayOfTheWeek());
// lcd.print(") ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
}
void loop () {
if(readButton<LID_BTN_PIN>(lid_state)) {
lid_open = lid_state == HIGH;
Serial.println((lid_open ? "lid open" : "lid closed"));
}
}