//===== EEPROM =====
#include <EEPROM.h>
//=====GENERAL=====
#define rlOn LOW
#define rlOff HIGH
int stateSetting = 0;
//====== DISPLAY =====
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long lastDisplay;
int counterDisplay = 0;
char text[20];
//====== VOLUME =====
#define pinTrig 10
#define pinEcho 9
#define pinPump 11
#define pinForcePump 29
int spMinAir = 20, spMaxAir = 110;
int tinggiWadah = 120, luasPenampang = 30;
int tinggiAir, jarakAir, volumeAir;
int statusVolume = 0; // 0= standby, 1= pengisian
//===== TEMPERATURE =====
#include <OneWire.h>
#include <DallasTemperature.h>
#define pinTemp 8
#define pinToggleTemp 31
#define pinHeater 12
#define pinPeltier 13
OneWire oneWire(pinTemp);
DallasTemperature ds18b20(&oneWire);
float realTemp;
float spLowTemp = 24, spHighTemp = 35, spHys = 0;
int statusHeat = 0; //0 = not set hot, 1=hot
int statusTemp = 0; //0=standby, 1=heating, 2=cooling
unsigned long lastToggle;
//===== PZEM =====
#include <PZEM004Tv30.h>
PZEM004Tv30 pzem(6, 7);
float V = 0, I = 0, P = 0, E = 0;
//===== KEYPAD =====
#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {33, 35, 37, 39};//connect to the row pinouts of the keypad
byte colPins[COLS] = {41, 43, 45, 47}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
unsigned long lastBlink, lastPush;
bool stateBlink;
int stateButton;
char tempChar;
String tempCode;
void setup() {
Serial.begin(9600);
Serial2.begin(9600);
//===== DISPLAY =====
lcd.init(); lcd.backlight();
lcd.setCursor(0, 0); lcd.print("PROGRAM STARTING");
lcd.setCursor(0, 1); lcd.print("[ inisialisasi ]");
//===== VOLUME =====
pinMode(pinTrig, OUTPUT); digitalWrite(pinTrig, LOW);
pinMode(pinPump, OUTPUT); digitalWrite(pinPump, rlOff);
pinMode(pinForcePump, INPUT_PULLUP);
pinMode(pinEcho, INPUT);
//===== TEMPERATURE =====
ds18b20.begin();
pinMode(pinHeater, OUTPUT); digitalWrite(pinHeater, rlOff);
pinMode(pinPeltier, OUTPUT); digitalWrite(pinPeltier, rlOff);
pinMode(pinToggleTemp, INPUT_PULLUP);
//===== LOAD FROM EEROM =====
loadData();
delay(1500);
}
void loop() {
readKeypad();
readVolume();
readTemperature();
readPzem();
setVolume();
setTemperature();
if (stateSetting == 0) setDisplay();
if (Serial2.available()) {
char fromWemos = Serial2.read();
if (fromWemos == 'M') {
if (millis() > (lastToggle + 1000)) {
statusHeat = 1 - statusHeat;
lastToggle = millis();
}
}
}
}
void readVolume() {
digitalWrite(pinTrig, HIGH); delayMicroseconds(10);
digitalWrite(pinTrig, LOW);
long duration = pulseIn(pinEcho, HIGH);
jarakAir = duration / 58;
if (jarakAir < 0) jarakAir = 400;
tinggiAir = tinggiWadah - jarakAir;
if (tinggiAir < 0) tinggiAir = 0;
volumeAir = luasPenampang * tinggiAir;
}
void readTemperature() {
ds18b20.requestTemperatures();
realTemp = ds18b20.getTempCByIndex(0);
}
void readPzem() {
float pzemV = pzem.voltage();
float pzemI = pzem.current();
float pzemP = pzem.power();
float pzemE = pzem.energy();
if (pzemV != NAN) {
V = pzemV;
I = pzemI;
P = pzemP;
E = pzemE;
}
}
void setVolume() {
if (statusVolume == 0) digitalWrite(pinPump, rlOff);
else digitalWrite(pinPump, rlOn);
if (digitalRead(pinForcePump) == LOW) statusVolume = 1;
if (tinggiAir < spMinAir) statusVolume = 1;
if (tinggiAir >= spMaxAir) statusVolume = 0;
}
void setTemperature() {
if (statusHeat == 0) {
if (realTemp > spLowTemp + spHys) {
digitalWrite(pinPeltier, rlOn);
digitalWrite(pinHeater, rlOff);
statusTemp = 2;
}
else {
digitalWrite(pinPeltier, rlOff);
digitalWrite(pinHeater, rlOff);
statusTemp = 0;
}
}
else {
if (realTemp < spHighTemp - spHys) {
digitalWrite(pinPeltier, rlOff);
digitalWrite(pinHeater, rlOn);
statusTemp = 1;
}
else {
digitalWrite(pinPeltier, rlOff);
digitalWrite(pinHeater, rlOff);
statusTemp = 0;
}
}
if (millis() > (lastToggle + 1000) && digitalRead(pinToggleTemp) == LOW) {
statusHeat = 1 - statusHeat;
lastToggle = millis();
}
}
void setDisplay() {
unsigned long thisTime = millis();
if (thisTime > lastDisplay + 500) {
if (counterDisplay < 5) {
// sprintf(text, "[TANGKI] %4dml ", volumeAir);
sprintf(text, "[TANGKI] %4dcm ", tinggiAir);
lcd.setCursor(0, 0); lcd.print(text);
sprintf(text, "%2d-%3dcm [%3dcm]", spMinAir, spMaxAir, tinggiAir);
lcd.setCursor(0, 1); lcd.print(text);
}
else if (counterDisplay < 10) {
sprintf(text, "[TANGKI] %4d ml", tinggiAir);
lcd.setCursor(0, 0); lcd.print(text);
sprintf(text, "PROSES : %s", statusVolume ? " ISI" : "STANDBY");
lcd.setCursor(0, 1); lcd.print(text);
}
else if (counterDisplay < 15) {
sprintf(text, "[TEMP] %s", statusHeat ? " AKTIF" : "NON-AKTIF");
lcd.setCursor(0, 0); lcd.print(text);
sprintf(text, "%02d-%02d%cC [%2d,%1d%cC]", int(spLowTemp), int(spHighTemp), 223, int(realTemp), int(realTemp * 10) % 10, 223);
lcd.setCursor(0, 1); lcd.print(text);
}
else if (counterDisplay < 20) {
sprintf(text, "[TEMP] %s", statusHeat ? " AKTIF" : "NON-AKTIF");
lcd.setCursor(0, 0); lcd.print(text);
lcd.setCursor(0, 1);
switch (statusTemp) {
case 0 : lcd.print("STANDBY "); break;
case 1 : lcd.print("HEATING "); break;
case 2 : lcd.print("COOLING "); break;
}
sprintf(text, "[%2d,%1d%cC]", int(realTemp), int(realTemp * 10) % 10, 223);
lcd.setCursor(8, 1); lcd.print(text);
}
else if (counterDisplay < 25) {
sprintf(text, "[PZEM] %5d W", int(P));
lcd.setCursor(0, 0); lcd.print(text);
sprintf(text, "%03d V %4d mA", int(V), int(I*1000));
lcd.setCursor(0, 1); lcd.print(text);
}
counterDisplay++;
if (counterDisplay >= 25)counterDisplay = 0;
char toSend[50];
//tinggiAir, spMinAir, spMaxAir,statusVolume
//realTemp, spLowTemp, spHighTemp, statusHeat, statusTemp
//V,I,P,E
sprintf(toSend, "*%03d,%04d,%1d#", tinggiAir, int(realTemp * 10), statusHeat);
Serial2.println(toSend);
Serial.println(String(toSend));
lastDisplay = thisTime;
}
}
void readKeypad() {
//===================BLINKING CURSOR===================
if (millis() - lastBlink >= 200 && stateSetting > 0) {
lastBlink = millis();
lcd.setCursor(0, 1); lcd.print("NEW VALUE : ");
lcd.setCursor(11, 1); lcd.print(tempCode);
lcd.setCursor(tempCode.length() + 11, 1);
if (stateBlink)lcd.print(char(255));
else lcd.print(" ");
stateBlink = 1 - stateBlink;
}
if (millis() - lastPush >= 400)stateButton = 0;
//====================SCAN TOMBOL START=========================
if (stateButton == 0) {
tempChar = keypad.getKey();
if (tempChar)stateButton = 1;
}
//===============TOMBOL DITEKAN=================================
if (stateButton == 1) {
stateButton = 2;
lastPush = millis();
if (tempChar == 'A') {
lcd.clear();
sprintf(text, "[TANK MIN] %3dcm", spMinAir);
lcd.setCursor(0, 0); lcd.print(text);
stateSetting = 1;
tempCode = "";
}
else if (tempChar == 'B') {
lcd.clear();
sprintf(text, "[TANK MAX] %3dcm", spMaxAir);
lcd.setCursor(0, 0); lcd.print(text);
lcdBlink(1);
stateSetting = 2;
tempCode = "";
}
else if (tempChar == 'C') {
lcd.clear();
sprintf(text, "[TEMP MIN] %3d%cC", int(spLowTemp), 223);
lcd.setCursor(0, 0); lcd.print(text);
lcdBlink(1);
stateSetting = 3;
tempCode = "";
}
else if (tempChar == 'D') {
lcd.clear();
sprintf(text, "[TEMP MAX] %3d%cC", int(spHighTemp), 223);
lcd.setCursor(0, 0); lcd.print(text);
lcdBlink(1);
stateSetting = 4;
tempCode = "";
}
else if (tempChar == '#' && stateSetting > 0) {
if (stateSetting == 1) EEPROM.write(0, tempCode.toInt());
if (stateSetting == 2) EEPROM.write(1, tempCode.toInt());
if (stateSetting == 3) EEPROM.write(2, tempCode.toInt());
if (stateSetting == 4) EEPROM.write(3, tempCode.toInt());
loadData();
lcdBlink(3);
lcd.setCursor(0, 0); lcd.print("SETTING DISIMPAN");
stateSetting = 0;
tempCode = "";
}
else if (tempChar == '*' && stateSetting > 0) {
if (tempCode.length() < 1) stateSetting = 0;
tempCode = tempCode.substring(0, tempCode.length() - 1);
}
else if (stateSetting > 0) {
if (tempCode.length() < 3) tempCode += tempChar;
else lcdBlink(2);
}
}
}
void lcdBlink(int perulangan) {
while (perulangan > 0) {
lcd.noBacklight(); delay(250);
lcd.backlight(); delay(250);
perulangan--;
}
}
void loadData() {
spMinAir = EEPROM.read(0);
spMaxAir = EEPROM.read(1);
spLowTemp = EEPROM.read(2);
spHighTemp = EEPROM.read(3);
}