Use Low-Power library and remove Analog Buttons library.
parent
59d043c1c6
commit
0f38115399
|
@ -20,4 +20,4 @@ lib_deps =
|
|||
adafruit/DHT sensor library @ ^1.4.3
|
||||
adafruit/Adafruit Unified Sensor @ ^1.1.4
|
||||
teckel12/toneAC @ ^1.5.0
|
||||
rlogiacco/Analog Buttons @ ^1.2.1
|
||||
rocketscream/Low-Power @ ^1.81
|
||||
|
|
|
@ -9,6 +9,8 @@ With modification by Joshua Purba.
|
|||
#define DEBUGUTILS_H
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_SETUP() Serial.begin(9600)
|
||||
#define DEBUG_TEARDOWN() Serial.end()
|
||||
#ifndef DEBUG_PRINT
|
||||
#define DEBUG_PRINT(...) Serial.print(__VA_ARGS__)
|
||||
#endif
|
||||
|
@ -16,11 +18,13 @@ With modification by Joshua Purba.
|
|||
#define DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__)
|
||||
#endif
|
||||
#else
|
||||
#define DEBUG_SETUP(...) {}
|
||||
#define DEBUG_TEARDOWN() {}
|
||||
#ifndef DEBUG_PRINT
|
||||
#define DEBUG_PRINT(...)
|
||||
#define DEBUG_PRINT(...) {}
|
||||
#endif
|
||||
#ifndef DEBUG_PRINTLN
|
||||
#define DEBUG_PRINTLN(...)
|
||||
#define DEBUG_PRINTLN(...) {}
|
||||
#endif
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(v) (void) (v)
|
||||
|
|
225
src/main.cpp
225
src/main.cpp
|
@ -1,15 +1,12 @@
|
|||
//#define DEBUG /* Uncomment this line to enable Serial debug output. */
|
||||
// #define DEBUG /* Uncomment this line to enable Serial debug output. */
|
||||
|
||||
#include <AnalogButtons.h>
|
||||
#define USE_STANDARD_LCD
|
||||
#include <LcdMenu.h>
|
||||
#include <ThreeWire.h>
|
||||
#include <RtcDS1302.h>
|
||||
#ifdef DEBUG
|
||||
#define DHT_DEBUG
|
||||
#endif
|
||||
#include <DHT.h>
|
||||
#include <toneAC.h> /* This means only pin 9 and 10 can be used by the buzzer. */
|
||||
#include <LowPower.h>
|
||||
#include "DebugUtil.h"
|
||||
|
||||
/* Command key for each button. This signifies which button is currently pressed. */
|
||||
|
@ -26,8 +23,6 @@
|
|||
#define SCREEN_SET_TIME 2 /* Currently executing menu item "Set Time". */
|
||||
#define SCREEN_SET_ALARM_TIME 3 /* Currently executing menu item "Set Alarm Time". */
|
||||
|
||||
#define SCREEN_TRANSITION 250 /* Screen transition delay in millisecond. */
|
||||
|
||||
/* Edit positions. Used in SCREEN_SET_TIME and SCREEN_SET_ALARM_TIME. */
|
||||
#define EDIT_YEAR 0 /* Editing year. */
|
||||
#define EDIT_MONTH 1 /* Editing month. */
|
||||
|
@ -36,13 +31,8 @@
|
|||
#define EDIT_MINUTE 4 /* Editing minute. */
|
||||
#define EDIT_SECOND 5 /* Editing second. */
|
||||
|
||||
void cbBtnEnter();
|
||||
void cbBtnLeft();
|
||||
void cbBtnUp();
|
||||
void cbBtnDown();
|
||||
void cbBtnRight();
|
||||
void cbBtnBack();
|
||||
void cbBtnNone();
|
||||
void isrBtn();
|
||||
void checkButtons();
|
||||
|
||||
void cbMenuSetTime();
|
||||
void cbMenuToggleAlarm(uint8_t);
|
||||
|
@ -53,8 +43,11 @@ void screenClock();
|
|||
void screenMenu();
|
||||
void screenSetTime();
|
||||
void screenSetAlarmTime();
|
||||
void powerDown(period_t);
|
||||
void screenTransition();
|
||||
void alarm();
|
||||
void resetAlarmRun();
|
||||
void sleep();
|
||||
|
||||
void showClock(const RtcDateTime&, uint8_t, uint8_t, uint8_t, uint8_t);
|
||||
void showDHT();
|
||||
|
@ -69,27 +62,13 @@ void restoreAlarm();
|
|||
|
||||
uint8_t rollOver(uint8_t, uint8_t, uint8_t, boolean);
|
||||
|
||||
#define BTN_HOLD_DURATION 250 /* Button hold duration in millisecond. */
|
||||
#define BTN_HOLD_INTERVAL 100 /* Button hold interval in millisecond. */
|
||||
|
||||
AnalogButtons analogButtons(PIN_A0, INPUT, 1, 26);
|
||||
Button btnEnter = Button(883, &cbBtnEnter, NULL, BTN_HOLD_DURATION, BTN_HOLD_INTERVAL);
|
||||
Button btnLeft = Button(738, &cbBtnLeft , NULL, BTN_HOLD_DURATION, BTN_HOLD_INTERVAL);
|
||||
Button btnUp = Button(584, &cbBtnUp , NULL, BTN_HOLD_DURATION, BTN_HOLD_INTERVAL);
|
||||
Button btnDown = Button(439, &cbBtnDown , NULL, BTN_HOLD_DURATION, BTN_HOLD_INTERVAL);
|
||||
Button btnRight = Button(293, &cbBtnRight, NULL, BTN_HOLD_DURATION, BTN_HOLD_INTERVAL);
|
||||
Button btnBack = Button(144, &cbBtnBack , NULL, BTN_HOLD_DURATION, BTN_HOLD_INTERVAL);
|
||||
|
||||
/* alarmOn and alarmOff is only to prevent the compiler warning: ISO C++ forbids converting a string constant to 'char*' */
|
||||
char alarmOn[] = "Yes";
|
||||
char alarmOff[] = "No";
|
||||
String alarmRunStr[] = { "1m", "5m", "10m", "15m" }; /* Array of allowable alarm runs (displayed in menu). */
|
||||
uint8_t alarmRunMin[] = { 1, 5, 10, 15 }; /* Array of allowable alarm runs (actual minutes). */
|
||||
|
||||
MenuItem mainMenu[] = {
|
||||
ItemHeader(),
|
||||
ItemCommand("Date/Time", cbMenuSetTime),
|
||||
ItemToggle("Alarm", alarmOn, alarmOff, cbMenuToggleAlarm),
|
||||
ItemToggle("Alarm", "Yes", "No", cbMenuToggleAlarm),
|
||||
ItemCommand("Alarm Time", cbMenuSetAlarm),
|
||||
ItemList("Alarm Run", alarmRunStr, 4, cbMenuSetAlarmDuration),
|
||||
ItemFooter()
|
||||
|
@ -98,6 +77,8 @@ MenuItem mainMenu[] = {
|
|||
#define LCD_ROWS 2
|
||||
#define LCD_COLS 16
|
||||
|
||||
extern volatile unsigned long timer0_millis; /* DHT11 depends on millis(). */
|
||||
volatile boolean btnPressed = false;
|
||||
LcdMenu menu(LCD_ROWS, LCD_COLS);
|
||||
ThreeWire rtcWire(7, 8, 6); // DAT, CLK, RST
|
||||
RtcDS1302<ThreeWire> rtc(rtcWire);
|
||||
|
@ -105,6 +86,7 @@ RtcDateTime clockTime; /* The currently displayed clock time. */
|
|||
uint8_t prevSec = 61; /* Pick a value that's not 0 to 60. */
|
||||
uint8_t cmdKey = CMD_IGNORE; /* Which button is currently pressed. */
|
||||
uint8_t currScreen = SCREEN_CLOCK; /* Which screen is currenly active. */
|
||||
boolean screenInTransit = false; /* Flag that the screen transition is in progress, so do not sleep. */
|
||||
boolean editTimeInit = false; /* Is editTime already initialized? */
|
||||
RtcDateTime editTime; /* The time shown when in SCREEN_SET_TIME and SCREEN_SET_ALARM_TIME mode. */
|
||||
boolean alarmActive = false; /* Whether the alarm is currently sounding or not. */
|
||||
|
@ -119,16 +101,14 @@ LiquidCrystal* lcd = NULL; /* Hold reference to menu.lcd .*/
|
|||
|
||||
#define DHT11_INIT 255 /* Value outside DHT11 range (and also not NaN) to signify "please read the sensor value". */
|
||||
|
||||
DHT dht(PIN_A2, DHT11);
|
||||
DHT dht(A1, DHT11);
|
||||
float temperature = DHT11_INIT;
|
||||
float humidity = DHT11_INIT;
|
||||
|
||||
void setup() {
|
||||
#ifdef DEBUG
|
||||
Serial.begin(115200, SERIAL_8N1);
|
||||
#endif
|
||||
DEBUG_SETUP();
|
||||
|
||||
menu.setupLcdWithMenu(12, 11, 5, 4, 3, 2, mainMenu);
|
||||
menu.setupLcdWithMenu(5, 4, 11, 12, A2, A3, mainMenu);
|
||||
menu.hide();
|
||||
lcd = menu.lcd;
|
||||
|
||||
|
@ -144,17 +124,29 @@ void setup() {
|
|||
|
||||
dht.begin();
|
||||
|
||||
analogButtons.add(btnEnter);
|
||||
analogButtons.add(btnLeft);
|
||||
analogButtons.add(btnUp);
|
||||
analogButtons.add(btnDown);
|
||||
analogButtons.add(btnRight);
|
||||
analogButtons.add(btnBack);
|
||||
pinMode(2, INPUT);
|
||||
attachInterrupt(digitalPinToInterrupt(2), isrBtn, RISING);
|
||||
|
||||
pinMode(13, OUTPUT);
|
||||
digitalWrite(13, LOW);
|
||||
|
||||
pinMode(A4, OUTPUT);
|
||||
digitalWrite(A4, HIGH);
|
||||
|
||||
pinMode(A5, OUTPUT);
|
||||
digitalWrite(A5, HIGH);
|
||||
|
||||
pinMode(A6, OUTPUT);
|
||||
digitalWrite(A6, HIGH);
|
||||
|
||||
pinMode(A7, OUTPUT);
|
||||
digitalWrite(A7, HIGH);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
sleep();
|
||||
checkButtons();
|
||||
clockTime = rtc.GetDateTime(); /* Used by the clock display and the alarm trigger. */
|
||||
analogButtons.check();
|
||||
if (currScreen == SCREEN_CLOCK) {
|
||||
screenClock();
|
||||
} else if (currScreen == SCREEN_MENU) {
|
||||
|
@ -168,47 +160,51 @@ void loop() {
|
|||
cmdKey = CMD_IGNORE; /* Must be reset at the end of each loop to prevent button press "lock". */
|
||||
}
|
||||
|
||||
/* Callback when the user pressed the ENTER button. */
|
||||
void cbBtnEnter() {
|
||||
cmdKey = CMD_ENTER;
|
||||
DEBUG_PRINTLN(F("Pressed ENTER"));
|
||||
void isrBtn() {
|
||||
btnPressed = true;
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
}
|
||||
|
||||
/* Callback when the user pressed the LEFT button. */
|
||||
void cbBtnLeft() {
|
||||
cmdKey = CMD_LEFT;
|
||||
DEBUG_PRINTLN(F("Pressed LEFT"));
|
||||
}
|
||||
|
||||
/* Callback when the user pressed the UP button. */
|
||||
void cbBtnUp() {
|
||||
cmdKey = CMD_UP;
|
||||
DEBUG_PRINTLN(F("Pressed UP"));
|
||||
}
|
||||
|
||||
/* Callback when the user pressed the DOWN button. */
|
||||
void cbBtnDown() {
|
||||
cmdKey = CMD_DOWN;
|
||||
DEBUG_PRINTLN(F("Pressed DOWN"));
|
||||
}
|
||||
|
||||
/* Callback when the user pressed the RIGHT button. */
|
||||
void cbBtnRight() {
|
||||
cmdKey = CMD_RIGHT;
|
||||
DEBUG_PRINTLN(F("Pressed RIGHT"));
|
||||
}
|
||||
|
||||
/* Callback when the user pressed the BACK button. */
|
||||
void cbBtnBack() {
|
||||
cmdKey = CMD_BACK;
|
||||
DEBUG_PRINTLN(F("Pressed BACK"));
|
||||
void checkButtons() {
|
||||
if (btnPressed) {
|
||||
const int val = analogRead(A0);
|
||||
if (val >= 1000 && val <= 1023) {
|
||||
cmdKey = CMD_ENTER;
|
||||
DEBUG_PRINTLN(F("ENTER"));
|
||||
} else if (val >= 910 && val <= 930) {
|
||||
cmdKey = CMD_LEFT;
|
||||
DEBUG_PRINTLN(F("LEFT"));
|
||||
} else if (val >= 810 && val <= 830) {
|
||||
cmdKey = CMD_UP;
|
||||
DEBUG_PRINTLN(F("UP"));
|
||||
} else if (val >= 710 && val <= 730) {
|
||||
cmdKey = CMD_DOWN;
|
||||
DEBUG_PRINTLN(F("DOWN"));
|
||||
} else if (val >= 620 && val <= 640) {
|
||||
cmdKey = CMD_RIGHT;
|
||||
DEBUG_PRINTLN(F("RIGHT"));
|
||||
} else if (val >= 530 && val <= 555) {
|
||||
cmdKey = CMD_BACK;
|
||||
DEBUG_PRINTLN(F("BACK"));
|
||||
} else {
|
||||
cmdKey = CMD_IGNORE;
|
||||
DEBUG_PRINT(F("Button value = "));
|
||||
DEBUG_PRINT(val);
|
||||
DEBUG_PRINTLN();
|
||||
}
|
||||
btnPressed = false;
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
} else {
|
||||
cmdKey = CMD_IGNORE;
|
||||
}
|
||||
screenInTransit = false;
|
||||
}
|
||||
|
||||
/* Callback when the user activates the "Set Time" menu item. */
|
||||
void cbMenuSetTime() {
|
||||
menu.hide();
|
||||
currScreen = SCREEN_SET_TIME;
|
||||
delay(SCREEN_TRANSITION);
|
||||
screenTransition();
|
||||
}
|
||||
|
||||
/* Callback when the user toggles the "Alarm" enable/disable menu item. */
|
||||
|
@ -227,7 +223,7 @@ void cbMenuToggleAlarm(const uint8_t yesNo) {
|
|||
void cbMenuSetAlarm() {
|
||||
menu.hide();
|
||||
currScreen = SCREEN_SET_ALARM_TIME;
|
||||
delay(SCREEN_TRANSITION);
|
||||
screenTransition();
|
||||
}
|
||||
|
||||
/* Callback when the user commits (pressed ENTER) the alarm duration in the menu system. */
|
||||
|
@ -246,7 +242,7 @@ void screenClock() {
|
|||
if (cmdKey == CMD_ENTER) {
|
||||
currScreen = SCREEN_MENU;
|
||||
lcd->clear(); /* Only necessary to make the transition uniform. */
|
||||
delay(SCREEN_TRANSITION);
|
||||
screenTransition();
|
||||
menu.show();
|
||||
return;
|
||||
} else if (cmdKey == CMD_BACK) {
|
||||
|
@ -285,7 +281,7 @@ void screenMenu() {
|
|||
temperature = DHT11_INIT; /* If not reset, it will not be redrawn. */
|
||||
humidity = DHT11_INIT; /* If not reset, it will not be redrawn. */
|
||||
currScreen = SCREEN_CLOCK;
|
||||
delay(SCREEN_TRANSITION);
|
||||
screenTransition();
|
||||
} else if (cmdKey == CMD_UP) {
|
||||
DEBUG_PRINTLN(F("Menu UP"));
|
||||
resetAlarmRun();
|
||||
|
@ -314,7 +310,7 @@ void screenSetTime() {
|
|||
editChanged = false;
|
||||
currScreen = SCREEN_MENU;
|
||||
lcd->clear(); /* Only necessary to make the transition uniform. */
|
||||
delay(SCREEN_TRANSITION);
|
||||
screenTransition();
|
||||
menu.show();
|
||||
return;
|
||||
}
|
||||
|
@ -461,7 +457,7 @@ void screenSetAlarmTime() {
|
|||
editChanged = false;
|
||||
currScreen = SCREEN_MENU;
|
||||
lcd->clear(); /* Only necessary to make the transition uniform. */
|
||||
delay(SCREEN_TRANSITION);
|
||||
screenTransition();
|
||||
menu.show();
|
||||
return;
|
||||
}
|
||||
|
@ -512,6 +508,40 @@ void screenSetAlarmTime() {
|
|||
}
|
||||
}
|
||||
|
||||
void powerDown(period_t period) {
|
||||
unsigned long addMillis;
|
||||
if (period == SLEEP_15MS) { addMillis = 15; }
|
||||
else if (period == SLEEP_30MS) { addMillis = 30; }
|
||||
else if (period == SLEEP_60MS) { addMillis = 60; }
|
||||
else if (period == SLEEP_120MS) { addMillis = 120; }
|
||||
else if (period == SLEEP_250MS) { addMillis = 250; }
|
||||
else if (period == SLEEP_500MS) { addMillis = 500; }
|
||||
else if (period == SLEEP_1S) { addMillis = 1000; }
|
||||
else if (period == SLEEP_2S) { addMillis = 2000; }
|
||||
else if (period == SLEEP_4S) { addMillis = 4000; }
|
||||
else if (period == SLEEP_8S) { addMillis = 8000; }
|
||||
else if (period == SLEEP_FOREVER) { addMillis = 0; }
|
||||
if (addMillis > 0) {
|
||||
DEBUG_PRINT(F("Sleep for "));
|
||||
DEBUG_PRINT(addMillis)
|
||||
DEBUG_PRINTLN(F(" ms"));
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("Sleep forever"));
|
||||
}
|
||||
DEBUG_TEARDOWN();
|
||||
LowPower.powerDown(period, ADC_OFF, BOD_OFF);
|
||||
const uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
timer0_millis += addMillis; /* Ensure DHT11 behaves. */
|
||||
SREG = oldSREG;
|
||||
DEBUG_SETUP();
|
||||
}
|
||||
|
||||
void screenTransition() {
|
||||
powerDown(SLEEP_60MS);
|
||||
screenInTransit = true;
|
||||
}
|
||||
|
||||
/*
|
||||
Start the alarm according to the alarmEnabled, alarmHour, and alarmMinute settings.
|
||||
The alarm tone is played continuously until the user stopped the alarm, or the alarm runtime is over.
|
||||
|
@ -520,7 +550,7 @@ void alarm() {
|
|||
boolean stopAlarm = false;
|
||||
const unsigned long now = millis();
|
||||
if (alarmEnabled) {
|
||||
if (clockTime.Hour() == alarmHour && clockTime.Minute() == alarmMinute && clockTime.Second() >= 00 && clockTime.Second() <= 1) {
|
||||
if (!alarmActive && clockTime.Hour() == alarmHour && clockTime.Minute() == alarmMinute && clockTime.Second() >= 00 && clockTime.Second() <= 1) {
|
||||
alarmActive = true;
|
||||
alarmActiveStart = now;
|
||||
DEBUG_PRINTLN(F("Alarm start"));
|
||||
|
@ -551,6 +581,41 @@ void alarm() {
|
|||
}
|
||||
}
|
||||
|
||||
void sleep() {
|
||||
if (alarmActive || screenInTransit) {
|
||||
return;
|
||||
}
|
||||
|
||||
RtcDateTime alarmStart = RtcDateTime(clockTime.Year(), clockTime.Month(), clockTime.Day(), alarmHour, alarmMinute, 0);
|
||||
if (clockTime > alarmStart) {
|
||||
alarmStart = RtcDateTime(alarmStart.TotalSeconds() + (((uint32_t) 24) * ((uint32_t) 60) * ((uint32_t) 60)));
|
||||
}
|
||||
|
||||
const uint32_t as = alarmStart.TotalSeconds();
|
||||
const uint32_t c = clockTime.TotalSeconds();
|
||||
period_t period;
|
||||
if (currScreen == SCREEN_CLOCK) {
|
||||
if (c + 2 <= as) {
|
||||
period = SLEEP_1S;
|
||||
} else {
|
||||
period = SLEEP_250MS;
|
||||
}
|
||||
} else {
|
||||
if (c + 9 <= as) {
|
||||
period = SLEEP_8S;
|
||||
} else if (c + 5 <= as) {
|
||||
period = SLEEP_4S;
|
||||
} else if (c + 3 <= as) {
|
||||
period = SLEEP_2S;
|
||||
} else if (c + 2 <= as) {
|
||||
period = SLEEP_1S;
|
||||
} else {
|
||||
period = SLEEP_250MS;
|
||||
}
|
||||
}
|
||||
powerDown(period);
|
||||
}
|
||||
|
||||
/*
|
||||
Reset the menu if the selected alarm position is not committed yet.
|
||||
Resetting is necessary because the menu system has no indication for committed/uncommitted list position.
|
||||
|
|
Loading…
Reference in New Issue