commit 9c9a64d72ed3da22ea389040edf4711deb12b8d8 Author: kicap1992 Date: Tue Mar 14 17:27:55 2023 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..2c2b55a --- /dev/null +++ b/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp12e] +platform = espressif8266 +board = esp12e +framework = arduino +lib_deps = + arduino-libraries/NTPClient@^3.2.1 + arduino-libraries/ArduinoHttpClient@^0.4.0 + arduino-libraries/Arduino_JSON@^0.2.0 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c1743c9 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,300 @@ +#include +#include +#include +#include +#include +#include +#include + +const char *ssid = "KARAN"; +const char *password = "12345679"; + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP, "pool.ntp.org"); +char daysOfTheWeek[7][12] = {"Ahad", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"}; + +String jam, menit, detik, hari; + +// ini script Karan +char serverAddress[] = "20.20.20.25"; +int serverPort = 3001; + +WiFiClient wifi; +// HttpClient client = HttpClient(wifi, serverAddress, serverPort); +HttpClient client = HttpClient(wifi, serverAddress, serverPort); + +// Untuk Angin Gunakan pin D6 pada Arduino +//================================================ +volatile byte rpmcount; // count signals +volatile unsigned long last_micros; +unsigned long timeold; +unsigned long timemeasure = 25.00; // seconds +int timetoSleep = 1; // minutes +unsigned long sleepTime = 15; // minutes +unsigned long timeNow; +int GPIO_pulse = D6; // +float rpm, rps; // frequencies +float radius = 0.1; // meters - measure of the lenght of each the anemometer wing +float velocity_kmh; // km/h +float velocity_ms; // m/s +float omega = 0; // rad/s +float calibration_value = 2.0; +//================================================ + +// Untuk Curah Hujan Gunakan pin D5 pada Arduino +//================================================ +const int pin_interrupt = D5; // Arduino = D3 +long int jumlah_tip = 0; +long int temp_jumlah_tip = 0; +float curah_hujan = 0.00; +float curah_hujan_per_menit = 0.00; +float curah_hujan_per_jam = 0.00; +float curah_hujan_per_hari = 0.00; +float curah_hujan_hari_ini = 0.00; +float temp_curah_hujan_per_menit = 0.00; +float temp_curah_hujan_per_jam = 0.00; +float temp_curah_hujan_per_hari = 0.00; +float milimeter_per_tip = 0.70; +String cuaca = "Berawan"; +volatile boolean flag = false; +//================================================ + +void IRAM_ATTR hitung_curah_hujan() +{ + flag = true; +} + +void IRAM_ATTR rpm_anemometer() +{ + if (long(micros() - last_micros) >= 5000) + { // time to debounce measures + rpmcount++; + last_micros = micros(); + } +} + +void setup() +{ + Serial.begin(9600); + //====================== SETUP Curah Hujan ================================================ + pinMode(pin_interrupt, INPUT); + attachInterrupt(digitalPinToInterrupt(pin_interrupt), hitung_curah_hujan, FALLING); // Akan menghitung tip jika pin berlogika dari HIGH ke LOW + //====================== END SETUP Curah Hujan ================================================ + + //====================== SETUP Angin ================================================ + pinMode(GPIO_pulse, INPUT_PULLUP); + digitalWrite(GPIO_pulse, LOW); + + detachInterrupt(digitalPinToInterrupt(GPIO_pulse)); // force to initiate Interrupt on zero + attachInterrupt(digitalPinToInterrupt(GPIO_pulse), rpm_anemometer, RISING); // Initialize the intterrupt pin + rpmcount = 0; + rpm = 0; + timeold = 0; + timeNow = 0; + //====================== SETUP Angin ================================================ + + Serial.print("Connecting to "); + Serial.println(ssid); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) + { + delay(500); + Serial.print("."); + } + Serial.println("Jaringan Terhubung"); + + // Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); + // bacaWaktu(); + // printSerial_angin(); + // printSerial_curah_hujan(); +} + +String konversi_jam(String angka) // Fungsi untuk supaya jika angka satuan ditambah 0 di depannya, Misalkan jam 1 maka jadi 01 pada LCD +{ + if (angka.length() == 1) + { + angka = "0" + angka; + } + else + { + angka = angka; + } + return angka; +} + +void bacaWaktu() +{ + timeClient.begin(); + timeClient.setTimeOffset(28800); + timeClient.update(); + hari = String(daysOfTheWeek[timeClient.getDay()]); + jam = String(timeClient.getHours(), DEC); + menit = String(timeClient.getMinutes(), DEC); + detik = String(timeClient.getSeconds(), DEC); +} + +void printSerial_angin() +{ + Serial.print("RPS="); + Serial.println(rps); + Serial.print("RPM="); + Serial.println(rpm); + Serial.print("Kecepatan="); + Serial.print(velocity_ms); + Serial.print(" m/s, "); + Serial.print(velocity_kmh); + Serial.println(" Km/jam"); + String angin_kmh = String(velocity_kmh, 2); + // Firebase.setString(fbdo, "/angin_kmh",angin_kmh); + client.post("/api/from_esp32", "application/json", "{\"kecepatan_per_detik\":\"" + String(velocity_ms) + "\",\"kecepatan_per_jam\":\"" + String(velocity_kmh) + "\",\"rps\":\"" + String(rps) + "\",\"rpm\":\"" + String(rpm) + "\"}"); + String response = client.responseBody(); + JSONVar myObject = JSON.parse(response); + if (JSON.typeof(myObject) == "undefined") + { + Serial.println("Parsing input failed!"); + return; + } + else + { + Serial.println("Parsing input success!"); + Serial.println(myObject); + } +} + +void printSerial_curah_hujan() +{ + Serial.println("Waktu=" + konversi_jam(jam) + ":" + konversi_jam(menit)); + Serial.print("Cuaca="); + Serial.println(cuaca); // Print cuaca hari ini (Ini bukan ramalan cuaca tapi membaca cuaca yang sudah terjadi/ sedang terjadi hari ini) + Serial.print("Jumlah tip="); + Serial.print(jumlah_tip); + Serial.println(" kali "); + Serial.print("Curah hujan hari ini="); + Serial.print(curah_hujan_hari_ini, 1); + Serial.println(" mm "); + Serial.print("Curah hujan per menit="); + Serial.print(curah_hujan_per_menit, 1); + Serial.println(" mm "); + Serial.print("Curah hujan per jam="); + Serial.print(curah_hujan_per_jam, 1); + Serial.println(" mm "); + Serial.print("Curah hujan per hari="); + Serial.print(curah_hujan_per_hari, 1); + Serial.println(" mm "); + + String waktu = hari + ", " + konversi_jam(jam) + ":" + konversi_jam(menit); + // Firebase.setString(fbdo, "/waktu",waktu); + // Firebase.setFloat(fbdo, "/curah_hujan",curah_hujan_hari_ini); + client.post("/api/from_esp32/curah_hujan", "application/json", "{\"jumlah_tip\":\"" + String(jumlah_tip) + "\",\"curah_hujan_per_menit\":\"" + String(curah_hujan_per_menit) + "\",\"curah_hujan_per_jam\":\"" + String(curah_hujan_per_jam) + "\",\"curah_hujan_per_hari\":\"" + String(curah_hujan_per_hari) + "\"}"); + String response = client.responseBody(); + JSONVar myObject = JSON.parse(response); + if (JSON.typeof(myObject) == "undefined") + { + Serial.println("Parsing input failed!"); + return; + } + else + { + Serial.println("Parsing input success!"); + Serial.println(myObject); + } +} + +void checkWifi() +{ + if (WiFi.status() != WL_CONNECTED) + { + Serial.println("WiFi Disconnected"); + delay(1000); + ESP.restart(); + } +} + +void loop() +{ + // checkwifi + checkWifi(); + + + // Measure RPM + if ((millis() - timeold) >= timemeasure * 1000) + { + Serial.println(rpmcount); + detachInterrupt(digitalPinToInterrupt(GPIO_pulse)); // Disable interrupt when calculating + rps = float(rpmcount) / float(timemeasure); // rotations per second + rpm = 60 * rps; // rotations per minute + omega = 2 * PI * rps; // rad/s + velocity_ms = omega * radius * calibration_value; // m/s + velocity_kmh = velocity_ms * 3.6; // km/h + printSerial_angin(); // print serial 25 detik sekali + timeold = millis(); + rpmcount = 0; + attachInterrupt(digitalPinToInterrupt(GPIO_pulse), rpm_anemometer, RISING); // enable interrupt + } + + if (flag == true) + { + curah_hujan += milimeter_per_tip; // Akan bertambah nilainya saat tip penuh + jumlah_tip++; + delay(500); + flag = false; // reset flag + } + + bacaWaktu(); + curah_hujan_hari_ini = jumlah_tip * milimeter_per_tip; + temp_curah_hujan_per_menit = curah_hujan; + + // Probabilistik Curah Hujan https://www.bmkg.go.id/cuaca/probabilistik-curah-hujan.bmkg + if (curah_hujan_hari_ini <= 0.00 && curah_hujan_hari_ini <= 0.50) + { + cuaca = "Berawan"; + } + if (curah_hujan_hari_ini > 0.50 && curah_hujan_hari_ini <= 20.00) + { + cuaca = "Hujan Ringan"; + } + if (curah_hujan_hari_ini > 20.00 && curah_hujan_hari_ini <= 50.00) + { + cuaca = "Hujan Sedang"; + } + if (curah_hujan_hari_ini > 50.00 && curah_hujan_hari_ini <= 100.00) + { + cuaca = "Hujan Lebat"; + } + if (curah_hujan_hari_ini > 100.00 && curah_hujan_hari_ini <= 150.00) + { + cuaca = "Hujan Sangat Lebat"; + } + if (curah_hujan_hari_ini > 150.00) + { + cuaca = "Hujan ekstrem"; + } + if (detik.equals("0")) // Hanya print pada detik 0 + { + curah_hujan_per_menit = temp_curah_hujan_per_menit; // Curah hujan per menit dihitung ketika detik 0 + temp_curah_hujan_per_jam += curah_hujan_per_menit; // Curah hujan per jam dihitung dari penjumlahan curah hujan per menit namun disimpan dulu dalam variabel temp + if (menit.equals("0")) + { + curah_hujan_per_jam = temp_curah_hujan_per_jam; // Curah hujan per jam baru dihitung ketika menit 0 + temp_curah_hujan_per_hari += curah_hujan_per_jam; //// Curah hujan per hari dihitung dari penjumlahan curah hujan per jam namun disimpan dulu dalam variabel temp + temp_curah_hujan_per_jam = 0.00; // Reset temp curah hujan per jam + } + // if (menit.equals("0") && jam.equals("0")) + if (menit.equals("0")) + { + curah_hujan_per_hari = temp_curah_hujan_per_hari; // Curah hujan per jam baru dihitung ketika menit 0 dan jam 0 (Tengah malam) + temp_curah_hujan_per_hari = 0.00; // Reset temp curah hujan per hari + curah_hujan_hari_ini = 0.00; // Reset curah hujan hari ini + jumlah_tip = 0; // Jumlah tip di reset setiap 24 jam sekali (Tengah malam) + } + temp_curah_hujan_per_menit = 0.00; + curah_hujan = 0.00; + delay(1000); + } + if ((jumlah_tip != temp_jumlah_tip) || (detik.equals("0"))) // Print serial setiap 1 menit atau ketika jumlah_tip berubah + { + printSerial_curah_hujan(); + Serial.println(" "); + } + temp_jumlah_tip = jumlah_tip; +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html