220 lines
5.8 KiB
C++
220 lines
5.8 KiB
C++
// Blynk credentials
|
|
#define BLYNK_TEMPLATE_ID "TMPL6TZRl9SiF"
|
|
#define BLYNK_TEMPLATE_NAME "Monitoring Ketersediaan Pakan Ikan"
|
|
#define BLYNK_AUTH_TOKEN "W0ak_qwmrPkN8hVrmptQDG_2IYXu3Ftu"
|
|
|
|
#include <Arduino.h>
|
|
#include <Wire.h>
|
|
#include <LiquidCrystal_I2C.h>
|
|
#include "RTClib.h"
|
|
#include <ESP32Servo.h>
|
|
#include <WiFi.h>
|
|
#include <BlynkSimpleEsp32.h>
|
|
|
|
// WiFi credentials
|
|
char ssid[] = "dewi";
|
|
char pass[] = "dewi1234";
|
|
|
|
// Blynk virtual pins
|
|
#define V1_DISTANCE V1
|
|
#define V2_MANUAL_FEED V2
|
|
|
|
// Tampilan LCD
|
|
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C 0x27, LCD 16x2
|
|
|
|
// RTC
|
|
RTC_DS3231 rtc;
|
|
char hariDalamSeminggu[7][12] = {"Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};
|
|
|
|
// Servo dan Buzzer
|
|
Servo servoKatup;
|
|
const int SERVO_PIN = 17;
|
|
const int BUZZER_PIN = 16;
|
|
|
|
// Sensor Ultrasonik
|
|
const int TRIG_PIN = 19;
|
|
const int ECHO_PIN = 18;
|
|
long durasi;
|
|
float jarak;
|
|
const float MAKS_JARAK = 200.0; // Batas maksimum pembacaan jarak yang masuk akal
|
|
|
|
// Waktu pemberian pakan
|
|
const int JAM_PAGI = 7;
|
|
const int MENIT_PAGI = 0;
|
|
const int JAM_SORE = 16;
|
|
const int MENIT_SORE = 0;
|
|
|
|
// Fungsi untuk memperbarui jarak
|
|
void updateJarak() {
|
|
// Kirim pulsa ultrasonik
|
|
digitalWrite(TRIG_PIN, LOW);
|
|
delayMicroseconds(2);
|
|
digitalWrite(TRIG_PIN, HIGH);
|
|
delayMicroseconds(10);
|
|
digitalWrite(TRIG_PIN, LOW);
|
|
|
|
// Hitung durasi pulsa dan konversi ke jarak
|
|
durasi = pulseIn(ECHO_PIN, HIGH);
|
|
jarak = durasi * 0.034 / 2;
|
|
|
|
// Saring pembacaan jarak yang tidak masuk akal
|
|
if (jarak > MAKS_JARAK) {
|
|
jarak = MAKS_JARAK;
|
|
}
|
|
}
|
|
|
|
// Fungsi untuk mengonversi jarak ke ukuran pakan
|
|
int konversiUkuranPakan(float x) {
|
|
x = 10 - jarak;
|
|
if (jarak > 1) {
|
|
return x;
|
|
}
|
|
delay(1000);
|
|
}
|
|
|
|
// Fungsi untuk menampilkan informasi di LCD
|
|
void tampilkanInformasi(DateTime sekarang, int ukuranPakan) {
|
|
lcd.clear();
|
|
|
|
// Tampilkan hari di pojok kiri atas
|
|
lcd.setCursor(0, 0);
|
|
lcd.print(hariDalamSeminggu[sekarang.dayOfTheWeek()]);
|
|
|
|
// Tampilkan jam di pojok kanan atas
|
|
lcd.setCursor(7, 0); // Sesuaikan posisi agar muat di layar
|
|
if (sekarang.hour() < 10) lcd.print('0'); // Tambahkan nol di depan jam jika kurang dari 10
|
|
lcd.print(sekarang.hour(), DEC);
|
|
lcd.print(':');
|
|
if (sekarang.minute() < 10) lcd.print('0'); // Tambahkan nol di depan menit jika kurang dari 10
|
|
lcd.print(sekarang.minute(), DEC);
|
|
lcd.print(':');
|
|
if (sekarang.second() < 10) lcd.print('0'); // Tambahkan nol di depan detik jika kurang dari 10
|
|
lcd.print(sekarang.second(), DEC);
|
|
|
|
// Tampilkan tanggal di pojok kiri bawah
|
|
lcd.setCursor(0, 1);
|
|
if (sekarang.day() < 10) lcd.print('0'); // Tambahkan nol di depan tanggal jika kurang dari 10
|
|
lcd.print(sekarang.day(), DEC);
|
|
lcd.print('/');
|
|
if (sekarang.month() < 10) lcd.print('0'); // Tambahkan nol di depan bulan jika kurang dari 10
|
|
lcd.print(sekarang.month(), DEC);
|
|
lcd.print('/');
|
|
lcd.print(sekarang.year(), DEC);
|
|
}
|
|
|
|
// Fungsi untuk menampilkan informasi pemberian pakan
|
|
void tampilkanPemberianPakan() {
|
|
lcd.clear();
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Pemberian Pakan");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Sedang Diberikan");
|
|
}
|
|
|
|
// Fungsi untuk membuka katup pakan
|
|
void bukaKatupPakan() {
|
|
tampilkanPemberianPakan();
|
|
|
|
// Putar servo untuk membuka dan menutup katup beberapa kali
|
|
for (int i = 0; i < 5; i++) {
|
|
servoKatup.write(90); // Sesuaikan sudut untuk membuka katup
|
|
delay(1000); // Tunggu sampai katup terbuka
|
|
servoKatup.write(0); // Tutup kembali katup
|
|
delay(1000); // Tunggu sebelum putaran berikutnya
|
|
}
|
|
}
|
|
|
|
// Fungsi untuk mengisi pakan
|
|
void isiPakan() {
|
|
// Bunyikan buzzer jika jarak lebih dari 10 cm
|
|
if (jarak > 8) {
|
|
digitalWrite(BUZZER_PIN, HIGH); // Aktifkan buzzer
|
|
delay(1000); // Bunyikan buzzer selama 1 detik
|
|
digitalWrite(BUZZER_PIN, LOW); // Matikan buzzer
|
|
}
|
|
}
|
|
|
|
// Blynk virtual pin handler
|
|
BLYNK_WRITE(V2_MANUAL_FEED) {
|
|
int state = param.asInt();
|
|
if (state == 1) {
|
|
bukaKatupPakan();
|
|
}
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
|
|
lcd.init(); // Inisialisasi LCD
|
|
lcd.backlight(); // Aktifkan backlight LCD
|
|
|
|
// Menampilkan pesan koneksi Wi-Fi di LCD
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Menghubungkan ke");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("WiFi...");
|
|
|
|
// WiFi setup
|
|
WiFi.begin(ssid, pass);
|
|
|
|
// Tunggu sampai terhubung ke WiFi
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(500);
|
|
Serial.print(".");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("WiFi...");
|
|
}
|
|
|
|
lcd.clear();
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Terhubung ke WiFi");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print(WiFi.localIP());
|
|
|
|
// Blynk setup
|
|
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
|
|
|
|
if (!rtc.begin()) {
|
|
Serial.println("RTC tidak ditemukan");
|
|
while (1);
|
|
}
|
|
|
|
if (rtc.lostPower()) {
|
|
Serial.println("RTC kehilangan daya, mari kita atur waktunya!");
|
|
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Atur RTC ke waktu saat ini dari komputer
|
|
}
|
|
|
|
// Inisialisasi servo, buzzer, dan sensor ultrasonik
|
|
servoKatup.attach(SERVO_PIN);
|
|
pinMode(BUZZER_PIN, OUTPUT);
|
|
servoKatup.write(0); // Pastikan katup tertutup pada awalnya
|
|
pinMode(TRIG_PIN, OUTPUT);
|
|
pinMode(ECHO_PIN, INPUT);
|
|
}
|
|
|
|
void loop() {
|
|
Blynk.run();
|
|
|
|
DateTime sekarang = rtc.now();
|
|
updateJarak(); // Perbarui pembacaan jarak
|
|
int ukuranPakan = konversiUkuranPakan(jarak); // Konversi jarak ke ukuran pakan
|
|
Serial.print("Jarak: ");
|
|
Serial.print(jarak);
|
|
Serial.print(" cm, Ukuran Pakan: ");
|
|
Serial.println(ukuranPakan); // Cetak jarak dan ukuran pakan di Serial Monitor
|
|
tampilkanInformasi(sekarang, ukuranPakan); // Tampilkan informasi di LCD
|
|
|
|
// Kirim data ke Blynk
|
|
Blynk.virtualWrite(V1_DISTANCE, ukuranPakan);
|
|
|
|
// Berikan pakan sesuai jadwal
|
|
if ((sekarang.hour() == JAM_PAGI && sekarang.minute() == MENIT_PAGI && sekarang.second() == 0) ||
|
|
(sekarang.hour() == JAM_SORE && sekarang.minute() == MENIT_SORE && sekarang.second() == 0)) {
|
|
bukaKatupPakan();
|
|
}
|
|
|
|
// Periksa jarak dan bunyikan buzzer jika perlu
|
|
isiPakan();
|
|
|
|
delay(1000);
|
|
} |