Anda di halaman 1dari 18

[Tutorial Lengkap] Kontrol Lampu via Internet of

Things dengan Antarmuka Web


setelah mendapatkan akun cloud MQTTBroker, dilanjutkan dengan
memprogram NodeMCU agar dapat terhubung dengan Cloud
MQTTBroker. Kode program berisi pembacaan sensor, dan kontrol
lampu. Pada sesi ini perserta dapat melakukan kontrol dan
monitorinng perangkat IoTnya melalui Internet.

Setelah menyelesaikan prosedur sign up pada CloudMQTT, periksa


informasi instance kita pada halaman instance information, Informasi
kredensial penting yang harus kita catat untuk dapat digunakan pada
NodeMCU adalah server, user, password, dan port.
cloudmqtt_instance_information.png

Disisi NodeMCU, kita akan menggunakan MQTT client yang


mendukung ESP8266 (chip inti dari NodeMCU), yang dinamakan
PubSubClient. Pustakanya dapat diinstall melalui Arduino IDE library
atau dengan menyalin file penyerta ke folder
Documents/Arduino/Libraries.

Pertama-tama, kita memulai dengan menambahkan libraries yang


diperlukan untuk semua fungsionalitas. Kita memerlukan
library ESP8266WiFi, agar dapat menghubungkan NodeMCU ke
jaringan WiFi, dan menggunakan library PubSubClient agar dapat
menghubungkan NodeMCU ke MQTT broker dan publish/subscribe
pesan pada topik terkait.
?

1 #include <ESP8266WiFi.h>

2 #include <PubSubClient.h>
Kemudian, kita perlu mendeklarasikan beberapa variabel global untuk
koneksi kita. Tentunya, kita, memerlukan kredensial untuk mengakses
WiFi, untuk menghubungkan diri ke jaringan WiFi. Berikut adalah
potongan kode yang digunakan untuk menyetel kredensial untuk
menghubung ke WiFi:

1 const char* ssid = "YourNetworkName";

2 const char* password =  "YourNetworkPassword";

Kita juga memerlukan informasi dan kredensial dari server


CloudMQTT. Sebagai mana dipaparkan pada sesi sebelumnya kita
perlu mengetahui alamat server, port, username dan password.
Sesuaikan nilai berikut dengan konfigurasi masing-masing:

1 const char* mqttServer = "m11.cloudmqtt.com";

2 const int mqttPort = 12948;

3 const char* mqttUser = "YourMqttUser";

4 const char* mqttPassword = "YourMqttUserPassword";

Setelah itu, kita perlu mendeklarasikan objek dari class WiFiClient,


yang memungkinkan kita untuk membuat koneksi ke IP dan port
spesifik. Kita juga perlu mendeklarasikan sebuah objek dari class
PubSubClient, yang mana menerima masukan dari konstruktor yang
sebelumnya didefinisikan oleh WiFiClient.

Konstruktor dari class ini dapat menerima sejumlah argumen lainnya,


sebagai mana dapat dilihat di halaman dokumentasinya
(http://pubsubclient.knolleary.net/api.html#setserver).
?

1 WiFiClient espClient;

2 PubSubClient client(espClient);

Sekarang, lanjut dari fungsi setup, kita membuka koneksi serial,


sehingga kita dapat melihat output dari hasil program kita. Kita juga
menghubungkan alatnya ke jaringan WiFi.

?
1 Serial.begin(115200);
2 WiFi.begin(ssid, password);
3 while (WiFi.status() != WL_CONNECTED) {

4   delay(500);

5   Serial.print("Connecting to WiFi..");

6 }

7 Serial.println("Connected to the WiFi network");

Selanjutnya, kita perlu menspesifikasikan alamat dan nomer port dari


MQTT server. Untuk itu, kita memanggil metode setServer dari objek
PubSubClient, argumen pertamanya adalah alamat dan yang kedua
adalah nomer port. Variabel yang berisi nilainya telah kita definisikan
sebelumnya, dalam bentuk string konstan.

1 client.setServer(mqttServer, mqttPort);

Kemudian, kita menggunakan metode setCallback pada objek yang


sama untuk fungsi penanganan yang dieksekusi ketika pesan MQTT
diterima. Kita akan menganalisis lebih dalam fungsi ini nanti.

1 client.setCallback(callback);

Sekarang, kita akan menghubungkan alatnya ke MQTT server, masi


tetap di fungsi setup. Sebagaimana yang kita lakukan pada bagian
menghubungkan ke jaringan WiFi, kita menghubungkan ke server
dalam perulangan loop hingga sukses terhubung.

Jadi, kita menggunakan perulangan while (while loop) berdasarkan


output dari metode connected pada objek PubSubClient, yang mana
akan mengembalikan nilai true jika koneksinya terbangun dengan
baik atau false jika tidak.
Untuk melakukan koneksi yang sebenarnya, kita memanggil
methode connect, yang menerima masukan berupa id pengenal unik
dari klien kita, yang mana akan kita namai "ESP8266Client", dan data
autentikasi berupa nama pengguna dan sandi, yang telah kita
definisikan sebelumnya. Ini akan mengembalikan nilai trua jika
koneksinya berhasil dan false jika gagal.
Wanti-wanti jika gagal, kita bisa memanggil metode state pada objek
PubSubClient, yang mana aka mengembalikan kode yang berisi
informasi mengenai mengapa koneksinya gagal. Berikut adalah kode
program untuk perulangan koneksinya:
?

1 while (!client.connected()) {
2     Serial.println("Connecting to MQTT...");
3     if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
4       Serial.println("connected");

5     } else {

6       Serial.print("failed with state ");

7       Serial.println(client.state());

8       delay(2000);

9     }

}
10

Untuk menyelesaikan fungsi setupnya, kita akan mempublish pesan


pada suatu topik. Untuk melakukan itu, kita memanggil
metode publish, yang menerima argumen input berupa topik dan
pesan. Pada kasus ini, kita akan mempublish sebuah pesan yang
mengatakan "Hello from ESP9266" pada topik "esp/test".
?

1 client.publish("esp/test", "Hello from ESP8266");

Kemudian, kita akan mensubscribe ke topik yang sama, sehingga kita


bisa menerima pesan dari publisher lainnya. Untuk melakukan itu,
kita memanggil metode subscribe, memberikan masukan berupa
argumen dengan nama topik yang sama.
?

1 client.subscribe("esp/test");

Periksa fungsi setup berikut yang telah ditulis secara lengkap:

1 void setup() {

2   Serial.begin(115200);

3   WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {


4
5     delay(500);

6     Serial.println("Connecting to WiFi..");

7   }

8   Serial.println("Connected to the WiFi network");

  client.setServer(mqttServer, mqttPort);
9
  client.setCallback(callback);
10
  while (!client.connected()) {
11
    Serial.println("Connecting to MQTT...");
12
    if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
13
      Serial.println("connected");
14
    } else {
15
      Serial.print("failed with state ");
16
      Serial.println(client.state());
17
      delay(2000);
18     }
19   }
20   client.publish("esp/test", "Hello from ESP8266");
21   client.subscribe("esp/test");

22 }

23

Fungsi Callback
Setelah inisialisasi, kita perlu menentukan fungsi callback, yang akan
menangani pesan masuk dari topik yang kita subscribe.

Argumen dari fungsi ini adalah nama topik, payload (dalam byte) dan
ukuran dari pesannya. Fungsi ini mestinya cukup mengembalikan
void/kosong.

Pada fungsi ini, kita pertama-tama mencetak nama topiknya ke serial


port, lalu mencetak setiap byte dari pesan yang diterima. Karena kita
juga memiliki panjang pesan sebagai argumen dari fungsi, ini dapat
dilakukan dengan mudah menggunakan perulangan.
Periksa keseleruhuan kode fungsinya sebagai berikut:

1 void callback(char* topic, byte* payload, unsigned int length) {


2   Serial.print("Message arrived in topic: ");
3   Serial.println(topic);
4   Serial.print("Message:");

5   for (int i = 0; i < length; i++) {

6     Serial.print((char)payload[i]);

7   }

8   Serial.println();

9   Serial.println("-----------------------");

}
10

Main loop
Pada fungsi main loop, kita hanya akan memanggil metode loop dari
PubSubClient. Fungsi ini harus dipanggil secara reguler agar
memungkinkan client untuk memproses pesan masuk dan menjaga
koneksinya dengan server.
?

1 void loop() {

2   client.loop();

3 }

Periksa kode lengkap dari awal hingga akhir sebagai berikut:

1 #include <ESP8266WiFi.h>

2 #include <PubSubClient.h>

3 const char* ssid = "YourNetworkName";

4 const char* password =  "YourNetworkPassword";

const char* mqttServer = "m11.cloudmqtt.com";


5
const int mqttPort = 12948;
6
const char* mqttUser = "YourMqttUser";
7
const char* mqttPassword = "YourMqttUserPassword";
8
9 WiFiClient espClient;

10 PubSubClient client(espClient);

11 void setup() {

12   Serial.begin(115200);

  WiFi.begin(ssid, password);
13
  while (WiFi.status() != WL_CONNECTED) {
14
    delay(500);
15
    Serial.println("Connecting to WiFi..");
16
  }
17
  Serial.println("Connected to the WiFi network");
18
  client.setServer(mqttServer, mqttPort);
19
  client.setCallback(callback);
20
  while (!client.connected()) {
21     Serial.println("Connecting to MQTT...");
22     if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
23       Serial.println("connected");
24     } else {

25       Serial.print("failed with state ");

26       Serial.println(client.state());

27       delay(2000);

28     }

29   }

  client.publish("esp/test", "Hello from ESP8266");


30
  client.subscribe("esp/test");
31
}
32
void callback(char* topic, byte* payload, unsigned int length) {
33
  Serial.print("Message arrived in topic: ");
34
  Serial.println(topic);
35
  Serial.print("Message:");
36
  for (int i = 0; i < length; i++) {
37
    Serial.print((char)payload[i]);
38   }
39   Serial.println();
40
41   Serial.println("-----------------------");
42 }

43 void loop() {

44   client.loop();

45 }

46

Berikut adalah kode program lengkap yang telah ditambahkan dua


subscribe (saklar & dimmer) dan satu publish (sensor). Subscribe
saklar untuk menyalakan dan mematikan lampu, subscribe dimmer
untuk menerangkan dan meredupkan lampu, dan publish sensor
untuk mengirim data pembacaan sensor potensiometer.

1 #include <ESP8266WiFi.h>

2 #include <PubSubClient.h>

3 const char* ssid = "......";

4 const char* password =  ""......";";

const char* mqttServer = ""......";";


5
const int mqttPort = "......";;
6
const char* mqttUser = ""......";";
7
const char* mqttPassword = ""......";";
8
WiFiClient espClient;
9
PubSubClient client(espClient);
10
int dataSensor = 0;
11
int dataSensorMapped = 0;
12
int dataSensorMappedBefore = 0;
13
void setup() {
14   pinMode(D1, OUTPUT);
15   pinMode(A0, INPUT);
16   Serial.begin(115200);
17   WiFi.begin(ssid, password);

18   while (WiFi.status() != WL_CONNECTED) {

    delay(500);
19     Serial.println("Connecting to WiFi..");

20   }

21   Serial.println("Connected to the WiFi network");

22   client.setServer(mqttServer, mqttPort);

  client.setCallback(callback);
23
  while (!client.connected()) {
24
    Serial.println("Connecting to MQTT...");
25
    if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
26
      Serial.println("connected");
27
    } else {
28
      Serial.print("failed with state ");
29
      Serial.println(client.state());
30
      delay(2000);
31     }
32   }
33   client.publish("esp/test", "Hello from ESP8266");
34   client.subscribe("esp/test");

35   client.subscribe("esp/saklar");

36   client.subscribe("esp/dimmer");

37 }

38 void callback(char* topic, byte* payload, unsigned int length) {

39   Serial.print("Message arrived in topic: ");

  Serial.println(topic);
40
  Serial.print("Message:");
41
  for (int i = 0; i < length; i++) {
42
    Serial.print((char)payload[i]);
43
  }
44
  Serial.println();
45
  Serial.println("-----------------------");
46
  if (strcmp(topic,"esp/saklar")==0){
47
    if((char)payload[0] == '1')
48     {
49       digitalWrite(D1, HIGH);
50       Serial.println("Turning on lamp");

51     }

52     else{

53       digitalWrite(D1, LOW);

      Serial.println("Turning off lamp");


54
    }
55
  }
56
  else if(strcmp(topic,"esp/dimmer")==0){
57
    payload[length] = '\0';
58
    int pwmVal = atoi((char *)payload);
59
    analogWrite(D1, pwmVal);
60
  }
61
}
62 long NOW = millis();
63 long LAST_SENT = 0;
64 void loop() {
65   client.loop();

66   NOW = millis();

67   if(NOW - LAST_SENT > 1500){

68     dataSensor = analogRead(A0);

69     dataSensorMapped = map(dataSensor, 0, 1023, 0, 100);

70     if(dataSensorMapped != dataSensorMappedBefore){

      Serial.print("Publishing to esp/sensor: ");


71
      Serial.println(dataSensorMapped);
72
      client.publish("esp/sensor", String(dataSensorMapped).c_str());
73
      dataSensorMappedBefore = dataSensorMapped;
74
    }
75
    LAST_SENT = NOW;
76
  }
77
  while (!client.connected()) {
78
    Serial.println("Connecting to MQTT...");
79     if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
80       Serial.println("connected");
81
82
83
84     } else {
85       Serial.print("failed with state ");
86       Serial.println(client.state());

87       delay(2000);

88     }

89   }

90 }

91
92
93

Melakukan pengujian melalui CloudMQTT WebSocket UI

Setelah kode program lengkap di atas diprogram ke NodeMCU


tentunya dengan merubah beberapa parameter seperti kredensial
WiFi dan CloudMQTT dan telah memastikan melalui serial monitor
bahwa koneksi ke CloudMQTT telah berhasil dilakukan oleh NodeMCU
seperti terlihat pada Gambar 2.21, kita dapat membuka halaman
WebSocket UI dari akun CloudMQTT kita untuk mencoba mengirim
perintah ke NodeMCU dan membaca data sensor yang dikirim oleh
NodeMCU. Sebagai contoh kita dapat mengirim perintah pada
topik esp/saklar dengan nilai 1 untuk menyalakan lampu, dengan 0
untuk memadamkan. Selain itu topik esp/dimmer juga dapat dicoba
dengan memberikan nilai 0 hingga 255 untuk menyetel terang redup
lampu. Pada topik esp/sensor si NodeMCU akan mempublish datanya
setiap kali kita memutar-mutar potensiometer.
arduino_serial_monitor.png

cloudmqtt_websocket_ui.jpg

Web Interfacing
Setelah dapat dilakukan kontrol dan monitoring perangkat IoT
melalui Internet, selanjutnya pada sesi ini dilanjutkan dengan
membuat antarmuka web moderen sederhana untuk kontrol &
monitoring sistem IoT yang telah dibuat.
tampilan_web_interface_untuk_kontrol_monitoring.jpg

Tampilan yang dibuat menggunakan beberapa framework pemrograman web seperti Bootstrap 3
untuk membuat komponen UI seperti tombol, slider dan progress bar, juga framework javascript
jQuery untuk memanipulasi data dan MQTTPaho untuk menangani koneksi dan integrasi dengan
CloudMQTT. File yang berisi kode sumber web interface telah disediakan untuk mempermudah
pengujian, pada file index.html perlu dilakukan beberapa penyesuaian seperti alamat server, nomer
port, username dan password dari instance CloudMQTT kita. Berikut adalah kode lengkap dari file
index.html yang berisi web interface:

1 <!DOCTYPE html>

2 <html lang="en">

3   <head>

4     <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">


5
    <meta name="viewport" content="width=device-width, initial-scale=1">
6
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
7
    <script src="js/jquery-1.12.4.js"></script>
8
    <script src="js/mqttws31.js"></script>
9
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
10
    <title>ESP8266 WebIface</title>
11
    <!-- Bootstrap -->
12
    <link href="css/bootstrap.min.css" rel="stylesheet">
13     <link href="css/bootstrap-toggle.min.css" rel="stylesheet">
14     <link href="css/bootstrap-slider.min.css" rel="stylesheet">
15     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
16     <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->

17     <!--[if lt IE 9]>
18       <script src="<a href="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js">https://oss.maxcdn.com/ht

19       <script src="<a href="https://oss.maxcdn.com/respond/1.4.2/respond.min.js">https://oss.maxcdn.com/respo

20     <![endif]-->

21     <script type="text/javascript">

        jQuery(document).ready(function(){
22
            // Create a client instance
23
            client = new Paho.MQTT.Client("postman.cloudmqtt.com", 38155,"WebIface");
24
            //Example client = new Paho.MQTT.Client("m11.cloudmqtt.com", 32903, "web_" + parseInt(Math.random() *
25
            // set callback handlers
26
            client.onConnectionLost = onConnectionLost;
27
            client.onMessageArrived = onMessageArrived;
28
            var options = {
29
                useSSL: true,
30                 userName: "isi username",
31                 password: "isi password",
32                 onSuccess:onConnect,
33                 onFailure:doFail

34             }

35             // connect the client

36             client.connect(options);

37             // called when the client connects

            function onConnect() {
38
                // Once a connection has been made, make a subscription and send a message.
39
                console.log("onConnect");
40
                client.subscribe("/cloudmqtt");
41
                client.subscribe("esp/sensor");
42
                /*message = new Paho.MQTT.Message("Hello CloudMQTT");
43
                message.destinationName = "/cloudmqtt";
44
                client.send(message);*/
45
            }
46
            function doFail(e){
47                 console.log(e);
48             }
49             // called when the client loses its connection

50             function onConnectionLost(responseObject) {

51                 if (responseObject.errorCode !== 0) {

52                   console.log("onConnectionLost:"+responseObject.errorMessage);

                }
53
            }
54
            // called when a message arrives
55
            function onMessageArrived(message) {
56
                console.log("onMessageArrived:"+message.payloadString);
57
                if(message.destinationName == "esp/sensor"){
58
                    $('#pgbar-sensor').css({'width': message.payloadString+'%'});
59
                    $('#pgbar-sensor').attr({'aria-valuenow': message.payloadString});
60
                    $('#pgbar-sensor').html(message.payloadString+'%');
61                 }
62             }
63         });
64     </script>

65     <style type="text/css">

66         .slider.slider-horizontal {

67             width: 100%;

68             height: 20px;

        }
69
        .text-bold {
70
            font-weight: bold;
71
        }
72
    </style>
73
  </head>
74
  <body>
75
    <div class="container">
76
        <div class="row">
77
            <div class="col-sm-12 text-center">
78                 <h1>My IoT Dashboard</h1>
79                 <hr>
80                 <div class="panel panel-primary">

81                     <div class="panel-heading"> <h3 class="panel-title text-bold"><span class="glyphicon glyphicon-eye-ope

82                     <div class="panel-body">

83                         <div class="progress">

                          <div id="pgbar-sensor" class="progress-bar progress-bar-danger progress-bar-striped active" role="


84
                          aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
85
                            Data sensor: 0%
86
                          </div>
87
                        </div>
88
                    </div>
89
                </div>
90
                <div class="panel panel-primary">
91
                    <div class="panel-heading"> <h3 class="panel-title text-bold"><span class="glyphicon glyphicon-tasks" a
92                     <div class="panel-body">
93                         <div class="form-group">
94                             <input id="slider-dimmer" type="text" data-slider-min="0" data-slider-max="1023" data-slider-step
95                         </div>

96                         <hr>

97                         <div class="form-group">

98                             <input id="btn-saklar" type="checkbox" checked data-toggle="toggle" data-onstyle="warning" data-

99                         </div>

100                     </div>

                </div>
101
            </div>
102
            <
103
        </div>
104
    </div>
105
    <!-- Include all compiled plugins (below), or include individual files as needed -->
106
    <script src="js/bootstrap.min.js"></script>
107
    <script src="js/bootstrap-toggle.min.js"></script>
108
    <script src="js/bootstrap-slider.min.js"></script>
109     <script type="text/javascript">
110         // jQuery Script
111
112
113
114
115         jQuery(document).ready(function(){

116             $("#slider-dimmer").slider();

117             $("#slider-dimmer").on("slide", function(slideEvt) {

                message = new Paho.MQTT.Message(slideEvt.value.toString());


118
                message.destinationName = "esp/dimmer";
119
                client.send(message);
120
            });
121
            $('#btn-saklar').change(function() {
122
                message = new Paho.MQTT.Message($(this).prop('checked') ? '1' : '0');
123
                message.destinationName = "esp/saklar";
124
                client.send(message);
125
            })
126         });
127     </script>
128   </body>
129 </html>

130
131
132
133

Kode program dari Web Interface yang telah dibuat dapat diakses
secara lokal melalui komputer/laptop. Namun untuk implementasi
riil, interface ini dapat diunggah secara privat ke internet sehingga
dapat diakses melalui alamat domain, misalnya seperti
dashboardsaya.com. Dengan demikian, antarmuka dapat diakses dari
mana saja melalui perangkat apapun yang mendukung teknologi web
modern.

Ringkasan
Pada pelatihan ini kita mempelajari microcontroller basic dan internet
of things. Mikrokontroler dipelajari karena teknologi IoT pada
umumnya menggunakan mikrokontroler sebagai perangkat keras
pengambil data dan pengendali instrument yang hendak dihubungkan
ke Internet. Teknologi IoT memungkinkan segala macam benda mati
maupun benda hidup untuk memiliki kemampuan komputasi dan
terhubung satu sama lain. Dengan demikian, mereka dapat saling
bertukar data dan meningkatkan fungsi dan efisiensi.
Secara teknis, kita menggunakan NodeMCU sebagai development
board untuk mempermudah percobaan implementasi teknologi IoT,
dibantu dengan Arduino IDE untuk memprogram. Selanjutnya,
CloudMQTT mengambil peran sebagai broker online yang bertindak
sebagai penengah antara alat kita dan web interface yang kita buat.
Sehingga antara alat kita dan web interface yang berisi tampilan
berupa tombol, slider dan progress bar dapat berinteraksi dengan alat
kita secara online melalui Internet. Apabila kita memiliki banyak alat,
maka masing-masing alat juga dapat berinteraksi satu sama lain tanpa
melibatkan manusia di dalamnya. Mereka dapat bertukar data melalui
metode publish dan subscribe dari library client MQTT yang kita pakai
yaitu PubSubClient.
Selanjutnya, apa yang telah kira pelajari pada pelatihan ini dapat
memberikan kita bayangan, bagaimana suatu benda mati/hidup dapat
ditingkatkan fungsi dan efisiensinya menggunakan teknologi IoT. Kita
dapat menambahkan lebih banyak lagi perangkat sensor dan aktuator
untuk mencapai tujuan di dunia nyata, seperti yang telah dipaparkan
pada bagian pengenalan IoT. Teknologi IoT dapat digunakan di semua
bidang, mulai dari bisnis, kesehatan, pertanian, hingga rumahan dan
edukasi. Berbagai materi dan pengetahuan tambahan mengenai
konsep, arsitektur, hingga tutorial untuk implementasi teknis dari
teknologi IoT telah tersedia melimpah di Internet.

Anda mungkin juga menyukai