226 lines
6.6 KiB
C++
226 lines
6.6 KiB
C++
#include <LiquidCrystal_I2C.h>
|
|
#include <ESP32_Servo.h>
|
|
#include <Wire.h>
|
|
#include <EEPROM.h>
|
|
#include "Arduino.h"
|
|
#include <WiFi.h>
|
|
#include "ESP32MQTTClient.h"
|
|
|
|
const char *ssid = "rasi";
|
|
const char *pass = "12345678";
|
|
char *server = "mqtt://broker.emqx.io:1883";
|
|
|
|
|
|
#define TCAADDR 0x70 // Alamat multiplexer TCA9548A
|
|
#define LCD1_ADDR 0x27 // Alamat LCD pertama
|
|
#define LCD2_ADDR 0x26 // Alamat LCD kedua
|
|
|
|
LiquidCrystal_I2C lcd1(LCD1_ADDR, 16, 2);
|
|
LiquidCrystal_I2C lcd2(LCD2_ADDR, 16, 2);
|
|
|
|
const int col = 16;
|
|
const int row = 2;
|
|
|
|
ESP32MQTTClient mqttClient; // all params are set later
|
|
|
|
Servo myservo; // Create a servo object to control a servo
|
|
int servoPin = 26;
|
|
|
|
float temperature = 25, tdsValue = 0;
|
|
const int sensorPh1 = 34; // Pin analog untuk membaca tegangan dari sensor pH 1
|
|
const int sensorPh2 = 35; // Pin analog untuk membaca tegangan dari sensor pH 2
|
|
float voltage1;
|
|
float pH1;
|
|
float voltage2;
|
|
float pH2;
|
|
|
|
// Nilai-nilai kalibrasi untuk sensor pH 1
|
|
float pH11 = 6.86;
|
|
float voltage11 = 3.06;
|
|
float pH21 = 9.18;
|
|
float voltage21 = 2.53;
|
|
|
|
// Nilai-nilai kalibrasi untuk sensor pH 2
|
|
float pH12 = 6.86;
|
|
float voltage12 = 2.53;
|
|
float pH22 = 9.18;
|
|
float voltage22 = 2.06;
|
|
|
|
const int TdsSensorPin1 = 33;
|
|
const int TdsSensorPin2 = 32;
|
|
|
|
float tdsValue1 = 0;
|
|
float tdsValue2 = 0;
|
|
|
|
float analogToVolt(float adc) {
|
|
float voltase = 3.3;
|
|
float hasil = (adc * voltase) / 4095.0;
|
|
|
|
return hasil;
|
|
}
|
|
|
|
float getPersentaseAdc(int pin) {
|
|
int jumlah = 100;
|
|
float nilai = 0;
|
|
for (int i = 0; i < jumlah; i++) {
|
|
nilai += analogRead(pin);
|
|
}
|
|
|
|
nilai = nilai / jumlah;
|
|
|
|
return nilai;
|
|
}
|
|
|
|
float nilaiTds1(float volt) {
|
|
if (volt > 0) {
|
|
float y = 68.902 * exp(1.1071 * volt);
|
|
return y;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
float nilaiTds2(float volt) {
|
|
if (volt > 0) {
|
|
float y = 71.413 * exp(1.3268 * volt);
|
|
return y;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
Wire.begin();
|
|
myservo.attach(servoPin);
|
|
lcd1.init();
|
|
lcd1.backlight();
|
|
lcd1.clear();
|
|
lcd2.init();
|
|
lcd2.backlight();
|
|
lcd2.clear();
|
|
|
|
mqttClient.enableDebuggingMessages();
|
|
|
|
mqttClient.setURI(server);
|
|
mqttClient.enableLastWillMessage("lwt", "I am going offline");
|
|
mqttClient.setKeepAlive(30);
|
|
WiFi.begin(ssid, pass);
|
|
mqttClient.loopStart();
|
|
|
|
pinMode(TdsSensorPin1, INPUT);
|
|
pinMode(TdsSensorPin2, INPUT);
|
|
}
|
|
|
|
void loop() {
|
|
// Membaca tegangan dari sensor pH
|
|
int jumlahData = 100;
|
|
int total1 = 0;
|
|
int total2 = 0;
|
|
|
|
for (int i = 0; i < jumlahData; i++) {
|
|
int nilai1 = analogRead(sensorPh1); // Membaca nilai analog dari sensor pH 1
|
|
total1 += nilai1; // Menambahkan nilai ke total sensor pH 1
|
|
int nilai2 = analogRead(sensorPh2); // Membaca nilai analog dari sensor pH 2
|
|
total2 += nilai2; // Menambahkan nilai ke total sensor pH 2
|
|
}
|
|
|
|
float rataRata1 = (float)total1 / jumlahData;
|
|
float rataRata2 = (float)total2 / jumlahData;
|
|
|
|
// Mengonversi nilai bacaan analog menjadi tegangan (dalam volt)
|
|
voltage1 = rataRata1 * (3.3 / 4095.0); // 3.3 adalah tegangan referensi pada ESP32
|
|
voltage2 = rataRata2 * (3.3 / 4095.0); // 3.3 adalah tegangan referensi pada ESP32
|
|
|
|
Serial.println("Voltage pH 1: " + String(voltage1));
|
|
Serial.println("Voltage pH 2: " + String(voltage2));
|
|
|
|
// Menggunakan persamaan linier untuk mengonversi tegangan menjadi pH untuk sensor pH 1
|
|
float m1 = (pH21 - pH11) / (voltage21 - voltage11); // Mencari kemiringan (slope) m untuk sensor pH 1
|
|
float c1 = pH11 - m1 * voltage11; // Mencari perpotongan dengan sumbu y (intercept) c untuk sensor pH 1
|
|
pH1 = (voltage1 < 0.01) ? 0 : m1 * voltage1 + c1; // Menggunakan persamaan garis untuk menghitung nilai pH dari voltage1
|
|
|
|
// Menggunakan persamaan linier untuk mengonversi tegangan menjadi pH untuk sensor pH 2
|
|
float m2 = (pH22 - pH12) / (voltage22 - voltage12); // Mencari kemiringan (slope) m untuk sensor pH 2
|
|
float c2 = pH12 - m2 * voltage12; // Mencari perpotongan dengan sumbu y (intercept) c untuk sensor pH 2
|
|
pH2 = (voltage2 < 0.01) ? 0 : m2 * voltage2 + c2; // Menggunakan persamaan garis untuk menghitung nilai pH dari voltage2
|
|
|
|
|
|
float voltTds1 = analogToVolt(getPersentaseAdc(TdsSensorPin1));
|
|
float voltTds2 = analogToVolt(getPersentaseAdc(TdsSensorPin2));
|
|
tdsValue1 = nilaiTds1(voltTds1);
|
|
tdsValue2 = nilaiTds2(voltTds2);
|
|
|
|
// Check TDS levels
|
|
if (tdsValue1 > 900) {
|
|
// Rotate servo (example rotation, adjust as per your servo specifications)
|
|
mqttClient.publish("servo", "1", 0, false);
|
|
myservo.write(0); // Rotate servo to 90 degrees position
|
|
delay(1000); // Wait for the servo to reach the position
|
|
} else {
|
|
// Servo back to initial position or stop rotation
|
|
myservo.write(360); // Rotate servo to 0 degrees position
|
|
delay(1000); // Wait for the servo to reach the position
|
|
}
|
|
|
|
// Menampilkan nilai pH dan TDS ke Serial Monitor
|
|
Serial.println("pH 1: " + String(pH1));
|
|
Serial.println("pH 2: " + String(pH2));
|
|
Serial.println("TDS 1: " + String(tdsValue1) + " ppm");
|
|
Serial.println("TDS 2: " + String(tdsValue2) + " ppm");
|
|
|
|
// Menampilkan nilai pH dan TDS ke LCD
|
|
lcd1.clear();
|
|
lcd2.clear();
|
|
|
|
lcd1.setCursor(0, 1);
|
|
lcd1.print("pH 1: ");
|
|
lcd1.print(pH1);
|
|
lcd2.setCursor(0, 1);
|
|
lcd2.print("pH 2: ");
|
|
lcd2.print(pH2);
|
|
|
|
// Delay 1 detik sebelum membaca kembali
|
|
lcd1.setCursor(0, 0);
|
|
lcd1.print("TDS 1: ");
|
|
lcd1.print(tdsValue1, 0);
|
|
lcd1.print(" ppm");
|
|
lcd2.setCursor(0, 0);
|
|
lcd2.print("TDS 2: ");
|
|
lcd2.print(tdsValue2, 0);
|
|
lcd2.print(" ppm");
|
|
|
|
delay(1000); // Delay 1 detik sebelum membaca kembali
|
|
|
|
String msg1 = "{\"ph\":\"" + String(pH1) + "\",\"tds\":\"" + String(tdsValue1) + "\"}";
|
|
mqttClient.publish("airlaut", msg1, 0, false);
|
|
|
|
String msg2 = "{\"ph\":\"" + String(pH2) + "\",\"tds\":\"" + String(tdsValue2) + "\"}";
|
|
mqttClient.publish("airbersih", msg2, 0, false);
|
|
}
|
|
void onConnectionEstablishedCallback(esp_mqtt_client_handle_t client)
|
|
{
|
|
if (mqttClient.isMyTurn(client)) // can be omitted if only one client
|
|
{
|
|
mqttClient.subscribe("servo", [](const String &topic, const String &payload)
|
|
{
|
|
myservo.write(0); // Rotate servo to 90 degrees position
|
|
delay(1000);
|
|
myservo.write(360);
|
|
delay(1000); });
|
|
}
|
|
mqttClient.subscribe("servo", [](const String &topic, const String &payload)
|
|
{
|
|
myservo.write(360); // Rotate servo to 90 degrees position
|
|
delay(1000);
|
|
myservo.write(0);
|
|
delay(1000); });
|
|
}
|
|
|
|
esp_err_t handleMQTT(esp_mqtt_event_handle_t event)
|
|
{
|
|
mqttClient.onEventCallback(event);
|
|
return ESP_OK;
|
|
}
|
|
|