Naposledy aktivní 1766034188

ridzimeko revidoval tento gist 1766034188. Přejít na revizi

1 file changed, 227 deletions

penyiraman-with-log.ino (smazal soubor)

@@ -1,227 +0,0 @@
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 -
22 - DHT dht(DHTPIN, DHTTYPE);
23 -
24 - FirebaseData fbdo;
25 - FirebaseAuth auth;
26 - FirebaseConfig config;
27 -
28 - unsigned long sendDataPrevMillis = 0;
29 - bool signupOK = false;
30 - bool modeOtomatis = true;
31 -
32 - int moistureThreshold = 30; // default kalau Firebase gagal
33 - unsigned long lastFetchThreshold = 0;
34 -
35 - const unsigned long LOG_INTERVAL =
36 - 60UL * 60UL * 1000UL; // 1 jam (ms)
37 -
38 - unsigned long lastLogTime = 0;
39 -
40 - void 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 -
49 - void loadLastLogTime() {
50 - if (Firebase.RTDB.getInt(&fbdo, "/monitoring/meta/lastLogTime")) {
51 - lastLogTime = fbdo.intData();
52 - Serial.println("LastLogTime loaded");
53 - }
54 - }
55 -
56 - void saveLastLogTime(unsigned long ts) {
57 - Firebase.RTDB.setInt(
58 - &fbdo,
59 - "/monitoring/meta/lastLogTime",
60 - ts
61 - );
62 - }
63 -
64 - unsigned long getTimestamp() {
65 - time_t now;
66 - time(&now);
67 - return (unsigned long)now * 1000;
68 - }
69 -
70 - String 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 -
79 - String 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 -
93 - void 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 -
114 - void 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 -
122 - void 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 -
157 - void 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 - }

ridzimeko revidoval tento gist 1766034170. Přejít na revizi

1 file changed, 2 insertions, 3 deletions

penyiraman-iot.ino

@@ -91,10 +91,9 @@ void loop() {
91 91 modeOtomatis = (mode == "auto");
92 92 }
93 93
94 - fetchThresholdFromFirebase();
95 -
96 94 // === KONTROL POMPA ===
97 95 if (modeOtomatis) {
96 + fetchThresholdFromFirebase();
98 97 if (kelembapanTanah < moistureThreshold) {
99 98 digitalWrite(RELAY_PIN, LOW); // pompa menyala
100 99 Firebase.RTDB.setString(&fbdo, "status/pompa", "ON");
@@ -127,5 +126,5 @@ void loop() {
127 126 Serial.println("Data sensor dikirim ke Firebase!");
128 127 }
129 128
130 - delay(3000);
129 + delay(1000);
131 130 }

ridzimeko revidoval tento gist 1766033242. Přejít na revizi

1 file changed, 9 insertions, 9 deletions

penyiraman-iot.ino

@@ -5,8 +5,8 @@
5 5 #include "addons/RTDBHelper.h"
6 6
7 7 // ====== KONFIGURASI WIFI ======
8 - #define WIFI_SSID "sandata"
9 - #define WIFI_PASSWORD "gnulibre567"
8 + #define WIFI_SSID "REDMI 15C"
9 + #define WIFI_PASSWORD "12312345"
10 10
11 11 // ====== KONFIGURASI FIREBASE ======
12 12 #define API_KEY "AIzaSyAO4ja4G-y20Qv20pe_kU7-vItW908nec4"
@@ -45,7 +45,7 @@ void setup() {
45 45 dht.begin();
46 46 pinMode(SOIL_PIN, INPUT);
47 47 pinMode(RELAY_PIN, OUTPUT);
48 - digitalWrite(RELAY_PIN, LOW);
48 + digitalWrite(RELAY_PIN, HIGH);
49 49
50 50 // ====== KONEKSI WIFI ======
51 51 WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
@@ -88,7 +88,7 @@ void loop() {
88 88 // === BACA MODE DARI FIREBASE ===
89 89 if (Firebase.RTDB.getString(&fbdo, "controls/pump/mode")) {
90 90 String mode = fbdo.stringData();
91 - modeOtomatis = (mode == "otomatis");
91 + modeOtomatis = (mode == "auto");
92 92 }
93 93
94 94 fetchThresholdFromFirebase();
@@ -97,11 +97,11 @@ void loop() {
97 97 if (modeOtomatis) {
98 98 if (kelembapanTanah < moistureThreshold) {
99 99 digitalWrite(RELAY_PIN, LOW); // pompa menyala
100 - Firebase.RTDB.setStringAsync(&fbdo, "status/pompa", "ON");
100 + Firebase.RTDB.setString(&fbdo, "status/pompa", "ON");
101 101 Serial.println("Pompa ON (otomatis - tanah kering)");
102 102 } else {
103 103 digitalWrite(RELAY_PIN, HIGH); // pompa mati
104 - Firebase.RTDB.setStringAsync(&fbdo, "status/pompa", "OFF");
104 + Firebase.RTDB.setString(&fbdo, "status/pompa", "OFF");
105 105 Serial.println("Pompa OFF (otomatis - tanah lembap)");
106 106 }
107 107 } else {
@@ -109,16 +109,16 @@ void loop() {
109 109 if (Firebase.RTDB.getString(&fbdo, "status/pompa")) {
110 110 String control = fbdo.stringData();
111 111 if (control == "ON") {
112 - digitalWrite(RELAY_PIN, HIGH);
112 + digitalWrite(RELAY_PIN, LOW);
113 113 Serial.println("Pompa ON (manual)");
114 114 } else {
115 - digitalWrite(RELAY_PIN, LOW);
115 + digitalWrite(RELAY_PIN, HIGH);
116 116 Serial.println("Pompa OFF (manual)");
117 117 }
118 118 }
119 119 }
120 120
121 - // === KIRIM DATA SENSOR SETIAP 3 DETIK ===
121 + // === KIRIM DATA SENSOR SETIAP 2 DETIK ===
122 122 if (millis() - sendDataPrevMillis > 3000) {
123 123 sendDataPrevMillis = millis();
124 124 Firebase.RTDB.setFloat(&fbdo, "sensor/suhu", suhu);

ridzimeko revidoval tento gist 1765989619. Přejít na revizi

1 file changed, 4 insertions, 4 deletions

penyiraman-iot.ino

@@ -5,8 +5,8 @@
5 5 #include "addons/RTDBHelper.h"
6 6
7 7 // ====== KONFIGURASI WIFI ======
8 - #define WIFI_SSID "DOUBLE A"
9 - #define WIFI_PASSWORD "nataneila"
8 + #define WIFI_SSID "sandata"
9 + #define WIFI_PASSWORD "gnulibre567"
10 10
11 11 // ====== KONFIGURASI FIREBASE ======
12 12 #define API_KEY "AIzaSyAO4ja4G-y20Qv20pe_kU7-vItW908nec4"
@@ -86,7 +86,7 @@ void loop() {
86 86 Serial.println("Kelembapan Tanah: " + String(kelembapanTanah) + "%");
87 87
88 88 // === BACA MODE DARI FIREBASE ===
89 - if (Firebase.RTDB.getString(&fbdo, "mode")) {
89 + if (Firebase.RTDB.getString(&fbdo, "controls/pump/mode")) {
90 90 String mode = fbdo.stringData();
91 91 modeOtomatis = (mode == "otomatis");
92 92 }
@@ -106,7 +106,7 @@ void loop() {
106 106 }
107 107 } else {
108 108 // === MODE MANUAL ===
109 - if (Firebase.RTDB.getString(&fbdo, "manual_control")) {
109 + if (Firebase.RTDB.getString(&fbdo, "status/pompa")) {
110 110 String control = fbdo.stringData();
111 111 if (control == "ON") {
112 112 digitalWrite(RELAY_PIN, HIGH);

ridzimeko revidoval tento gist 1765985109. Přejít na revizi

1 file changed, 227 insertions

penyiraman-with-log.ino(vytvořil soubor)

@@ -0,0 +1,227 @@
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 +
22 + DHT dht(DHTPIN, DHTTYPE);
23 +
24 + FirebaseData fbdo;
25 + FirebaseAuth auth;
26 + FirebaseConfig config;
27 +
28 + unsigned long sendDataPrevMillis = 0;
29 + bool signupOK = false;
30 + bool modeOtomatis = true;
31 +
32 + int moistureThreshold = 30; // default kalau Firebase gagal
33 + unsigned long lastFetchThreshold = 0;
34 +
35 + const unsigned long LOG_INTERVAL =
36 + 60UL * 60UL * 1000UL; // 1 jam (ms)
37 +
38 + unsigned long lastLogTime = 0;
39 +
40 + void 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 +
49 + void loadLastLogTime() {
50 + if (Firebase.RTDB.getInt(&fbdo, "/monitoring/meta/lastLogTime")) {
51 + lastLogTime = fbdo.intData();
52 + Serial.println("LastLogTime loaded");
53 + }
54 + }
55 +
56 + void saveLastLogTime(unsigned long ts) {
57 + Firebase.RTDB.setInt(
58 + &fbdo,
59 + "/monitoring/meta/lastLogTime",
60 + ts
61 + );
62 + }
63 +
64 + unsigned long getTimestamp() {
65 + time_t now;
66 + time(&now);
67 + return (unsigned long)now * 1000;
68 + }
69 +
70 + String 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 +
79 + String 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 +
93 + void 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 +
114 + void 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 +
122 + void 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 +
157 + void 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 + }

ridzimeko revidoval tento gist 1765604579. Přejít na revizi

1 file changed, 131 insertions

penyiraman-iot.ino(vytvořil soubor)

@@ -0,0 +1,131 @@
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 "DOUBLE A"
9 + #define WIFI_PASSWORD "nataneila"
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 +
21 + DHT dht(DHTPIN, DHTTYPE);
22 +
23 + FirebaseData fbdo;
24 + FirebaseAuth auth;
25 + FirebaseConfig config;
26 +
27 + unsigned long sendDataPrevMillis = 0;
28 + bool signupOK = false;
29 + bool modeOtomatis = true;
30 +
31 + int moistureThreshold = 30; // default kalau Firebase gagal
32 + unsigned long lastFetchThreshold = 0;
33 +
34 + void 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 +
43 + void 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 +
74 + void 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, "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, "manual_control")) {
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 + }
Novější Starší