Cara menggunakan php serial port communication

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

Setup

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

Instalasi package

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 serialport
npm 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:

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},

Simpan perubahan file tersebut.

Data acak pada Arduino

Photo 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
#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);
}
  • upload program lalu tampilkan hasilnya pada serial monitor.

Jangan lupa simpan program tersebut karena akan kita butuhkan nantinya.

Membuat server sederhana

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 express = require('express')
const app = express()
const port = 3000
app.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
app.use(express.static(__dirname))

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

app.listen(port, () => console.log(`Listening on port ${port}!`))

Menjalankan server pada port yang telah ditentukan.

Pembacaan data serial dengan SerialPort.io

Selanjutnya kita lakukan pembacaan data serial menggunakan package yang sudah kita install sebelumnya.

  • Buka file server.js
  • Tambahkan library serialport dengan cara berikut:
const express = require('express'),
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

var stream
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 = 3000
app.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 = 3000
app.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 = 3000
app.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 express express-http-to-https serialport
npm i --save-dev nodemon
0

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 = 3000
app.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 = 3000
app.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 = 3000
app.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 = 3000
    app.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 serialport
npm i --save-dev nodemon
1

Kita telah berhasil mengakuisisi data serial dan menampilkannya pada website!

Data yang terbaca akan berubah ubah dan terpotong. Pada langkah berikutnya akan dijelaskan penyelesaiannya.

Membuat halaman index.html

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 express express-http-to-https serialport
npm i --save-dev nodemon
2
  • Buka file server.js
  • Ubahlah baris berikut:
app.get('/', (req, res) => res.send('Hello World!'))

Menjadi:

npm i --save express express-http-to-https serialport
npm i --save-dev nodemon
4
  • 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 serialport
npm i --save-dev nodemon
5Tokenisasi

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 serialport
npm i --save-dev nodemon
6

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 serialport
npm i --save-dev nodemon
7

Apabila kita melakukan tokenisasi berdasarkan tanda ‘?’, maka kita dapat membagi teks tersebut menjadi:

  1. data pertama = 12
  2. data kedua = 250
  3. 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 serialport
npm i --save-dev nodemon
8

Kemudian kita tambah program tokenizing pada server.js dengan mengubah baris berikut:

npm i --save express express-http-to-https serialport
npm i --save-dev nodemon
9
  • 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
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "nodemon server.js"
},
0
  • Kemudian untuk menggunakannya tambahkan baris berikut:
"scripts": {
"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 = 3000
app.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.

"scripts": {
"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 = 3000
app.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:
"scripts": {
"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.