Dalam melakukan debugging pada Arduino, kita tentu sering menambahkan "scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},6 kemudian melihat hasilnya pada serial monitor. Namun, bagaimana caranya agar semua data yang ada pada serial monitor bisa ditampilkan pada sebuah website? Beruntungnya sebuah projek serialport.io mampu menjawab permasalahan ini, yaitu hanya dengan menggunakan javascript kita dapat mengakuisisi data serial pada Arduino. Gambar di atas merupakan contoh website yang akan kita buat pada tutorial ini.
Apa yang saya gunakan?
- Browser: Google Chrome 79.0
- Text Editor: Visual Studio Code
- IDE: Arduino IDE
- Arduino: WeMos D1
- NodeJS versi 12
- Node package: Express, SerialPort, Express-http-to-https
- Library: ChartJS
- Sistem operasi: Fedora 31
Disarankan untuk mencoba program ini pada Linux, dikarenakan program ini mengalami error ketika dijalankan pada windows 10
Index
Sebelum kita memulai, pastikan di komputer kita telah terpasang NodeJS karena untuk menggunakan package SerialPort kita harus memasang NodeJS terlebih dahulu.
Cara Install Node.js dan NPM di Ubuntu 18.04 - Niagahoster Blog
Anda menggunakan Linux Ubuntu dan ingin menginstall Node.js dan NPM? Tenang saja karena caranya cukup mudah. Setidaknya…
www.niagahoster.co.id
- Setelah NodeJS telah terpasang, selanjutnya buatlah folder khusus yang akan digunakan untuk menyimpan file yang diperlukan.
- Bukalah terminal pada folder tersebut
- Jalankan perintah "scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},7 lalu tekan enter
"name": "SerialComm",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Setelah dijalankan, maka akan muncul hasil seperti di atas. Hasil tersebut tidak mutlak jadi pasti akan berbeda beda setiap PC.
Bila kita perhatikan, kini di dalam folder yang telah dibuat terdapat sebuah file bernama package.json. Isi file tersebut tidak jauh berbeda dengan apa yang muncul setelah menjalankan perintah "scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},7
Pastikan pada folder tersebut sudah terdapat file package.json sebelum melakukan instalasi.
Untuk memulai instalasi, jalankan perintah berikut pada terminal
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon
Perintah di atas akan mengunduh package yang dibutuhkan melalui internet jadi pastikan komputer telah terkoneksi ke jaringan internet.
Setelah selesai, maka akan muncul folder baru bernama node_modules yang berisikan package yang kita butuhkan serta pada file package.json ada tambahan keterangan bagian dependencies.
Pada gambar tersebut, di bagian dependencies kita bisa lihat package apa saja yang telah terpasang dan versi dari masing masing package. Disini kita telah berhasil melakukan instalasi node package.
Berikutnya buka file package.json, pada baris "scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},9 ubah menjadi berikut:
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},
Simpan perubahan file tersebut.
Data acak pada ArduinoPhoto by Harrison Broadbent on Unsplash
Selanjutnya, kita siapkan data serial yang akan dikirim melalui Arduino. Berhubung disini kita hanya membuat prototipe, jadi kita cukup membuat data random untuk memastikan apakah data tersebut dapat diterima.
- Jalankan program Arduino IDE
- Tentukan board yang akan digunakan serta port yang dipakai
- Tambahkan program berikut
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}
- upload program lalu tampilkan hasilnya pada serial monitor.
Membuat server sederhanaJangan lupa simpan program tersebut karena akan kita butuhkan nantinya.
Dikarenakan kita akan membuat website untuk menerima data serial, kita membutuhkan server. Nantinya kita akan membuat REST API sederhana untuk mengambil data serial tersebut.
Disini kita menggunakan expressJS yang sebelumnya sudah kita install.
- Buat file baru bernama server.js
- Buka file tersebut menggunakan text editor favorit kalian.
- Tambahkan program berikut:
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))
- Simpan program di atas pada file server.js
- Jalankan perintah #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}0pada terminal - Bukalah #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}1 pada browser
Kita telah membuat server sederhana menggunakan ExpressJS. Berikut adalah penjelasan dari tiap baris program sebelumnya:
- #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}2 Meng-import library express - #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}3 Membuat objek dari class express - #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}4 Membuat variabel port
Berfungsi untuk menentukan dimana file server.js dijalankan. Ini akan kita gunakan untuk memudahkan kita melacak lokasi file HTML.
app.get('/', (req, res) => res.send('Hello World!'))Kita menentukan respon yang diberikan server ketika mengakses url #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}1 atau #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}6
Menjalankan server pada port yang telah ditentukan.
Pembacaan data serial dengan SerialPort.ioSelanjutnya kita lakukan pembacaan data serial menggunakan package yang sudah kita install sebelumnya.
- Buka file server.js
- Tambahkan library serialport dengan cara berikut:
app = express(),
SerialPort = require('serialport'),
port = new SerialPort('/dev/ttyUSB0', {
baudRate: 115200,
}, err => {
if(err != null) {
console.log(err)
return
}
})
Ketika kita hendak menggunakan library serialport kita langsung menambahkan parameter nama port yang terdeteksi dan baudrate yang digunakan. Nama port yang terdeteksi serta baudrate disesuaikan dengan yang ada pada Arduino IDE
Selanjutnya mari kita tambahkan program untuk membaca data serial pada baris sebelum #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}7
app.get('/data', (req,res) => {
port.setMaxListeners(9000)
port.on('data', data => {
data = JSON.stringify(data)
data = JSON.parse(data)
stream = data
})
res.json(stream)
})
Program di atas merupakan gabungan dari library serialport dan expressJS. Pertama kita membuat variabel bernama #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}8 kemudian kita membuat route baru menggunakan #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}9 yaitu dimana ketika mengakses const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))0 program di dalamnya akan dijalankan.
const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))1 digunakan untuk meminimalisir terjadinya error ketika pengambilan data serial.
const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))2 merupakan fungsi untuk mengakuisisi data serial dari Arduino yang mana data yang diterima akan disimpan pada variabel data.
npm i --save-dev nodemon0
Proses di atas berfungsi untuk melakukan parsing data serial yang berupa byte. Sebab untuk bisa diolah pada website maka data tersebut perlu diubah ke format yang dapat dibaca oleh website, salah satunya JSON (JavaScript Object Notation)
Mengenal Format JSON - CodePolitan.com
JSON - singkatan untuk JavaScript Object Notation - adalah sebuah format untuk berbagi data. Seperti dapat kita lihat…
www.codepolitan.com
const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))3 ini merupakan sebuah fungsi wajib setiap kali membuat route pada ExpressJS, const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))4 merupakan response yang diberikan oleh server. Biasanya berupa status, apakah 404 Not found atau 200 Ok atau bisa juga berupa HTML, teks maupun JSON. Dikarenakan data yang dikirim adalah JSON maka kita gunakan const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))5
- Simpan file tersebut lalu akses URL const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))0 melalui browser
Bila kita perhatikan di atas, data yang tersimpan masih berupa byte. Sekarang kita ubah data tersebut agar lebih mudah terbaca dengan mengubah program berikut:
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon1
Kita telah berhasil mengakuisisi data serial dan menampilkannya pada website!
Membuat halaman index.htmlData yang terbaca akan berubah ubah dan terpotong. Pada langkah berikutnya akan dijelaskan penyelesaiannya.
Photo by ian dooley on Unsplash
Wokay, kini kita tinggal menampilkan semua data yang ada pada website. Disini kita hanya memainkan HTML/CSS dan sedikit javascript untuk mengakuisisi data.
- Buatlah folder bernama public di dalam folder yang telah kita buat.
- Buatlah file index.html di dalam folder public
- Buka file index.html dan tambahkan:
- Buatlah folder bernama static
- Buatlah file bernama style.css di dalam folder static
- Isilah dengan:
npm i --save-dev nodemon2
- Buka file server.js
- Ubahlah baris berikut:
Menjadi:
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon4
- Simpan file lalu buka#include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}1 pada browser
Bila kita perhatikan, data di atas merupakan data yang kita atur secara default menggunakan HTML. Lalu kanvas sebelah kanan akan kita isi dengan grafik yang akan dijelaskan di bagian berikutnya.
Untuk mendapatkan data serial, kita perlu menambahkan javascript pada file index.html yaitu menambahkan baris berikut:
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon5Tokenisasi
Disini kita sudah berhasil mengambil data serial, namun sebelumnya data yang ditampilkan tidaklah sempurna dan terpotong-potong. Bagaimana cara mengatasinya? Dikarenakan kita hanya membutuhkan angka saja, maka kita hilangkan semua keterangan yang ada. Sehingga bila kita lihat lagi program di Arduino kita menjadi seperti berikut:
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon6
Masalah kedua muncul, bagaimana kita membedakan mana data pertama, kedua, dan ketiga dari data tersebut?
Disini kita mengenal sebuah metode bernama tokenizing atau tokenisasi. Singkatnya, metode tokenisasi membagi teks berdasarkan tanda tertentu. Contoh:
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon7
Apabila kita melakukan tokenisasi berdasarkan tanda ‘?’, maka kita dapat membagi teks tersebut menjadi:
- data pertama = 12
- data kedua = 250
- data ketiga = 30
Tokenisasi
Dari Wikipedia bahasa Indonesia, ensiklopedia bebas Loncat ke navigasi Loncat ke pencarian Artikel ini perlu…
id.wikipedia.org
Maka kita perlu mengubah format data serial yang dikirim dari Arduino menjadi berikut:
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon8
Kemudian kita tambah program tokenizing pada server.js dengan mengubah baris berikut:
npm i --save express express-http-to-https serialportnpm i --save-dev nodemon9
- Simpan file dan buka #include<time.h>void setup() {
srand(time(NULL));
Serial.begin(115200);
}void loop() {
String data = "temperature = " + String(rand()%40) + " adc = " + String(rand()%255) + " milivolt = " + String(rand()%50);
Serial.print(data);
delay(1000);
}1 pada browser
Membuat grafik dengan chartJS
ChartJS Homepage
Pada bagian ini kita akan memvisualisasikan dari data yang didapatkan dalam bentuk grafik menggunakan chartJS.
- Salin program dari link ini dan simpan dalam folder static dengan nama chart.min.js
- Pada index.html tambahkan baris berikut untuk menggunakan chartJS
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},0
- Kemudian untuk menggunakannya tambahkan baris berikut:
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},1
- Refresh browser maka akan tampil seperti berikut:
Mari kita pahami maksud dari program sebelumnya:
"scripts": {"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},2
Disini kita melakukan DOM (Document Object Manipulation) dengan mengambil tag HTML dengan ID const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))9. app.use(express.static(__dirname))0 maksudnya adalah karena kita akan menggambar grafik 2 dimensi di app.use(express.static(__dirname))1 maka method ini kita perlukan.
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},3
Kita membuat objek dari class app.use(express.static(__dirname))2 yang di dalamnya terdapat parameter yang kita isi dengan variabel app.use(express.static(__dirname))3 yang sudah kita buat sebelumnya. Disini kita akan menggunakan tag HTML dengan ID const express = require('express')
const app = express()
const port = 3000app.use(express.static(__dirname))
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Listening on port ${port}!`))9 untuk mengambar grafik.
Pada parameter kedua berisikan objek yang terdapat key dan value, berikut adalah penjelasannya:
- app.use(express.static(__dirname))5 merupakan jenis grafik yang akan digambar
- app.use(express.static(__dirname))6 berisikan konfigurasi grafik seperti warna label, warna grafik, banyak data grafik, dll.
- app.use(express.static(__dirname))7 merupakan keterangan yang terdapat pada sumbu X.
- app.use(express.static(__dirname))8 konfigurasi data pada grafik
- app.use(express.static(__dirname))9 label keterangan yang muncul pada bagian atas grafik
- app.use(express.static(__dirname))6 merupakan data yang ditampilkan pada grafik
- app.get('/', (req, res) => res.send('Hello World!'))1 warna garis pada grafik
- app.get('/', (req, res) => res.send('Hello World!'))2 ketebalan garis
- app.get('/', (req, res) => res.send('Hello World!'))3 memblok area bawah garis dengan warna.
- app.get('/', (req, res) => res.send('Hello World!'))4 opsi tambahan untuk konfigurasi pada grafik
- app.get('/', (req, res) => res.send('Hello World!'))5 berisi konfigurasi untuk sumbu pada grafik
- app.get('/', (req, res) => res.send('Hello World!'))6 konfigurasi sumbu Y
- app.get('/', (req, res) => res.send('Hello World!'))7 konfigurasi nilai pada sumbu Y
- app.get('/', (req, res) => res.send('Hello World!'))8 menentukan apakah nilai pada sumbu dimulai dari 0
Selanjutnya, kita akan memasukkan data yang telah kita terima dan menggambarkannya pada grafik. Tambahkan program javascript berikut setelah fungsi app.get('/', (req, res) => res.send('Hello World!'))9 pada file index.html:
"scripts": {"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},4
- Setelah itu ubahlah fungsi app.get('/', (req, res) => res.send('Hello World!'))9 menjadi seperti berikut:
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},5
- Simpan file lalu refresh browser
Kini kita telah berhasil membaca data serial dan menampilkannya di website, metode yang digunakan disini hanya untuk pelajaran semata. Memang protokol HTTP dengan metode GET & POST tidak cocok untuk digunakan mengakuisisi data dengan interval ≤ 1 detik. Alternatif yang lebih baik menggunakan websocket atau MQTT. Namun, untuk saat ini penulis masih memelajari kedua protokol tersebut.