#include <EEPROM.h>
#include <Encoder.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>
// Define LCD pins
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Define custom character for the progress bar
byte bar[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111};
#define SW1 4
#define DT1 5
#define CLK1 2
#define SW2 7
#define DT2 10
#define CLK2 3
int scrollStepCount1=4;
int scrollStepCount2=4;
Encoder myEnc1(CLK1, DT1);
Encoder myEnc2(CLK2, DT2);
long oldPosition1 = 0;
long oldPosition2 = 0;
int scrollUp1=0, scrollDown1=0, click1=0;
int scrollUp2=0, scrollDown2=0, click2=0;
// Define button pins
const int toggleButton = 0;
const int RECV_PIN = 1;
// Define output pins
const int sounderPin = 13;
const int relayPin = 12;
int buttonDelay = 500;
IRrecv irrecv(RECV_PIN);
decode_results results;
bool IRSelect = false;
bool IRRun = false;
bool toggleRelay = 0;
// Define presets
int presets[30][5] = {};
String description[30] = {
"AAAA",
"BBB",
"CCCC",
"DDD",
"EEEE",
"FFF",
"GGGG",
"HHH",
"IIII",
"JJJ",
"KKKK",
"LLL",
"MMMM",
"NNN",
"OOOO",
"PPP",
"QQQQQQ",
"RR",
"SSSSSSS",
"TTTTT",
"UU",
"VVVVVVVV",
"WWWWW",
"XXXXXX",
"Y",
"ZZZ",
"ABABABAB",
"CDCD",
"EFEFEFEF",
"GHGH",
};
int run[5] = {0, 0, 0, 0, 0};
int selectedPreset = 0;
bool programmingMode = false;
bool flashing = false;
int currentParameter = 0;
unsigned int previousTime = 0;
unsigned int flashingTime = 200; // 1 sec
unsigned int initialTimeSelectButton = 0;
unsigned int finalTimeSelectButton = 0;
unsigned int timeDelaySelectButton = 1500;
void(* resetFunc) (void) = 0;
bool leftButtonFlag = false;
bool rightButtonFlag = false;
bool selectLongPress = false;
unsigned int currentTimeProgress = 0;
unsigned int previousTimeProgress = 0;
void setup() {
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.createChar(0, bar);
lcd.setCursor(0,0);
lcd.print(" EBSC CONTROLLER");
lcd.setCursor(0,1);
lcd.print(" BY HOFFMAN");
delay(2000);
lcd.clear();
lcd.setCursor(0,2);
lcd.print("PR FC ED FC ED RPT");
lcd.setCursor(0,0);
lcd.print(description[0]);
irrecv.enableIRIn();
// Initialize buttons
pinMode(SW1, INPUT_PULLUP);
pinMode(SW2, INPUT_PULLUP);
pinMode(toggleButton, INPUT_PULLUP);
// Initialize outputs
pinMode(sounderPin, OUTPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(sounderPin, HIGH);
digitalWrite(relayPin, HIGH);
/* for(int j=0; j<30; j++)
{
selectedPreset = EEPROM.read(6*j);
presets[j][0] = EEPROM.read((6*j)+1);
presets[j][1] = EEPROM.read((6*j)+2);
presets[j][2] = EEPROM.read((6*j)+3); // NEED TO BE UNCOMMENTED
presets[j][3] = EEPROM.read((6*j)+4);
presets[j][4] = EEPROM.read((6*j)+5);
}*/
}
void loop() {
getPosition1();
getPosition2();
if( (leftButtonFlag) && (!flashing) )
{
currentParameter--;
if(currentParameter == -1)
{
currentParameter = 5;
}
currentParameter = currentParameter % 6;
leftButtonFlag = false;
}
else if( (rightButtonFlag) && (!flashing) )
{
currentParameter++;
currentParameter = currentParameter % 6;
rightButtonFlag = false;
}
if (irrecv.decode(&results))
{
switch(results.value)
{
case 0x2F5708F: // Replace with IR code for Run button
setRunParameters();
handleRun();
delay(buttonDelay);
break;
case 0x2F540BF: // Replace with IR code for On/Off (Toggle) button
toggleRelay = !toggleRelay;
digitalWrite(relayPin, toggleRelay);
delay(buttonDelay);
break;
case 0x2F5A05F: // Replace with IR code for Reset button
resetFunc();
delay(buttonDelay);
break;
}
irrecv.resume(); // Receive the next value
}
if ((click2 == 1) && (!flashing)) // For Select Button
{
if (!programmingMode)
{
programmingMode = true;
currentParameter = 0;
} else
{
programmingMode = false;
if(selectLongPress)
{
saveToEEPROM();
selectLongPress = false;
}
}
//delay(buttonDelay);
click2 = 0;
}
else if ( scrollDown1 == 1 ) // For Left Button
{
if (programmingMode)
{
leftButtonFlag = true;
}
//delay(buttonDelay);
scrollDown1 = 0;
}
else if ( scrollUp1 == 1 ) // For Right Button
{
if (programmingMode)
{
rightButtonFlag = true;
}
//delay(buttonDelay);
scrollUp1 = 0;
}
else if ( scrollUp2 == 1 ) // For Up Button
{
if (programmingMode)
{
if(currentParameter == 0)
{
selectedPreset++;
selectedPreset = selectedPreset % 30;
}
else if(currentParameter == 5)
{
presets[selectedPreset][4]++;
presets[selectedPreset][4] = presets[selectedPreset][4] % 100;
}
else
{
for(int i=1; i<=4; i++)
{
if(currentParameter == i)
{
presets[selectedPreset][i-1]++;
presets[selectedPreset][i-1] = presets[selectedPreset][i-1] % 100;
}
}
}
}
// delay(buttonDelay);
scrollUp2 = 0;
}
else if ( scrollDown2 == 1 ) // For Down Button
{
if (programmingMode)
{
if(currentParameter == 0)
{
selectedPreset--;
if(selectedPreset < 0)
{
selectedPreset = 29;
}
}
else if(currentParameter == 5)
{
presets[selectedPreset][4]--;
if(presets[selectedPreset][4] < 0)
{
presets[selectedPreset][4] = 99;
}
}
else
{
for(int i=1; i<=4; i++)
{
if(currentParameter == i)
{
presets[selectedPreset][i-1]--;
if(presets[selectedPreset][i-1] < 0)
{
presets[selectedPreset][i-1] = 99;
}
}
}
}
}
// delay(buttonDelay);
scrollDown2 = 0;
}
if((click1 == 1) && (!flashing))
{
setRunParameters();
handleRun();
// delay(buttonDelay);
click1 = 0;
}
if(digitalRead(toggleButton) == LOW)
{
toggleRelay = !toggleRelay;
digitalWrite(relayPin, toggleRelay);
delay(buttonDelay);
}
displayState();
delay(20);
}
void updatePosition1(){
if(click1) {
click1=0;
}
if(scrollUp1) {
scrollUp1=0;
}
if(scrollDown1) {
scrollDown1=0;
}
}
void updatePosition2(){
if(click2) {
click2=0;
}
if(scrollUp2) {
scrollUp2=0;
}
if(scrollDown2) {
scrollDown2=0;
}
}
void getPosition1(){
long newPosition1 = myEnc1.read();
if ((newPosition1 - oldPosition1>=scrollStepCount1)) {
oldPosition1 = newPosition1;
scrollDown1=1;
}
if ((newPosition1 - oldPosition1<=-scrollStepCount1)) {
oldPosition1 = newPosition1;
scrollUp1=1;
}
if(digitalRead(SW1)==0) {
click1=1;
while(digitalRead(SW1)==0) delay(15);
}
}
void getPosition2(){
long newPosition2 = myEnc2.read();
if ((newPosition2 - oldPosition2>=scrollStepCount2)) {
oldPosition2 = newPosition2;
scrollDown2=1;
}
if ((newPosition2 - oldPosition2<=-scrollStepCount2)) {
oldPosition2 = newPosition2;
scrollUp2=1;
}
if(digitalRead(SW2)==0) {
click2=1;
initialTimeSelectButton = millis();
while(digitalRead(SW2)==0)
{
delay(15);
finalTimeSelectButton = millis();
if(finalTimeSelectButton-initialTimeSelectButton > timeDelaySelectButton)
{
selectLongPress = true;
}
}
}
}
void displayState()
{
if (programmingMode)
{
unsigned int currentTime = millis();
if (currentParameter == 0)
{
if((flashing) && ((currentTime-previousTime) > flashingTime))
{
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(description[selectedPreset]);
lcd.setCursor(0, 1);
lcd.print(selectedPreset+1);
getPosition1();
getPosition2();
previousTime = currentTime;
flashing = false;
}
else if((!flashing) && ((currentTime-previousTime) > flashingTime))
{
lcd.setCursor(0, 1);
lcd.print(" ");
getPosition1();
getPosition2();
previousTime = currentTime;
flashing = true;
}
for(int i=1; i<=5; i++)
{
lcd.setCursor((3*i)+1, 1);
if(i == 5)
{
lcd.setCursor((3*i)+2, 1);
}
lcd.print(presets[selectedPreset][i-1]);
getPosition1();
getPosition2();
lcd.print(" ");
getPosition1();
getPosition2();
}
}
else
{
for(int i = 1; i<=5; i++)
{
if (currentParameter == i)
{
if((flashing) && ((currentTime-previousTime) > flashingTime))
{
lcd.setCursor((3*i)+1, 1);
if(i == 5)
{
lcd.setCursor((3*i)+2, 1);
}
lcd.print(presets[selectedPreset][i-1]);
getPosition1();
getPosition2();
previousTime = currentTime;
flashing = false;
}
else if((!flashing) && ((currentTime-previousTime) > flashingTime))
{
lcd.setCursor((3*i)+1, 1);
if(i == 5)
{
lcd.setCursor((3*i)+2, 1);
}
lcd.print(" ");
getPosition1();
getPosition2();
previousTime = currentTime;
flashing = true;
}
}
else
{
lcd.setCursor((3*i)+1, 1);
if(i == 5)
{
lcd.setCursor((3*i)+2, 1);
}
lcd.print(presets[selectedPreset][i-1]);
getPosition1();
getPosition2();
}
}
}
}
else
{
lcd.setCursor(0, 1);
lcd.print(selectedPreset+1);
getPosition1();
getPosition2();
lcd.setCursor(4, 1);
lcd.print(presets[selectedPreset][0]);
getPosition1();
getPosition2();
lcd.setCursor(7, 1);
lcd.print(presets[selectedPreset][1]);
getPosition1();
getPosition2();
lcd.setCursor(10, 1);
lcd.print(presets[selectedPreset][2]);
getPosition1();
getPosition2();
lcd.setCursor(13, 1);
lcd.print(presets[selectedPreset][3]);
getPosition1();
getPosition2();
lcd.setCursor(17, 1);
lcd.print(presets[selectedPreset][4]);
getPosition1();
getPosition2();
}
}
void setRunParameters()
{
for(int i=0; i<5; i++)
{
run[i] = presets[selectedPreset][i];
}
}
void saveToEEPROM()
{
EEPROM.write((6*selectedPreset), selectedPreset);
EEPROM.write(((6*selectedPreset)+1), presets[selectedPreset][0]);
EEPROM.write(((6*selectedPreset)+2), presets[selectedPreset][1]);
EEPROM.write(((6*selectedPreset)+3), presets[selectedPreset][2]);
EEPROM.write(((6*selectedPreset)+4), presets[selectedPreset][3]);
EEPROM.write(((6*selectedPreset)+5), presets[selectedPreset][4]);
}
void handleRun()
{
unsigned int totalTime = 0;
unsigned int timePerUnit = 0;
int barCount = 0;
bool tFlag = 0;
for(int i=0; i<4; i++)
{
totalTime = (totalTime) + (presets[selectedPreset][i]);
}
totalTime = (totalTime)*(presets[selectedPreset][4]);
if(totalTime<60)
{
tFlag = 1;
totalTime = 1000*totalTime;
previousTimeProgress = millis();
}
else
{
previousTimeProgress = millis()/1000;
}
timePerUnit = (1+totalTime)/20;
digitalWrite(sounderPin, LOW);
// delay(200);
digitalWrite(sounderPin, HIGH);
// delay(5000);
toggleRelay = false;
digitalWrite(relayPin, toggleRelay);
for (int i=presets[selectedPreset][4]; i>0; i--)
{
for(int j=0; j<4; j++)
{
for(int k=run[j]; k>=0; k--)
{
lcd.setCursor((3*(j+1)+1), 1);
lcd.print(k);
getPosition1();
getPosition2();
lcd.print(" ");
getPosition1();
getPosition2();
if(k!=0)
{
digitalWrite(relayPin, toggleRelay);
unsigned int currentTime = millis();
previousTime = millis();
while(currentTime - previousTime < 1000)
{
if(tFlag)
{
currentTimeProgress = millis();
}
else
{
currentTimeProgress = millis()/1000;
}
if(currentTimeProgress - previousTimeProgress >= timePerUnit)
{
previousTimeProgress = currentTimeProgress;
lcd.setCursor(barCount, 3);
lcd.write(0);
barCount++;
}
if(digitalRead(toggleButton) == LOW)
{
k = 0;
j = 3;
i = 1;
digitalWrite(relayPin, HIGH);
delay(buttonDelay);
}
currentTime = millis();
delay(20);
}
}
}
toggleRelay = !toggleRelay;
}
run[4]--;
if(run[4]>0)
{
for(int l=0; l<5; l++)
{
lcd.setCursor((3*(l+1)+1), 1);
if(l == 4)
{
lcd.setCursor((3*(l+1)+2), 1);
}
lcd.print(run[l]);
lcd.print(" ");
getPosition1();
getPosition2();
}
}
else
{
lcd.setCursor(17, 1);
lcd.print(run[4]);
lcd.print(" ");
getPosition1();
getPosition2();
digitalWrite(relayPin, HIGH);
digitalWrite(sounderPin, LOW);
// delay(1000);
digitalWrite(sounderPin, HIGH);
// delay(2000);
}
}
totalTime = 0;
lcd.setCursor(0,3);
lcd.print(" ");
}