Lamp App: Mengendalikan Aplikasi Desktop Menggunakan Sensor Cahaya

10 Desember 2016

Tulisan asli saya bisa diakses di sini

Weekend sudah tiba, dan saatnya bermain-main dengan javascript. Hari ini saya akan mencoba hal baru, membuat aplikasi desktop yang dapat berinteraksi dengan cahaya. Aplikasi desktop ini akan saya beri nama Lamp App, dimana lampu di dalam aplikasi akan menyala jika kita berada di tempat gelap, sebaliknya lampu akan mati jika kita berada di tempat yang terang. Mari kita mulai.

Bahan yang dibutuhkan

1. Perangkat Lunak

2. Perangkat Keras

  • Papan Arduino (Saya menggunakan Arduino UNO)
  • Breadboard
  • LDR / Light Dependent Resistor
  • Resistor 10K Ω
  • 3 buah kabel jumper

Pada awalnya Electron dibuat oleh orang-orang hebat di Github sebagai basis dari teks editor Atom. Dengan menggunakan Electron, kita dapat membuat aplikasi desktop yang berjalan di Windows, macOS, dan Linux hanya dengan menggunakan teknologi berbasis web (HTML, CSS, Javascript). Saat ini Electron banyak digunakan untuk membuat aplikasi desktop terkenal seperti Skype, Slack, Visual Studio Code, Whatsapp, dll. Pada dasarnya, Electron adalah peramban web berbasis Chromium, dan kita membuat web app untuk berjalan di atasnya. Electron menyediakan API (Application Programming Interface) untuk memudahkan para pengembang untuk mengaksses File System, OS Menu, Sistem Notifikasi OS, Automatic Update, dan lain-lain. Kita juga dapat dengan mudah mengintegrasikan modul-modul Node.js ke dalam Electron.

Tentang Arduino, jika dilihat dari halaman wikipedianya:

Arduino is an open-source project that created microcontroller-based kits for building digital devices and interactive objects that can sense and control physical devices.

Kamu dapat membaca tentang Arduino langsung dari Wikipedia, atau dari website resminya.

Johnny Five adalah sebuah modul Node.js yang menggunakan Firmata untuk secara langsung dengan Arduino. Dengan menggunakan modul ini, kita bisa dengan mudah berinteraksi dengan Arduino, cukup menggunakan javascript, tanpa menggunakan bahasa C / C++. Silakan klik link berikut untuk mendapatkan instruksi yang lebih lengkap cara menyiapkan Arduino milikmu agar dapat berkomunikasi dengan Johnny Five.

Socket.io adalah sebuah pustaka javascript untuk protokol komunikasi websocket, sehingga memungkina komunikasi dua arah secara real-time. Untuk aplikasi yang akan kita bangun, socket.io digunakan untuk sebagai jalur komunikasi data antara Johnny Five dengan antarmuka aplikasi.

Tampilan Antarmuka

Tampilan antarmuka aplikasi kita akan sangat sederhana. Kita akan menaruh satu icon berbentuk lampu di bagian tengah, dan menaruh sebuah lingkaran sinar di belakang lampu tersebut. Kita akan mengubah opacity lingkaran berdasarkan data yang kita terima dari sensor cahaya. Untuk mempermudah, icon lampu akan kita ambil dari pustaka icon Font Awesome.

Antarmuka
Tampilan akhir aplikasi (sebelah kiri), dan tampilan ketika kita berada di tempat gelap (sebelah kanan)

Kode

Mari mulai menulis kode. Silakan memulai dari electron quick start menggunakan perintah berikut:

$ git clone https://github.com/electron/electron-quick-start lamp
$ cd lamp
$ npm install

Setelah proses di atas selesai, silakan install modul-modul lain yang kita butuhkan

$ npm install --save johnny-five express socket.io

Bagian pertama dari kode aplikasi adalah server.js. Ini adalah kode yang bertindak sebagai server. Ketika aplikasi dijalankan, kode ini akan berjalan di latar belakang aplikasi, memeriksa apakah papan Arduino terhubung dengan benar, menerima data dari sensor cahaya, dan mengirimkan data ke antarmuka melalui socket.io.

const express = require('express')
const socket = require('socket.io')
const jfive = require('johnny-five')
const http = require('http')

const CONSTANTS = require('./const')

module.exports = () => {
  const app = express()
  const server = http.createServer(app)
  const io = new socket(server)
  const port = process.env.PORT || CONSTANTS.PORT
  const board = new jfive.Board()

  // on Socket.io connection
  io.on('connection', (client) => {
    client.emit('init', { message: 'Server - Client connected, Socket.IO works.' })

    // on Arduino Board ready
    board.on('ready', () => {

      // create an LDR sensor object
      const ldr = new jfive.Sensor({
    		pin: 'A2',
    		freq: 250
    	})

      // send data to client if get new value from the sensor
      ldr.on('data', () => {
        let data = {
          opacity: ldr.scaleTo(0, 100)
        }
        client.emit('ldr', data)
      })
    })
  })

  // make server listen to the preconfigured port
  server.listen(port)
}

Dari kode di atas, bisa kita lihat, ketika socket.io sudah berjalan, kita cek apakah papan Arduino terhubung dengan benar. Ketika sudah terhubung dengan benar, kita akan membuat sebuah objek LDR (sensor cahaya). LDR akan dipasang pada pin “A2” pada papan Arduino, dan sensor akan mengambil data setiap interval 250 milidetik. Setiap data yang diterima akan kita ubah agar selalui berada dalam rentang 0 - 100 untuk mempermudah perhitungan. Dan terakhir, socket.io akan mengirimkan data tersebut.

Selanjutkan kita akan menaruh server.js ke dalam main.js. main.js dibuat secara otomatis oleh Electron Quick Start. Berikut adalah kode lengkap main.js yang sudah dimodifikasi.

const electron = require('electron')
const http = require('http')
const initServer = require('./js/server')

// Module to control application life.
const app = electron.app

// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

const path = require('path')
const url = require('url')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

const createWindow = () => {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 480, height: 640})

  // and load the index.html of the app.
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))

  // Open the DevTools.
  // mainWindow.webContents.openDevTools()

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null
  })

  // Init Express + Socket.IO server
  initServer()
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

Selanjutnya kita akan membuat file renderer.js yang digunakan untuk memanipulasi tampilan apilkasi, berdasarkan data yang dikirimkan oleh socket.io. Kita lihat, jika ada data dari socket.io yang diterima, maka kita akan mengubah opacity dari elemen #the-light.

const io = require('socket.io-client')
const CONSTANTS = require('./const')
const socket = io.connect('http://localhost:' + CONSTANTS.PORT)
const theLight = document.getElementById('the-light')

// log the message, check if socket.io server is connected
socket.on('init', (data) => {
  console.log(data.message)
})

// catch the data if 'ldr' event occur
socket.on('ldr', (data) => {
  let opacity = data.opacity
  if( opacity < 85 ) {
    opacity = 0
  }
  // set element opacity based on data value
  theLight.style.opacity = opacity / 100
})

Karena pada dasarnya Electron adalah halaman web, maka kita memerlukan sebuah file berenkstensi .html. Dan berikut adalah isi index.html. Kita bisa lihat, renderer.js dijalankan secara langsung oleh index.html.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Lamp</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div id="the-light"></div>
    <div class="container">
      <i class="fa fa-lightbulb-o"></i>
    </div>
  </body>
  <script>
    require('./js/renderer')
  </script>
</html>

Dan supaya tampilan aplikasi kita terlihat lebih baik, berikut adalah style.css yang akan kita gunakan

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  background: black;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: sans-serif;
}

a {
  text-decoration: none;
}

.container {
  text-align: center;
  color: white;
  z-index: 1000;
}

.container i {
  font-size: 10em;
  text-shadow: 0 0 10px #000;
}

#the-light {
  opacity: 0;
  display: block;
  position: fixed;
  width: 640px;
  height: 640px;
  top: 50%;
  left: 50%;
  margin-left: -320px;
  margin-top: -320px;
  border-radius: 320px;
  z-index: 0;
  background: radial-gradient(ellipse at center, rgba(255,255,255,1) 0%,rgba(0,0,0,1) 70%);
}

Perangkat Keras

Setelah selesai dengan kode, berikut kita akan susun perangkat keras dengan posisi seperti pada gambar berikut, berdasarkan contoh yang terdapat pada website Johnny Five.

Pengaturan Perangkat Keras
Posisi kabel, papan Arduino, dan komponen lain pada Breadboard.

Sekarang Kamu dapat menyambungkan papan Arduino ke port USB komputer.

Menjalankan Aplikasi

Silakan buka Terminal Emulator, dan jalankan perintah berikut

$ npm start

Jika muncul pesan error Module version mismatch, maka Kamu harus menginstall modul tambahan menggunakan perintah berikut

$ npm install --save-dev electron-rebuild
$ ./node_modules/.bin/electron-reubild

Setelah proses di atas selesai, silakan jalankan kembali perintah npm start. Silakan coba bawa aplikasi ini ke dalam kamar gelap, atau tutup komponen LDR dengan jari. Maka tampilan aplikasi akan berubah, dan tampilan lampu akan menyala. Berikut contoh videonya:

Kesimpulan

Proyek weekend ini cukup seru. Tidak hanya front-end dan server, ternyata javascript juga dapat digunakan untuk terkoneksi dengan dunia nyata, dalam hal ini sensor cahaya. Semuanya jadi mungkin karena Johnny Five dan Arduino. Semoga eksperimen ini bisa jadi sumber inspirasi untuk proyek-proyek lainnya. Mengedalikan robot menggunakan javacript? Lampu yang dikendalikan oleh sebuah tweet? Semua terserah kamu dan imajinasimu.

Jangan lupa, silakan lihat keseluruhan kode proyek ini di sini. Terima kasih.

tag: , , , ,


Aldi Daswanto
Ditulis oleh Aldi Daswanto, full stack developer
Follow saya di Instagram, atau kontak saya via email di aldi[at]daswanto.com
© 2022, Dibuat menggunakan Gatsby