Aplikasi#2. Parkir IoT

Aplikasi kedua ini juga seputar penggunaan Modul LED&KEY (yang murah meriah), yang digunakan bersama dengan NodeMCU (agar bisa terhubung dengan IoT Cloud) untuk membuat sistem parkir berbasis IoT. Mengapa Parkir memerlukan IoT? 

Saya menanyakan pertanyaan di atas kepada ChatGPT, wow, jawabannya sangat bagus, banyak informasi yang bisa diperoleh, serta yang menarik, ketika saya menanyakan pertanyaan yang sama tersebut beberapa kali, jawabannya bisa selalu berbeda kalimatnya (walau intinya sama), wah senang saya mendapat mainan baru. Baiklah, tulisan berikut ini saya kutip dari jawaban yang terakhir:

    Sistem parkir menggunakan IoT (Internet of Things) karena teknologi IoT dapat memungkinkan perangkat dan sensor untuk saling terhubung dan berkomunikasi melalui jaringan internet. Dalam hal ini, IoT dapat digunakan untuk memantau status parkir secara real-time dengan mengumpulkan dan mengirimkan data tentang ketersediaan tempat parkir dan memungkinkan pengguna untuk melihat informasi tersebut melalui aplikasi atau layanan online.
    Selain itu, IoT juga dapat memungkinkan sistem parkir untuk berfungsi secara otomatis, seperti membuka dan menutup gerbang parkir, memandu pengguna ke tempat parkir yang tersedia, dan mengenali nomor plat kendaraan untuk mengidentifikasi pengguna parkir yang sah. Hal ini dapat membantu meningkatkan efisiensi penggunaan ruang parkir, mengurangi waktu yang dihabiskan untuk mencari tempat parkir yang tersedia, dan meminimalkan kemacetan lalu lintas.
    Dalam hal keamanan, IoT juga dapat memungkinkan sistem parkir untuk dilengkapi dengan sensor dan kamera yang dapat mendeteksi dan merekam aktivitas yang mencurigakan di area parkir. Hal ini dapat membantu meningkatkan keamanan bagi pengguna parkir dan mencegah tindak kriminal seperti pencurian dan vandalisme.
    Secara keseluruhan, IoT dapat membantu meningkatkan efisiensi, kenyamanan, dan keamanan sistem parkir, sehingga menjadi pilihan yang populer bagi banyak pengelola parkir dan pengguna parkir.

Terlihat jawabannya sangat cerdas ya rekan-rekan. Terima kasih buat layanan ChatGPT yang sangat membantu 👍👍👍👍👍. Baiklah, kembali ke pembuatan aplikasi parkir IoT sederhana ini, berikut ini gambaran ide sekaligus batasan dari aplikasi ini.

1. Alat atau aplikasi yang akan dibuat ini, dibatasi hanya untuk memenuhi paragraf pertama dari jawaban ChatGPT di atas, yaitu hanya untuk memantau status parkir secara real-time dengan mengumpulkan dan mengirimkan data tentang ketersediaan tempat parkir dan memungkinkan pengguna untuk melihat informasi tersebut melalui aplikasi atau layanan online.

2. Diagram berikut ini memberikan gambaran ide dari parkir IoT yang akan dibuat:

Gambar 1. Ide Parkir IoT dengan Arduino IoT Cloud, NodeMCU, Modul LED&KEY & Google Sheet

3. Modul LED&KEY memiliki 3 jenis komponen, yaitu LED, 7-segmen dan tombol, yang masing-masing sebanyak 8 buah. Dari ketiga jenis komponen tersebut, ketiganya dapat dimanfaatkan untuk mensimulasikan hal-hal berikut ini:
  • Komponen LED digunakan untuk mensimulasikan buka tutup gerbang masuk kendaraan. Apabila LED menyala, maka gerbang masuk terbuka, kendaraan dari luar bisa masuk. Apabila LED padam, maka gerbang masuk tertutup, kendaraan dari luar tidak bisa masuk.
  • Komponen 7-segmen digunakan untuk menampilkan jumlah kendaraan. Karena angka 99 dirasa sudah cukup banyak, maka di aplikasi ini, kedelapan digit 7-segmen tersebut dibagi menjadi 4 kelompok, yang dinamai lantai 1 s/d lantai 4, dengan masing-masing lantai bisa menampung kendaraan hingga maksimum 99 buah. Jumlah ruang yang kosong untuk Lantai 1 ditampilkan di 2 digit 7-segmen yang paling kiri, sedangkan jumlah ruang yang kosong untuk lantai 4 ditampilkan di 2 digit 7-segmen yang paling kanan (lihat Gambar 1 di atas).
  • Komponen tombol digunakan untuk mensimulasikan kendaraan masuk dan kendaraan keluar. Ketika tombol + ditekan, menandakan bahwa ada kendaraan masuk. Ketika tombol - ditekan menandakan ada kendaraan keluar. Tombol + (masuk) dan tombol - (keluar) untuk lantai 1 berada di paling kiri, dan untuk lantai 4 berada di paling kanan. 
4. Hal yang menarik dari alat yang dibuat ini adalah sebagai berikut:
  1. Karena menggunakan Cloud, maka data jumlah kendaraan dan tempat parkir yang tersedia, tidak akan hilang ketika Modul LED&KEY dimatikan, karena datanya tersimpan di Cloud. 
  2. Data kendaraan masuk dan keluar dapat terpantau secara real-time dan online, sehingga ketersediaan tempat parkir dapat diketahui secara cepat dan mudah.
  3. Karena menggunakan Arduino IoT Cloud, maka pembuatan aplikasinya menjadi mudah dan cepat. Di samping itu, dengan banyaknya variabel dan widget yang tersedia, memungkinkan banyak sekali aplikasi yang dapat dikembangkan. Dalam aplikasi di sini, selain menggunakan widget Messenger dengan tipe data String, widget yang digunakan adalah widget Color, dengan variabel Color, yang termasuk dalam jenis variabel kompleks, yaitu sebuah variabel yang menggabungkan 3 buah nilai (hue, saturation, brightness).
  4. Penggunaan Google Sheet menguntungkan, karena selain bisa diakses secara online, juga dilengkapi dengan banyak sekali kemampuan olah data, sehingga berbagai variasi penyajian data bisa dilakukan dengan mudah. 
Kelemahan dari alat ini: apabila listrik mati atau internet mati, update (penambahan/pengurangan) data kendaraan tidak bisa dilakukan.

Lalu bagaimana cara membuatnya? Berikut ini langkah-langkah pembuatannya:
1. Mula-mula buka Arduino IoT Cloud, login dan buat sebuah Thing, beri nama Parkir.
2. Buat 5 buah variabel seperti tabel berikut:

Thing: Parkir

Variable

Tipe Variable

Permission

Update

lantai1

CloudColor (Light and color | Color)

Read & Write

On Change

lantai2

CloudColor (Light and color | Color)

Read & Write

On Change

lantai3

CloudColor (Light and color | Color)

Read & Write

On Change

lantai4

CloudColor (Light and color | Color)

Read & Write

On Change

out1

String (Basic | Character String)

Read & Write

On Change


Gambar 2. Penambahan 5 buah variabel: 4 variabel Color dan 1 variabel String

3. Setelah kelima variabel tersebut selesai ditambahkan, berikutnya tekan tombol Select Device (di Associated Device). Di jendela yang muncul, pilih Set Up New Device, pilih Set up a 3rd Party device, pilih ESP8266 dan pilih model: NodeMCU 1.0 (ESP-12E Module). Jangan lupa untuk menyimpan kode Device ID dan Secret Key (gunakan download the pdf). Tidak perlu mengisi Network di kedua Thing, karena Sketch nantinya akan di-download dari Web Editor dan kemudian di-upload menggunakan software Arduino IDE. 

4. Berikutnya, klik pada Tab Sketch, tekan tombol Open Full Editor, untuk membuka Web Editor. Di halaman Web Editor, download Sketch Parkir. Setelah Sketch tersebut terdownload, ekstrak file. Di Sketch Parkir, klik 2 kali pada file program ino. Setelah software Arduino IDE terbuka, di Tab program ino, hapus seluruh isinya, dan ganti dengan program berikut ini:  
  1. #include "arduino_secrets.h"
  2. #include "thingProperties.h"
  3. #include <TM1638plus.h>
  4. uint8_t tombol = 0;
  5. uint8_t maxlt1 = 0;  //kapasitas maks lantai1
  6. uint8_t maxlt2 = 0;  //kapasitas maks lantai2
  7. uint8_t maxlt3 = 0;  //kapasitas maks lantai3
  8. uint8_t maxlt4 = 0;  //kapasitas maks lantai4
  9. uint8_t trslt1 = 0;  //jumlah terisi di lantai 1
  10. uint8_t trslt2 = 0;  //jumlah terisi di lantai 2
  11. uint8_t trslt3 = 0;  //jumlah terisi di lantai 3
  12. uint8_t trslt4 = 0;  //jumlah terisi di lantai 4
  13. uint8_t ksglt1 = 0;  //jumlah kosong di lantai 1
  14. uint8_t ksglt2 = 0;  //jumlah kosong di lantai 2
  15. uint8_t ksglt3 = 0;  //jumlah kosong di lantai 3
  16. uint8_t ksglt4 = 0;  //jumlah kosong di lantai 4
  17. TM1638plus tm(D5, D6, D7, false);
  18. void setup() {
  19.   Serial.begin(9600);
  20.   delay(1500);
  21.   initProperties();
  22.   ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  23.   setDebugMessageLevel(2);
  24.   ArduinoCloud.printDebugInfo();
  25.   tm.displayBegin();
  26.   delay(1000);
  27.   tm.reset();
  28. }
  29. void loop() {
  30.   ArduinoCloud.update();
  31.   maxlt1 = lantai1.getValue().hue;
  32.   trslt1 = lantai1.getValue().sat;
  33.   ksglt1 = lantai1.getValue().bri;
  34.   maxlt2 = lantai2.getValue().hue;
  35.   trslt2 = lantai2.getValue().sat;
  36.   ksglt2 = lantai2.getValue().bri;
  37.   maxlt3 = lantai3.getValue().hue;
  38.   trslt3 = lantai3.getValue().sat;
  39.   ksglt3 = lantai3.getValue().bri;
  40.   maxlt4 = lantai4.getValue().hue;
  41.   trslt4 = lantai4.getValue().sat;
  42.   ksglt4 = lantai4.getValue().bri;
  43.   tombol = tm.readButtons();
  44.   switch (tombol) {
  45.     case 1:
  46.       if (ksglt1) {
  47.         trslt1++;
  48.         if (trslt1 < 10) out1 = "ta0" + String(trslt1);
  49.         else out1 = "ta" + String(trslt1);
  50.       }
  51.       break;
  52.     case 2:
  53.       if (ksglt1 < maxlt1) {
  54.         trslt1--;
  55.         if (trslt1 < 10) out1 = "ta0" + String(trslt1);
  56.         else out1 = "ta" + String(trslt1);
  57.       }
  58.       break;
  59.     case 4:
  60.       if (ksglt2) {
  61.         trslt2++;
  62.         if (trslt2 < 10) out1 = "tb0" + String(trslt2);
  63.         else out1 = "tb" + String(trslt2);
  64.       }
  65.       break;
  66.     case 8:
  67.       if (ksglt2 < maxlt2) {
  68.         trslt2--;
  69.         if (trslt2 < 10) out1 = "tb0" + String(trslt2);
  70.         else out1 = "tb" + String(trslt2);
  71.       }
  72.       break;
  73.     case 16:
  74.       if (ksglt3) {
  75.         trslt3++;
  76.         if (trslt3 < 10) out1 = "tc0" + String(trslt3);
  77.         else out1 = "tc" + String(trslt3);
  78.       }
  79.       break;
  80.     case 32:
  81.       if (ksglt3 < maxlt3) {
  82.         trslt3--;
  83.         if (trslt3 < 10) out1 = "tc0" + String(trslt3);
  84.         else out1 = "tc" + String(trslt3);
  85.       }
  86.       break;
  87.     case 64:
  88.       if (ksglt4) {
  89.         trslt4++;
  90.         if (trslt4 < 10) out1 = "td0" + String(trslt4);
  91.         else out1 = "td" + String(trslt4);
  92.       }
  93.       break;
  94.     case 128:
  95.       if (ksglt4 < maxlt4) {
  96.         trslt4--;
  97.         if (trslt4 < 10) out1 = "td0" + String(trslt4);
  98.         else out1 = "td" + String(trslt4);
  99.       }
  100.       break;
  101.   }
  102.   tm.displayASCII(0, char(ksglt1 / 10 + 48));
  103.   tm.displayASCIIwDot(1, char(ksglt1 % 10 + 48));
  104.   tm.displayASCII(2, char(ksglt2 / 10 + 48));
  105.   tm.displayASCIIwDot(3, char(ksglt2 % 10 + 48));
  106.   tm.displayASCII(4, char(ksglt3 / 10 + 48));
  107.   tm.displayASCIIwDot(5, char(ksglt3 % 10 + 48));
  108.   tm.displayASCII(6, char(ksglt4 / 10 + 48));
  109.   tm.displayASCIIwDot(7, char(ksglt4 % 10 + 48));
  110.   if (ksglt1) {
  111.     tm.setLED(0, 1);
  112.     tm.setLED(1, 1);
  113.   } else {
  114.     tm.setLED(0, 0);
  115.     tm.setLED(1, 0);
  116.   }
  117.   if (ksglt2) {
  118.     tm.setLED(2, 1);
  119.     tm.setLED(3, 1);
  120.   } else {
  121.     tm.setLED(2, 0);
  122.     tm.setLED(3, 0);
  123.   }
  124.   if (ksglt3) {
  125.     tm.setLED(4, 1);
  126.     tm.setLED(5, 1);
  127.   } else {
  128.     tm.setLED(4, 0);
  129.     tm.setLED(5, 0);
  130.   }
  131.   if (ksglt4) {
  132.     tm.setLED(6, 1);
  133.     tm.setLED(7, 1);
  134.   } else {
  135.     tm.setLED(6, 0);
  136.     tm.setLED(7, 0);
  137.   }
  138.   if (out1.length() == 4) {
  139.     String out2 = out1.substring(2);
  140.     if (out1.startsWith("m")) {
  141.       if (out1.startsWith("a", 1) || out1.startsWith("A", 1)) maxlt1 = out2.toInt();
  142.       if (out1.startsWith("b", 1) || out1.startsWith("B", 1)) maxlt2 = out2.toInt();
  143.       if (out1.startsWith("c", 1) || out1.startsWith("C", 1)) maxlt3 = out2.toInt();
  144.       if (out1.startsWith("d", 1) || out1.startsWith("D", 1)) maxlt4 = out2.toInt();
  145.     }
  146.     if (out1.startsWith("t")) {
  147.       if (out1.startsWith("a", 1) || out1.startsWith("A", 1)) trslt1 = out2.toInt();
  148.       if (out1.startsWith("b", 1) || out1.startsWith("B", 1)) trslt2 = out2.toInt();
  149.       if (out1.startsWith("c", 1) || out1.startsWith("C", 1)) trslt3 = out2.toInt();
  150.       if (out1.startsWith("d", 1) || out1.startsWith("D", 1)) trslt4 = out2.toInt();
  151.     }
  152.   }
  153.   ksglt1 = maxlt1 - trslt1;
  154.   ksglt2 = maxlt2 - trslt2;
  155.   ksglt3 = maxlt3 - trslt3;
  156.   ksglt4 = maxlt4 - trslt4;
  157.   lantai1 = Color(maxlt1, trslt1, ksglt1);
  158.   lantai2 = Color(maxlt2, trslt2, ksglt2);
  159.   lantai3 = Color(maxlt3, trslt3, ksglt3);
  160.   lantai4 = Color(maxlt4, trslt4, ksglt4);
  161. }
  162. void onOut1Change() {
  163. }
  164. void onLantai1Change() {
  165. }
  166. void onLantai2Change() {
  167. }
  168. void onLantai3Change() {
  169. }
  170. void onLantai4Change() {
  171. }
5. Berikutnya, sebelum meng-upload program tersebut ke NodeMCU, isi dulu nama Wi-Fi, password Wi-Fi dan Kode Secret Key di Tab program arduino_secrets.h, dan kode Device ID diisikan di Tab program thingProperties.h di Device_Login_Name (ini harusnya sudah terisi). Sketch di atas memerlukan 5 library berikut ini. Pastikan 5 library ini telah di-instal di software Arduino IDE, yaitu secara berturut-turut:
  • ArduinoIoTCloud (versi 1.8.0)
  • Arduino_ConnectionHandler (versi 0.7.1)
  • Arduino_DebugUtils-master
  • ArduinoMqttClient-master
  • TM1638plus 
6. Rekan-rekan dapat mengunduh kelima file library di atas pada file lampiran yang disertakan di langkah no. 19. Setelah kelima library di atas terinstal, berikutnya pilih Board dan Port. Gunakan Board NodeMCU 1.0, dan Port sesuai dengan yang digunakan. Upload program, dan tunggu hingga selesai. Setelah selesai, buka Serial Monitor. Apabila muncul tulisan, Connected to Arduino IoT Cloud, berarti Device NodeMCU sudah online, alias sudah terhubung dengan variabel di Cloud. 

7. Berikutnya, buka Dashboard, klik tombol Add, pilih Things, pilih Parkir. Kemudian pilih kelima variabel, klik Create Widgets, maka akan muncul 4 buah widget Color dan sebuah widget Messenger.

Gambar 3. Di Dashboard, klik Add, pilih Things, pilih Parkir, klik Create Widgets

8. Berikutnya, klik Tool Arrange widgets. Kemudian atur ukuran dan posisi kelima widget hingga seperti gambar berikut ini.

Gambar 4. Muncul 5 buah widget di Dashboard, atur posisi dan ukuran kelima widget tersebut

9. Berikutnya hubungkan Modul LED&KEY ke NodeMCU seperti gambar berikut. Hubungkan kaki VCC, GND, STB, CLK dan DIO Modul LED&KEY secara berturut-turut ke kaki 3V, GND, D5, D6 dan D7 NodeMCU.

Gambar 5. D5, D6, D7 NodeMCU terhubung ke STB, CLK, DIO modul LED&KEY (TM1638)

10. Beri suplai ke NodeMCU. Tunggu hingga tampilan 7-segmen menampilkan angka yang sama dengan nilai Brightness dari keempat widget Color. 

Catatan: variabel dan widget Color digunakan di sini, karena variabel dan widget Color ini dapat menampung 3 buah data, yaitu Hue, Saturation dan Brightness. Untuk aplikasi ini, data Hue digunakan untuk menampung data kapasitas maksimum kendaraan pada tempat parkir, data Saturation digunakan untuk menampung data tempat parkir yang telah terisi, sedangkan data Brightness digunakan untuk menampung data tempat parkir yang masih kosong. Karena menggunakan data Brightness, maka ketika tempat parkir masih banyak yang kosong, yang berarti nilai Brightness besar, warna yang dihasilkan adalah warna cerah (mendekati putih), sebaliknya ketika tempat parkir tinggal sedikit, berarti nilai Brightness kecil, warna yang dihasilkan adalah warna gelap (mendekati hitam). Karena tempat parkir yang kosong ini dihitung dari kapasitas maksimum parkir dikurangi dengan tempat parkir yang terisi, maka data kapasitas maksimum parkir dan tempat parkir yang terisi harus dimasukkan dulu (melalui widget Messenger), barulah data tempat parkir yang kosong diperoleh. 

Berikut ini kode input untuk memasukkan data kapasitas maksimum parkir melalui widget Messenger:
  • Ketik maxx, dimana xx adalah angka -> widget Color Lantai1 untuk nilai Hue berisi angka XX. 
  • Ketik mbxx, dimana xx adalah angka -> widget Color Lantai2 untuk nilai Hue berisi angka XX. 
  • Ketik mcxx, dimana xx adalah angka -> widget Color Lantai3 untuk nilai Hue berisi angka XX. 
  • Ketik mdxx, dimana xx adalah angka -> widget Color Lantai4 untuk nilai Hue berisi angka XX.
Berikut ini kode input untuk memasukkan data tempat parkir yang terisi melalui widget Messenger:
  • Ketik taxx, dimana xx adalah angka -> widget Color Lantai1 untuk Saturation berisi angka xx.
  • Ketik tbxx, dimana xx adalah angka -> widget Color Lantai2 untuk Saturation berisi angka xx.
  • Ketik tcxx, dimana xx adalah angka -> widget Color Lantai3 untuk Saturation berisi angka xx.
  • Ketik tdxx, dimana xx adalah angka -> widget Color Lantai4 untuk Saturation berisi angka xx.
Catatan: kode input untuk memasukkan data kapasitas maksimum diberi awalan huruf m, yang merupakan singkatan "maksimum", diikuti huruf a, b, c atau d, yang mengacu pada Lantai1 (huruf a), Lantai2 (huruf b), Lantai3 (huruf c) dan Lantai4 (huruf d), kemudian diikuti angka 2 digit yang menunjukkan besaran nilainya. Sedangkan kode input untuk memasukkan data tempat parkir yang terisi, diberi awalan huruf t, yang merupakan singkatan "terisi", yang diikuti huruf a, b, c atau d, yang mengacu pada Lantai1 (huruf a), Lantai2 (huruf b), Lantai3 (huruf c) dan Lantai4 (huruf d), kemudian diikuti angka 2 digit yang menunjukkan besaran nilainya.

11. Untuk data tempat parkir yang terisi, selain dimasukkan dari widget Messengger, juga dimasukkan melalui penekanan tombol + atau tombol - di Modul LED&KEY. Berikut ini penjelasannya:
  • Ketika tombol + yang paling kiri di Modul LED&KEY ditekan, membuat kode input taxx (kode untuk memasukkan data tempat parkir yang terisi di Lantai 1) dikirim ke widget Messenger, di mana nilai xx tersebut akan bertambah 1 angka setiap kali tombol + tersebut ditekan. 
  • Ketika tombol - di samping kanannya ditekan, membuat kode input taxx dikirim ke widget Messenger, di mana nilai xx akan berkurang 1 angka setiap kali tombol - tersebut ditekan.  
  • Ketika tombol - yang paling kanan di Modul LED&KEY ditekan, maka akan mengirim kode input tdxx (kode untuk memasukkan data tempat parkir yang terisi di Lantai 4) ke widget Messenger, di mana nilai xx akan berkurang 1 angka setiap kali tombol - tersebut ditekan. 
  • Ketika tombol + di samping kirinya ditekan, maka akan mengirim kode input tdxx ke widget Messenger, di mana nilai xx akan bertambah 1 angka setiap kali tombol + tersebut ditekan. 
12. Setelah data kapasitas maksimum tempat parkir di setiap Lantai diinputkan ke widget Messenger, dengan cara mengetikkan maxx, mbxx, mcxx dan mdxx secara berturut-turut, dimana xx diganti dengan nilai angka kapasitas maksimum, maka tampilan kedelapan 7-segmen di Modul LED&KEY akan bisa menampilkan nilai tempat parkir yang masih kosong di setiap Lantai. Untuk awalan, maka belum ada kendaraan yang masuk, maka nilai tempat parkir yang masih kosong ini akan sama dengan nilai kapasitas maksimum tempat parkir. Kemudian ketika tombol + di setiap Lantai di Modul LED&KEY ditekan, maka terlihat nilai yang ditampilkan 7-segmen akan berkurang 1 nilainya setiap kali penekanan tombol + berikutnya. Ketika tombol - ditekan, nilai di 7-segmen akan bertambah, karena ketika tombol - ditekan, berarti ada kendaraan yang keluar parkir, sehingga jumlah tempat parkir yang kosong akan bertambah. Agar lebih jelas, perhatikan gambar berikut ini:

Gambar 6. Kondisi mula-mula, semua nilai di setiap Lantai bernilai 0

Gambar 7. Kapasitas maksimum di setiap Lantai dimasukkan melalui widget Messenger dengan kode input ma90, mb90, mc90, md90, yang berarti kapasitas maksimum di setiap Lantai adalah 90. Karena belum ada kendaraan yang masuk, maka tempat parkir yang kosong sama dengan kapasitas maksimumnya, terlihat kedelapan 7-segmen di Modul LED&KEY menampilkan tempat parkir yang kosong di setiap Lantai

Gambar 8. Ketika tombol + di Lantai1 ditekan, maka tempat parkir yang kosong di Lantai1 mulai berkurang. Setelah 7 kali penekanan, maka tempat parkir yang kosong di Lantai1 bernilai 83, seperti ditampilkan pada 7-segmen. Setiap kali penekanan tombol+ di Lantai1 dilakukan, akan ada kode input taxx yang dikirimkan ke widget Messenger, di mana nilai xx akan dimulai dari 00, dan akan bertambah 1 angka setiap kali penekanan berikutnya.

Gambar 9. Ketika tombol + di Lantai2 ditekan, maka tempat parkir yang kosong di Lantai2 mulai berkurang. Setelah 27 kali penekanan, maka tempat parkir yang kosong di Lantai2 bernilai 63, seperti ditampilkan pada 7-segmen. Setiap kali penekanan tombol+ di Lantai2 dilakukan, akan ada kode input tbxx yang dikirimkan ke widget Messenger, di mana nilai xx akan dimulai dari 00, dan akan bertambah 1 angka setiap kali penekanan berikutnya.

Gambar 10. Ketika kode input tc88 diketikkan di kotak input widget Messenger, maka tempat parkir yang kosong di Lantai3 menjadi 2, seperti ditampilkan pada 7-segmen. Mengapa 2? Karena kode input tc88 ini berarti ada 88 kendaraan yang sudah masuk mengisi tempat parkir. Dengan kapasitas tempat parkir 90, maka yang kosong hanya tinggal 2. 

Gambar 11. Ketika kode input td88 diketikkan di kotak input widget Messenger, kemudian dilanjutkan dengan penekanan tombol + hingga tempat kosong di Lantai 4 menjadi 0, tampak terlihat 2 LED di atas 7-segmen terlihat padam. Padamnya LED ini mensimulasikan bahwa gerbang masuk ke parkir di Lantai4 telah ditutup, karena tempat parkir sudah penuh. 

Gambar 12. Begitu pula ketika tombol + di Lantai3 ditekan beberapa kali hingga tempat kosong menjadi 0, seperti terlihat pada tampilan 7-segmen, maka LED di atasnya menjadi padam, yang menandakan bahwa gerbang masuk ke parkir di Lantai3 telah ditutup.

13. Matikan NodeMCU dengan memutus suplai tegangan. Kemudian hidupkan lagi NodeMCU. Perhatikan bahwa angka pada kedelapan 7-segmen akan menampilkan kembali angka yang sama dengan nilai Brightness pada keempat widget Color. Dengan kondisi seperti ini, kita tidak perlu kuatir data hilang karena listrik mati, karena datanya tersimpan di Cloud.

14. Agar setiap update, baik penambahan maupun pengurangan tempat parkir yang kosong ini dapat terpantau secara real time, tidak hanya melalui tampilan 7-segmen dan Dashboard, tetapi juga bisa diakses oleh orang lain, maka kita tambahkan Webhook Google Sheet di halaman Things. Dengan Webhook ini, data di Dashboard akan dikirimkan ke Google Sheet, yang nantinya bisa diolah untuk menampilkan data kapasitas maksimum kendaraan, jumlah tempat parkir yang telah terisi dan jumlah tempat parkir yang masih kosong di setiap Lantai. 

15. Untuk pembuatan link Webhook ini, silahkan teman-teman bisa mengikuti langkah-langkah di link ini: https://bermainarduinoiotcloud.blogspot.com/p/5-kontrol-di-mana-mana.html di topik "Memantau Data Arduino IoT Cloud dengan Webhook & Google Sheet". Gambar-gambar berikut ini menunjukkan langkah-langkah penambahan Webhook Google Sheet ke Arduino IoT Cloud ini.

Gambar 13. Setelah link Webhook diperoleh, klik tombol Set Webhook di halaman Things hingga muncul jendela, lalu tempelkan link Webhook di kotak yang disediakan

Gambar 14. Tekan tombol Set Webhook di bawah kotak link, maka link Webhook menjadi aktif

Gambar 15. Tutup jendela, tampak di bagian bawah, link Webhook dengan status aktif

16. Setelah link Webhook aktif, perhatikan tampilan data di Google Sheet. Agar data tidak terlalu banyak, hapus semua kolom data, kecuali kolom dengan header: "values_0_name", "values_0_value" dan "values_0_updated_at", yang berisi data yang diperlukan. Karena data yang diterima di kolom "values_0_value" belum menampilkan data yang mudah dipahami (berisi data dengan awalan huruf ma.., mb.., mc.., md.., ta.., tb.., tc.., td..) di mana masih sulit mengetahui berapa jumlah tempat parkir yang masih kosong, maka tambahkan sebuah formula seperti tabel berikut:

Nilai yang ingin diketahui

Formula di Google Sheet

Kapasitas maksimum di Lantai 1

RIGHT(index(B1:B,arrayformula(max(row(B1:B)* (--(left(B1:B,2)="ma"))))),2)

Kapasitas maksimum di Lantai 2

RIGHT(index(B1:B,arrayformula(max(row(B1:B)*(--(left(B1:B,2)="mb"))))),2)

Kapasitas maksimum di Lantai 3

RIGHT(index(B1:B,arrayformula(max(row(B1:B)*(--(left(B1:B,2)="mc"))))),2)

Kapasitas maksimum di Lantai 4

RIGHT(index(B1:B,arrayformula(max(row(B1:B)*(--(left(B1:B,2)="md"))))),2)

Tempat parkir yang terisi di Lantai 1

RIGHT(index(B1:B,arrayformula(max(row(B1:B)*(--(left(B1:B,2)="ta"))))),2)

Tempat parkir yang terisi di Lantai 2

RIGHT(index(B1:B,arrayformula(max(row(B1:B)*(--(left(B1:B,2)="tb"))))),2)

Tempat parkir yang terisi di Lantai 3

RIGHT(index(B1:B,arrayformula(max(row(B1:B)*(--(left(B1:B,2)="tc"))))),2)

Tempat parkir yang terisi di Lantai 4

RIGHT(index(B1:B,arrayformula(max(row(B1:B)*(--(left(B1:B,2)="td"))))),2)

Tempat parkir yang kosong di Lantai 1

= nilai maksimum – nilai terisi

Tempat parkir yang kosong di Lantai 2

= nilai maksimum – nilai terisi 

Tempat parkir yang kosong di Lantai 3

= nilai maksimum – nilai terisi 

Tempat parkir yang kosong di Lantai 4

= nilai maksimum – nilai terisi 


17. Agar lebih jelas, berikut ini hasil penerapan formula di atas di Google Sheet.

Gambar 16. Tampilan 7-segmen nilainya sama dengan nilai Kosong di Google Sheet. Ketika nilai Kosong besar, widget Color menampilkan warna cerah mendekati putih.

Gambar 17. Tampilan 7-segmen nilainya sama dengan nilai Kosong di Google Sheet. Ketika nilai Kosong kecil, widget Color menampilkan warna gelap mendekati hitam.

Gambar 18. Ketika tombol + ditekan berkali-kali hingga nilai Kosong menjadi 0, tampak LED menjadi padam, mensimulasikan bahwa gerbang masuk parkir ditutup karena tempat parkir telah penuh 

Gambar 19. Ketika tombol + ditekan berkali-kali hingga nilai Kosong menjadi 0, tampak LED menjadi padam, mensimulasikan bahwa gerbang masuk parkir ditutup karena tempat parkir telah penuh 

18. Agar lebih jelas mengenai pembuatan aplikasi Parkir IoT ini, silahkan melihat video berikut ini:

Video pembuatan parkir IoT dengan NodeMCU, Modul LED&KEY, Arduino IoT Cloud & Google Sheet

19. Sampai di sini pembuatan aplikasi Parkir IoT. Untuk file program NodeMCU dan Library yang digunakan di bagian ini, silahkan bisa diunduh di link ini: Program NodeMCU dan Library

No comments:

Post a Comment