#include <LiquidCrystal_I2C.h>
#define RELAY_PIN 4
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
#define IA_RATE 50 // impulse to amount rate
#define IT_RATE 15 // impulse to time rate
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_LINES);
uint8_t relayOffChar[8] = {
0b00000,
0b00000,
0b01110,
0b10001,
0b10001,
0b10001,
0b01110,
0b00000,
};
uint8_t relayOnChar[8] = {
0b00000,
0b00000,
0b01110,
0b11111,
0b11111,
0b11111,
0b01110,
0b00000,
};
volatile int totalImpulses = 0;
volatile int leftImpulses = 0;
volatile int tempImpulses = 0;
volatile int totalTime = 0;
volatile int leftTime = 0;
volatile int totalAmount = 0;
volatile int leftAmount = 0;
volatile char startStop = LOW;
volatile int lcdTimer = 60;
volatile char lcdLight = HIGH;
volatile char relay = LOW;
void setupTimer();
void setupIO();
void setupLCD();
void formatTime(int timestamp, char* formatedTime, int bufferSize);
void formatAmount(int amount, char* formatedAmount, int bufferSize);
void addImpulse();
void toggleStartStop();
void countdown();
void setup() {
Serial.begin(9600);
setupTimer();
setupIO();
setupLCD();
}
void loop() {
char formatedAmount[7];
char formatedTime[9];
lcd.setCursor(0, 0);
lcd.print("\x01");
formatAmount(totalAmount, formatedAmount, sizeof(formatedAmount));
lcd.setCursor(1, 0);
lcd.print(formatedAmount);
formatTime(totalTime, formatedTime, sizeof(formatedTime));
lcd.setCursor(8, 0);
lcd.print(formatedTime);
lcd.setCursor(0, 1);
lcd.print("\x02");
formatAmount(leftAmount, formatedAmount, sizeof(formatedAmount));
lcd.setCursor(1, 1);
lcd.print(formatedAmount);
formatTime(leftTime, formatedTime, sizeof(formatedTime));
lcd.setCursor(8, 1);
lcd.print(formatedTime);
// lcd.setCursor(0, 2);
// lcd.print(lcdTimer);
}
ISR(TIMER1_COMPA_vect)
{
OCR1A += 62500;
countdown();
}
void setupTimer() {
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= B00000100;
OCR1A = 62500;
TIMSK1 |= B00000010;
}
void setupIO() {
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), addImpulse, FALLING);
pinMode(3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(3), toggleStartStop, FALLING);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, relay);
}
void setupLCD() {
lcd.init();
lcd.createChar(1, relayOffChar);
lcd.createChar(2, relayOnChar);
}
void formatTime(int timestamp, char* formatedTime, int bufferSize) {
int hours = timestamp / 3600;
int minutes = (timestamp % 3600) / 60;
int seconds = timestamp % 60;
snprintf(formatedTime, bufferSize, "%02d:%02d:%02d", hours, minutes, seconds);
}
void formatAmount(int amount, char* formatedAmount, int bufferSize) {
int f = amount / 100;
int r = amount % 100;
snprintf(formatedAmount, bufferSize, "%3d,%02d", f, r);
}
void addImpulse() {
totalImpulses++;
leftImpulses++;
totalAmount = totalAmount + IA_RATE;
leftAmount = leftAmount + IA_RATE;
totalTime = totalTime + IT_RATE;
leftTime = leftTime + IT_RATE;
}
void toggleStartStop() {
startStop = ! startStop;
relay = ! digitalRead(RELAY_PIN);
digitalWrite(RELAY_PIN, relay);
}
void countdown() {
if (startStop == HIGH) {
if (leftTime > 0) {
leftTime--;
tempImpulses++;
if (tempImpulses == IT_RATE) {
leftAmount -= IA_RATE;
tempImpulses = 0;
}
}
}
}
/* void decrementImpulses() {
if (impulses > 0) {
impulses--;
relay = relay == LOW ? HIGH : LOW;
digitalWrite(4, relay);
}
} */
/* void decrementLcdTimer() {
if (impulses == 0 && lcdTimer > 0) {
lcdTimer--;
}
} */
/* void buttonClick() {
impulses += 20;
lcdTimer = 10;
} */