/* Test 3 buttons
use buttons to enter menu and change value
function for multiple delay with millis
prevent display flicker (test it on NTC)
*/
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
byte hour = 10;
byte minute = 15;
byte second = 20;
unsigned long time;
unsigned long next_millis;
unsigned long seconds;
byte menu = 1; //default
//pins define
#define butSET 10
#define butUP 11
#define butDN 12
#define buzz 6
//const String enMnu[] = {"Manual Control ", "Pool Temp ", "Filtration ", "Heating cirquit ", "Pool cirquit ", "Day Light ", "Display OFF ", "Factory setting ", "EXIT MENU "};
bool butPressed=false; //for catch and delay if but pressed
//term beta
const float BETA = 3950;
float thermFlick;
//multiple delays int delaysVal[n] n-num of millisdelays
int delaysVal[6];
unsigned long startMillis[6]; //initial start time
//keep previousstate
bool xshow = false;
bool xashow = false;
bool xbshow;
/** 0-time on main
1,2,3,4 - free for use
5-menu reset timer
*/
void setup() {
Serial.begin(9600);
pinMode(butSET, INPUT_PULLUP);
pinMode(butUP, INPUT_PULLUP);
pinMode(butDN, INPUT_PULLUP);
pinMode(13, OUTPUT);
pinMode(buzz, OUTPUT);
lcd.begin(16, 2);
lcd.backlight();
lcd.print("TEST" );
beep();
}
void loop() {
float celsius;
//show time on main in 1 sec interval
if (delays(0, 1000)){
showTime();
}
if (delays(3, 500)){
int analogValue = analogRead(A1);
celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
lcd.setCursor(8,0);
lcd.print("T:");
lcd.print(celsius);
//Protect disp flicker on the value edge
if (celsius > 25) thermFlick = 5; //SET antiflicker
if (celsius+thermFlick < 25) thermFlick = 0; //reset flicker
}
//catch button action by page
buttons();
//blink with flicker protection during quick change down/up
if (delays(2, 200) && celsius > 25-thermFlick){
lcd.setCursor(15,1);
if (xashow == false){
lcd.print("X");
xashow = true;
}else{
lcd.print(" ");
xashow = false;
}
}
}
/** millis delays(id, ms)
id - num of delay
ms - time of delay
global var necessary nuber of delays
int delaysVal[n];
unsigned long startMillis[n];
for time extension set
startMillis[n] = millis();
*/
bool delays(int id, int ms){
//init or redefine ms value
if (delaysVal[id] == 0 || delaysVal[id] != ms){
delaysVal[id] = ms;
}
unsigned long currentMillis = millis();
if (currentMillis - startMillis[id] >= delaysVal[id]) {
startMillis[id] = currentMillis;
return true;
}
return false;
}
/*
void menuSet(byte but){
if (menu == 2 && but == 1){
//save value and return to main menu
menu = 1;
but = "";
lcd.clear();
}
if (but == 1 && menu == 1){
lcd.clear();
//vstup do set menu
lcd.setCursor(9, 1);
lcd.print("MENU2");
//menu = 2; //nastevujeme cas
//vstup do menu
settingVal();
}
}
*/
//test menu setting values up and down while set pressed
void settingVal(){
bool setting = true;
int manTime = 200;
startMillis[5] = millis(); //default reset
//delays(5, 10000);//menu init
lcd.clear();
Serial.print("Delay 5 val: ");
Serial.println(startMillis[5]);
//dokud nastavujeme tocime
while(setting){
//reuse 1 with diffrent int
if (delays(1, 500)){
lcd.setCursor(0, 1);
lcd.print(millis());
}
//nastavovani hodnoty, value, step, min, max
manTime = setValue(manTime, 10, 20,220);
lcd.setCursor(0,0);
//if (manTime<100) lcd.print( " " ); //protect leading space
lcd.print( manTime );
if (manTime<100) lcd.print( " " ); //reset rest number
if (butPressed==true){
//provedeme reset prodlouzeni hodnoty spiciho menu
startMillis[5] = millis();
delay(150); //protect button keeping
butPressed=false;
}
//pokud ubehla vterina, tak muzeme kontrolovat ukonceni modu button SET
if (digitalRead(butSET) == LOW && delays(2, 1500)) {
lcd.setCursor(0, 1);
lcd.print( "SET PRESSED");
lcd.setCursor(1, 0);
lcd.print( "SAVE TO MEMORY");
delay(1000);
setting = false;
}
//pokud necinnost
//pokud jsme v modu dele jak minutu, tak to vratime
if (delays(5, 10000)){
//navrat do menu, ukonceni settings
beep();
setting = false;
}
//Serial.print("Delay 5 val: ");
//Serial.println(startMillis[5]);
}
lcd.setCursor(0, 1);
lcd.print( "END SETTING");
delay(500); //protecting enter again
lcd.clear();
}
/** Setting value int-/+ 32767
int setValue(int val, int step, int minVal, int maxVal){
val - incoming value
step - value step
minVal - minimal value
maxVal - maximal value
return val, set butPressed=true for but delay after disp value
*/
int setValue(int val, int step, int minVal, int maxVal){
//nastovovani hodnoty
if (digitalRead(butUP) == LOW){ val+=step; if (val > maxVal){ val = maxVal; beep(); } butPressed=true; }
if (digitalRead(butDN) == LOW){ val-=step; if (val < minVal){ val=minVal; beep(); } butPressed=true; }
return val;
}
//Hlavni menu selection
void beep (){
tone(buzz, 1500); // Send 1KHz sound signal...
delay(100); // ...for 1 sec
noTone(buzz); // Stop sound...
}
//cath buttons
void buttons(){
lcd.setCursor(0,0);
if (digitalRead(butSET) == LOW) {
digitalWrite(13, HIGH);
//menuSet(1);
lcd.print("BUT SET");
//odskok do menu na nastaveni hodnot
settingVal();
delay(100);
}
if (digitalRead(butUP) == LOW) {
digitalWrite(13, HIGH);
lcd.print("BUT UP ");
delay(100);
}
if (digitalRead(butDN) == LOW) {
digitalWrite(13, HIGH);
lcd.print("BUT DN ");
delay(100);
}
digitalWrite(13, LOW);
}
void printDigits(byte digits){
// utility function for digital clock display: prints preceding colon and leading 0
if(digits < 10)
lcd.print('0');
lcd.print(digits,DEC);
}
void showTime(){
int sec;
int min;
int hrs;
if(millis() >= next_millis) {
next_millis += 1000;
time++;
seconds = time;
sec = seconds % 60;
seconds /= 60;
min = seconds % 60;
seconds /= 60;
hrs = seconds % 24;
seconds /= 24;
lcd.setCursor(0, 1);
printDigits(hrs); //lcd.print(hrs,DEC);
lcd.print(":");
printDigits(min);
lcd.print(":");
printDigits(sec);
}
}