Dernière activité 1766034188

Révision 5b9e903e56510a6df33c8981466b9c3fa13a0d80

penyiraman-iot.ino Brut
1#include <WiFi.h>
2#include <Firebase_ESP_Client.h>
3#include <DHT.h>
4#include "addons/TokenHelper.h"
5#include "addons/RTDBHelper.h"
6
7// ====== KONFIGURASI WIFI ======
8#define WIFI_SSID "sandata"
9#define WIFI_PASSWORD "gnulibre567"
10
11// ====== KONFIGURASI FIREBASE ======
12#define API_KEY "AIzaSyAO4ja4G-y20Qv20pe_kU7-vItW908nec4"
13#define DATABASE_URL "https://penyiramanotomatis-3f962-default-rtdb.asia-southeast1.firebasedatabase.app/"
14
15// ====== PIN SENSOR DAN RELAY ======
16#define DHTPIN 4
17#define DHTTYPE DHT11
18#define SOIL_PIN 36
19#define RELAY_PIN 5
20
21DHT dht(DHTPIN, DHTTYPE);
22
23FirebaseData fbdo;
24FirebaseAuth auth;
25FirebaseConfig config;
26
27unsigned long sendDataPrevMillis = 0;
28bool signupOK = false;
29bool modeOtomatis = true;
30
31int moistureThreshold = 30; // default kalau Firebase gagal
32unsigned long lastFetchThreshold = 0;
33
34void fetchThresholdFromFirebase() {
35 if (Firebase.RTDB.getInt(&fbdo, "controls/pump/moisture_threshold")) {
36 moistureThreshold = fbdo.intData();
37 Serial.println("Threshold diperbarui: " + String(moistureThreshold) + "%");
38 } else {
39 Serial.println("Gagal ambil threshold: " + fbdo.errorReason());
40 }
41}
42
43void setup() {
44 Serial.begin(115200);
45 dht.begin();
46 pinMode(SOIL_PIN, INPUT);
47 pinMode(RELAY_PIN, OUTPUT);
48 digitalWrite(RELAY_PIN, LOW);
49
50 // ====== KONEKSI WIFI ======
51 WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
52 Serial.print("Menghubungkan WiFi");
53 while (WiFi.status() != WL_CONNECTED) {
54 Serial.print(".");
55 delay(300);
56 }
57 Serial.println("\nTerhubung ke WiFi!");
58
59 // ====== KONFIGURASI FIREBASE ======
60 config.api_key = API_KEY;
61 config.database_url = DATABASE_URL;
62
63 if (Firebase.signUp(&config, &auth, "", "")) {
64 Serial.println("Firebase SignUp OK");
65 signupOK = true;
66 } else {
67 Serial.printf("SignUp Error: %s\n", config.signer.signupError.message.c_str());
68 }
69
70 Firebase.begin(&config, &auth);
71 Firebase.reconnectWiFi(true);
72}
73
74void loop() {
75 if (!Firebase.ready() || !signupOK) return;
76
77 // === BACA SENSOR ===
78 float suhu = dht.readTemperature();
79 float kelembapanUdara = dht.readHumidity();
80 int soilValue = analogRead(SOIL_PIN);
81 float kelembapanTanah = map(soilValue, 4095, 0, 0, 100);
82
83 Serial.println("===========================");
84 Serial.println("Suhu: " + String(suhu) + "°C");
85 Serial.println("Kelembapan Udara: " + String(kelembapanUdara) + "%");
86 Serial.println("Kelembapan Tanah: " + String(kelembapanTanah) + "%");
87
88 // === BACA MODE DARI FIREBASE ===
89 if (Firebase.RTDB.getString(&fbdo, "controls/pump/mode")) {
90 String mode = fbdo.stringData();
91 modeOtomatis = (mode == "otomatis");
92 }
93
94 fetchThresholdFromFirebase();
95
96 // === KONTROL POMPA ===
97 if (modeOtomatis) {
98 if (kelembapanTanah < moistureThreshold) {
99 digitalWrite(RELAY_PIN, LOW); // pompa menyala
100 Firebase.RTDB.setStringAsync(&fbdo, "status/pompa", "ON");
101 Serial.println("Pompa ON (otomatis - tanah kering)");
102 } else {
103 digitalWrite(RELAY_PIN, HIGH); // pompa mati
104 Firebase.RTDB.setStringAsync(&fbdo, "status/pompa", "OFF");
105 Serial.println("Pompa OFF (otomatis - tanah lembap)");
106 }
107 } else {
108 // === MODE MANUAL ===
109 if (Firebase.RTDB.getString(&fbdo, "status/pompa")) {
110 String control = fbdo.stringData();
111 if (control == "ON") {
112 digitalWrite(RELAY_PIN, HIGH);
113 Serial.println("Pompa ON (manual)");
114 } else {
115 digitalWrite(RELAY_PIN, LOW);
116 Serial.println("Pompa OFF (manual)");
117 }
118 }
119 }
120
121 // === KIRIM DATA SENSOR SETIAP 3 DETIK ===
122 if (millis() - sendDataPrevMillis > 3000) {
123 sendDataPrevMillis = millis();
124 Firebase.RTDB.setFloat(&fbdo, "sensor/suhu", suhu);
125 Firebase.RTDB.setFloat(&fbdo, "sensor/kelembapan_udara", kelembapanUdara);
126 Firebase.RTDB.setFloat(&fbdo, "sensor/kelembapan_tanah", kelembapanTanah);
127 Serial.println("Data sensor dikirim ke Firebase!");
128 }
129
130 delay(3000);
131}
penyiraman-with-log.ino Brut
1#include <WiFi.h>
2#include <Firebase_ESP_Client.h>
3#include <DHT.h>
4#include "addons/TokenHelper.h"
5#include "addons/RTDBHelper.h"
6#include <time.h>
7
8// ====== KONFIGURASI WIFI ======
9#define WIFI_SSID "sandata"
10#define WIFI_PASSWORD "gnulibre567"
11
12// ====== KONFIGURASI FIREBASE ======
13#define API_KEY "AIzaSyAO4ja4G-y20Qv20pe_kU7-vItW908nec4"
14#define DATABASE_URL "https://penyiramanotomatis-3f962-default-rtdb.asia-southeast1.firebasedatabase.app/"
15
16// ====== PIN SENSOR DAN RELAY ======
17#define DHTPIN 4
18#define DHTTYPE DHT11
19#define SOIL_PIN 36
20#define RELAY_PIN 5
21
22DHT dht(DHTPIN, DHTTYPE);
23
24FirebaseData fbdo;
25FirebaseAuth auth;
26FirebaseConfig config;
27
28unsigned long sendDataPrevMillis = 0;
29bool signupOK = false;
30bool modeOtomatis = true;
31
32int moistureThreshold = 30; // default kalau Firebase gagal
33unsigned long lastFetchThreshold = 0;
34
35const unsigned long LOG_INTERVAL =
36 60UL * 60UL * 1000UL; // 1 jam (ms)
37
38unsigned long lastLogTime = 0;
39
40void fetchThresholdFromFirebase() {
41 if (Firebase.RTDB.getInt(&fbdo, "controls/pump/moisture_threshold")) {
42 moistureThreshold = fbdo.intData();
43 Serial.println("Threshold diperbarui: " + String(moistureThreshold) + "%");
44 } else {
45 Serial.println("Gagal ambil threshold: " + fbdo.errorReason());
46 }
47}
48
49void loadLastLogTime() {
50 if (Firebase.RTDB.getInt(&fbdo, "/monitoring/meta/lastLogTime")) {
51 lastLogTime = fbdo.intData();
52 Serial.println("LastLogTime loaded");
53 }
54}
55
56void saveLastLogTime(unsigned long ts) {
57 Firebase.RTDB.setInt(
58 &fbdo,
59 "/monitoring/meta/lastLogTime",
60 ts
61 );
62}
63
64unsigned long getTimestamp() {
65 time_t now;
66 time(&now);
67 return (unsigned long)now * 1000;
68}
69
70String getDateKey() {
71 struct tm timeinfo;
72 if (!getLocalTime(&timeinfo)) return "unknown";
73
74 char buf[11];
75 strftime(buf, sizeof(buf), "%Y-%m-%d", &timeinfo);
76 return String(buf);
77}
78
79String getDateOffset(int days) {
80 time_t now;
81 time(&now);
82 now += days * 86400;
83
84 struct tm timeinfo;
85 localtime_r(&now, &timeinfo);
86
87 char buf[11];
88 strftime(buf, sizeof(buf), "%Y-%m-%d", &timeinfo);
89 return String(buf);
90}
91
92
93void sendHourlyLog(
94 unsigned long ts,
95 float suhu,
96 float humidity,
97 int soilMoisture
98) {
99 String dateKey = getDateKey();
100
101 FirebaseJson json;
102 json.set("timestamp", ts);
103 json.set("suhu", suhu);
104 json.set("humidity", humidity);
105 json.set("soilMoisture", soilMoisture);
106
107 // push ke logs/tanggal
108 String path = "/monitoring/logs/" + dateKey;
109 Firebase.RTDB.pushJSON(&fbdo, path, &json);
110
111 Serial.println("Log tersimpan: " + path);
112}
113
114void deleteOldDate() {
115 String oldDate = getDateOffset(-2); // 2 hari lalu
116 String path = "/monitoring/logs/" + oldDate;
117
118 Firebase.RTDB.deleteNode(&fbdo, path);
119 Serial.println("Hapus data: " + path);
120}
121
122void setup() {
123 Serial.begin(115200);
124 dht.begin();
125 pinMode(SOIL_PIN, INPUT);
126 pinMode(RELAY_PIN, OUTPUT);
127 digitalWrite(RELAY_PIN, LOW);
128
129 // ====== KONEKSI WIFI ======
130 WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
131 Serial.print("Menghubungkan WiFi");
132 while (WiFi.status() != WL_CONNECTED) {
133 Serial.print(".");
134 delay(300);
135 }
136 Serial.println("\nTerhubung ke WiFi!");
137
138 // NTP untuk timestamp
139 configTime(7 * 3600, 0, "pool.ntp.org", "time.nist.gov");
140
141 // ====== KONFIGURASI FIREBASE ======
142 config.api_key = API_KEY;
143 config.database_url = DATABASE_URL;
144
145 if (Firebase.signUp(&config, &auth, "", "")) {
146 Serial.println("Firebase SignUp OK");
147 signupOK = true;
148 loadLastLogTime();
149 } else {
150 Serial.printf("SignUp Error: %s\n", config.signer.signupError.message.c_str());
151 }
152
153 Firebase.begin(&config, &auth);
154 Firebase.reconnectWiFi(true);
155}
156
157void loop() {
158 if (!Firebase.ready() || !signupOK) return;
159
160 // === BACA SENSOR ===
161 float suhu = dht.readTemperature();
162 float kelembapanUdara = dht.readHumidity();
163 int soilValue = analogRead(SOIL_PIN);
164 float kelembapanTanah = map(soilValue, 4095, 0, 0, 100);
165
166 Serial.println("===========================");
167 Serial.println("Suhu: " + String(suhu) + "°C");
168 Serial.println("Kelembapan Udara: " + String(kelembapanUdara) + "%");
169 Serial.println("Kelembapan Tanah: " + String(kelembapanTanah) + "%");
170
171 // === BACA MODE DARI FIREBASE ===
172 if (Firebase.RTDB.getString(&fbdo, "mode")) {
173 String mode = fbdo.stringData();
174 modeOtomatis = (mode == "otomatis");
175 }
176
177 fetchThresholdFromFirebase();
178
179 unsigned long nowTs = getTimestamp();
180
181 // log 1 JAM SEKALI
182 if (nowTs - lastLogTime >= LOG_INTERVAL) {
183 lastLogTime = nowTs;
184
185 sendHourlyLog(nowTs, suhu, kelembapanUdara, kelembapanTanah);
186 saveLastLogTime(nowTs);
187
188 // hapus data 2 hari lalu (jaga 24 jam)
189 deleteOldDate();
190 }
191
192 // === KONTROL POMPA ===
193 if (modeOtomatis) {
194 if (kelembapanTanah < moistureThreshold) {
195 digitalWrite(RELAY_PIN, LOW); // pompa menyala
196 Firebase.RTDB.setString(&fbdo, "status/pompa", "ON");
197 Serial.println("Pompa ON (otomatis - tanah kering)");
198 } else {
199 digitalWrite(RELAY_PIN, HIGH); // pompa mati
200 Firebase.RTDB.setString(&fbdo, "status/pompa", "OFF");
201 Serial.println("Pompa OFF (otomatis - tanah lembap)");
202 }
203 } else {
204 // === MODE MANUAL ===
205 if (Firebase.RTDB.getString(&fbdo, "manual_control")) {
206 String control = fbdo.stringData();
207 if (control == "ON") {
208 digitalWrite(RELAY_PIN, HIGH);
209 Serial.println("Pompa ON (manual)");
210 } else {
211 digitalWrite(RELAY_PIN, LOW);
212 Serial.println("Pompa OFF (manual)");
213 }
214 }
215 }
216
217 // === KIRIM DATA SENSOR SETIAP 3 DETIK ===
218 if (millis() - sendDataPrevMillis > 3000) {
219 sendDataPrevMillis = millis();
220 Firebase.RTDB.setFloat(&fbdo, "sensor/suhu", suhu);
221 Firebase.RTDB.setFloat(&fbdo, "sensor/kelembapan_udara", kelembapanUdara);
222 Firebase.RTDB.setFloat(&fbdo, "sensor/kelembapan_tanah", kelembapanTanah);
223 Serial.println("Data sensor dikirim ke Firebase!");
224 }
225
226 delay(3000);
227}