// Konfigurasi Blynk
#define BLYNK_PRINT Serial // Menggunakan Serial Monitor untuk debug Blynk
#define BLYNK_TEMPLATE_ID "TTMPL6dQO12J1O" // Ganti dengan Template ID Anda
#define BLYNK_TEMPLATE_NAME "Monitoring pH Air" // Ganti dengan Template Name Anda
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#include <SD.h>
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
// Konfigurasi OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Pin untuk sensor pH
#define PH_SENSOR_PIN 34 // Pin ADC pada ESP32
// Pin untuk microSD
#define SD_CS_PIN 5 // Pin CS untuk microSD
// Variabel untuk kalibrasi
float pHValue;
float calibrationOffset = 2.465; // Sesuaikan berdasarkan kalibrasi
// Objek RTC
RTC_DS3231 rtc;
// File untuk menyimpan data
File dataFile;
// Token Blynk, nama WiFi, dan password WiFi
char auth[] = "v2ItHGJfo25zBOKCLmMWXamdvvX253k9"; // Ganti dengan Token Blynk Anda
char ssid[] = "Wokwi-GUEST"; // Ganti dengan SSID WiFi Anda
char pass[] = ""; // Ganti dengan Password WiFi Anda
void setup() {
// Inisialisasi Serial Monitor
Serial.begin(115200);
// Inisialisasi OLED
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("failed to start SSD1306 OLED"));
while (1);
}
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(SSD1306_WHITE);
oled.setCursor(0, 0);
oled.println(F("Sensor pH Air"));
oled.display();
delay(2000);
// Inisialisasi pin ADC
pinMode(PH_SENSOR_PIN, INPUT);
// Inisialisasi RTC
if (!rtc.begin()) {
Serial.println(F("RTC tidak ditemukan!"));
while (1);
}
// Inisialisasi microSD
if (!SD.begin(SD_CS_PIN)) {
Serial.println(F("MicroSD gagal diinisialisasi!"));
while (1);
}
Serial.println(F("MicroSD siap digunakan."));
// Inisialisasi koneksi WiFi dan Blynk
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi terhubung!");
Blynk.begin(auth, ssid, pass); // Hubungkan ke Blynk menggunakan token
// Menunggu sedikit waktu sebelum melanjutkan
delay(1000);
}
void loop() {
// Membaca tegangan dari sensor pH
int analogValue = analogRead(PH_SENSOR_PIN);
float voltage = analogValue * 3.3 / 4095.0; // Konversi ke voltase (ESP32: ADC 12-bit)
// Menghitung nilai pH
pHValue = 3.5 * voltage + calibrationOffset; // Rumus pH standar untuk pH-4502C
// Mendapatkan waktu saat ini dari RTC secara real-time
DateTime now = rtc.now();
String currentTime = String(now.year()) + "-" + String(now.month()) + "-" + String(now.day()) + " " +
String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second());
// Menampilkan data di Serial Monitor
Serial.print("Waktu: ");
Serial.print(currentTime);
Serial.print(" | pH: ");
Serial.println(pHValue, 2);
// Menampilkan data di OLED
oled.clearDisplay();
oled.setCursor(0, 0);
oled.println(F("Monitoring pH Air"));
oled.setCursor(0, 20);
oled.print("Tanggal: ");
oled.print(now.day());
oled.print("/");
oled.print(now.month());
oled.print("/");
oled.println(now.year());
oled.setCursor(0, 40);
oled.print("Jam: ");
oled.print(now.hour());
oled.print(":");
if (now.minute() < 10) oled.print("0"); // Tambahkan '0' untuk menit < 10
oled.print(now.minute());
oled.println();
oled.setCursor(0, 55);
oled.print("Nilai pH: ");
oled.print(pHValue, 2);
oled.display();
// Menyimpan data ke microSD
dataFile = SD.open("/data_pH.txt", FILE_APPEND);
if (dataFile) {
dataFile.print(currentTime);
dataFile.print(", ");
dataFile.println(pHValue, 2);
dataFile.close();
Serial.println(F("Data berhasil disimpan."));
} else {
Serial.println(F("Gagal membuka file untuk menulis!"));
}
// Kirim data ke Blynk
Blynk.virtualWrite(V0, pHValue); // Kirim nilai pH ke Virtual Pin V0
Blynk.virtualWrite(V1, currentTime); // Kirim waktu ke Virtual Pin V1
// Jalankan fungsi Blynk
Blynk.run();
// Tunggu 1 detik sebelum pembacaan berikutnya
delay(1000);
}