/*
Forum: https://forum.arduino.cc/t/relay-wont-switch-in-my-project/1182004/4
Wokwi: https://wokwi.com/projects/379549071654633473
*/
#define WOKWI
#ifdef WOKWI
#define BLYNK_TEMPLATE_ID "xxxxxxx"
#define BLYNK_TEMPLATE_NAME "xxxxxxx"
#define BLYNK_AUTH_TOKEN "xxxxxxxx"
#endif
#include <Wire.h>
#include <Blynk.h>
#include <LiquidCrystal_I2C.h>
#ifndef WOKWI
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#endif
//Initialize the LCD display
LiquidCrystal_I2C lcd(0x27, 16, 2);
char auth[] = "xxx";//Enter your Auth token
char ssid[] = "xxx";//Enter your WIFI name
char pass[] = "xxx";//Enter your WIFI password
BlynkTimer timer;
#ifdef WOKWI
#define pinSensor 15 // mendefinisikan pin A0 sebagai pin yang berhubungan dengan sensor
#define PIN_RELAY_1 5 // the Arduino pin, which connects to the IN1 pin of relay module
#define PIN_RELAY_2 4 // the Arduino pin, which connects to the IN1 pin of relay module
#else
#define pinSensor A0 // mendefinisikan pin A0 sebagai pin yang berhubungan dengan sensor
#define PIN_RELAY_1 D3 // the Arduino pin, which connects to the IN1 pin of relay module
#define PIN_RELAY_2 D4 // the Arduino pin, which connects to the IN1 pin of relay module
#endif
constexpr int startThreshold = 2; // pumping shall start at startThreshold [cm] and above
constexpr int stopThreshold = 1; // pumping shall start at stopThreshold [cm] and below
int sensorValue = 0; // variable untuk menampung nilai baca dari sensor dalam bentuk integer
float tinggiAir = 0; // variabel untuk menampung ketinggian air
float sensorVoltage = 0; // untuk menampung nilai ketinggian air
int nilaiMax = 686; // nilai "sensorValue" saat sensor terendam penuh kedalam air, bisa dirubah sesuai sensor dan jenis air yang anda pakai
float panjangSensor = 4.0 ; // 4.0 cm
enum StatusType {CHECKLEVEL, LEVELHIGH, PUMPING};
StatusType status = LEVELHIGH; // Let's start with LEVELHIGH to check level and set the display correctly
void setup() {
Serial.begin(115200);
#ifdef WOKWI
lcd.init();
#else
lcd.begin();
Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
#endif
lcd.backlight();
pinMode(PIN_RELAY_1, OUTPUT);
pinMode(PIN_RELAY_2, OUTPUT);
digitalWrite(PIN_RELAY_1, HIGH);
digitalWrite(PIN_RELAY_2, HIGH);
lcd.setCursor(0, 0);
lcd.print("Water level");
lcd.setCursor(4, 1);
lcd.print("Monitoring");
delay(4000);
lcd.clear();
timer.setInterval(100L, wLevel);
}
void wLevel() {
sensorValue = analogRead(pinSensor); // membaca tengan dari sensor dalam bentuk integer
tinggiAir = sensorValue * panjangSensor / nilaiMax;
sensorVoltage = sensorValue * 5.0 / 686;
}
void loop() {
#ifndef WOKWI
Blynk.run();
#endif
timer.run();
handleStatus();
}
void handleStatus() {
switch (status) {
case CHECKLEVEL:
// Wait for level above threshold
if (tinggiAir >= startThreshold) { // if wlevel more than startThreshold [cm], then
status = LEVELHIGH;
Serial.println("LEVELHIGH");
}
break;
case LEVELHIGH:
levelIsHigh();
break;
case PUMPING:
if (tinggiAir < stopThreshold) { // if wlevel less than stopThreshold [cm] (use hysteresis!) then
levelIsLowAgain();
status = CHECKLEVEL;
Serial.println("CHECKLEVEL");
}
break;
}
displayValues();
}
void displayValues() {
static int oldSensorValue = -1; // variable untuk menampung nilai baca dari sensor dalam bentuk integer
float oldTinggiAir = -1; // variabel untuk menampung ketinggian air
float oldSensorVoltage = -1; // untuk menampung nilai ketinggian air
if (oldSensorValue != sensorValue ||
oldTinggiAir != tinggiAir ||
oldSensorVoltage != sensorVoltage) {
Serial.print("Sensor Value = ");
Serial.println(sensorValue);
Serial.print("Sensor Voltage = ");
Serial.println(sensorVoltage);
Serial.print("Tinggi Air = ");
Serial.println(tinggiAir);
Serial.println();
// Display ke LCD
lcd.setCursor(0, 0);
lcd.print("WLevel:");
lcd.print(tinggiAir);
lcd.setCursor(12, 0);
lcd.print("cm");
oldSensorValue = sensorValue;
oldTinggiAir = tinggiAir;
oldSensorVoltage = sensorVoltage;
#ifndef WOKWI
Blynk.virtualWrite(V0, tinggiAir);
#endif
}
}
void levelIsHigh() {
digitalWrite(PIN_RELAY_1, HIGH);
digitalWrite(PIN_RELAY_2, LOW);
lcd.setCursor(0, 1);
lcd.print("F:OFF P:ON");
#ifndef WOKWI
Blynk.logEvent("wlevel", "wLevel more than 2cm");
#endif
status = PUMPING;
Serial.println("PUMPING");
}
void levelIsLowAgain() {
digitalWrite(PIN_RELAY_1, LOW);
digitalWrite(PIN_RELAY_2, HIGH);
lcd.setCursor(0, 1);
lcd.print("F:ON P:OFF");
status = CHECKLEVEL;
Serial.println("CHECKLEVEL");
}