Assalamualaikum, jumpa lagi di triyonos.com dengan tutorial-tutorial pemrograman yang menarik dan mudah untuk dipelajari.
Pada tutorial kali ini triyonos.com akan membahas tentang implementasi dari Server Sent Events (SSE), yang merupakan salah satu metode transfer data satu arah dari server ke client. Server Sent Events (SSE) adalah API yang disediakan oleh HTML 5 untuk mem-push data dari server ke client. Dengan menggunakan SSE kita dapat mendapatkan update dari server tanpa harus mengirimkan data tertentu terlebih dahulu.
Di tutorial ini saya akan membuat suatu project controller warna nyala lampu LED Strip WS2812, yang warna nyala LED strip-nya berdasarkan nilai RGB dari warna object yang tertangkap di webcam. Hmmm.. menurut saya cukup keren sih projectnya, mudah-mudahan teman-teman bisa mempraktikkannya walaupun harus keluar biaya untuk membeli Arduino, LED Strip, dll.
Dalam membuat project tersebut saya menggunakan bahasa pemrograman Python dan Javascript. Aplikasi web yang berperan sebagai server saya buat menggunakan framework Flask yang berbahasa pemrograman Python, sedangkan client-nya menggunakan interface EventSource di node.js untuk menerima data Server Sent Events (SSE).
Saya akan membuat aplikasi pendeteksi warna (RGB) dari suatu object atau benda yang di dekatkan ke webcam menggunakan library Python OpenCV. Aplikasi ini berjalan di web browser, data RGB yang terdeteksi akan di-push ke client tiap 0.3 detik melalui metode Server Sent Events (SSE). Data RGB ini kemudian dibaca oleh node.js untuk kemudian diteruskan ke Arduino Uno untuk mengontrol nyala lampu LED strip WS2812.
Tahapan Pembuatan Project
1. Pembuatan Color Detection Web Application
Seperti pada tutorial-tutorial sebelumnya, dalam pembuatan web application ini saya menggunakan framework Flask yang di-install melalui Pycharm IDE. Berikut tahapan pembuatan aplikasinya:
- Buka Pycharm IDE kemudian Create Project
- Install Flask & OpenCV
- Copy Paste Folder templates & static
- Create New Python File app.py
- Test Running App
Beri nama project Flask_OpenCV_SSE pada text box Location. Kemudian klik tombol Create
Tampilan awal project Flask_OpenCV_SSE di Pycharm IDE
Pilih menu File Setting, kemudian pilih menu Python Interpreter, kemudian klik icon + untuk menampilkan jendela Available Packages
Install Flask melalui jendela Available Packages
Install OpenCV melalui jendela Available Packages
Flask & OpenCV berhasil terinstall.
Silakan klik link templates_static_folder.zip ini untuk mendownload folder templates dan static untuk di copy paste ke dalam root folder project Flask_OpenCV_SSE.
Extract file .zip yang sudah didownload
Drag and drop folder templates dan static dari folder download ke root folder project Flask_OpenCV_SSE
Jika proses copy paste folder templates dan static berhasil, maka struktur file-nya akan seperti gambar berikut:
Klik kanan pada root folder, arahkan mouse ke New Pyhton File, kemudian isikan dengan nama file app
File app.py berhasil dibuat
Selanjutnya copy paste script kode di bawah ini:
from flask import Flask, Response, render_template
import time
import cv2
import json
r = 0
g = 0
b = 0
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
def rgb_detection():
wCam, hCam = 400, 400
cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)
while True:
_, img = cap.read()
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
height, width, _ = img.shape
cx = int(width / 2)
cy = int(height / 2)
# Pick pixel value
pixel_center = hsv_img[cy, cx]
hue_value = pixel_center[0]
global b, g, r
pixel_center_bgr = img[cy, cx]
b, g, r = int(pixel_center_bgr[0]), int(pixel_center_bgr[1]), int(pixel_center_bgr[2])
cv2.rectangle(img, (cx - 260, 10), (cx + 150, 70), (255, 255, 255), -1)
cv2.putText(img, 'R:'+str(r)+', G:'+str(g)+', B:'+str(b), (cx - 220, 50), 0, 1, (b, g, r), 4)
cv2.circle(img, (cx, cy), 5, (25, 25, 25), 3)
frame = cv2.imencode('.jpg', img)[1].tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
key = cv2.waitKey(1)
if key == 27:
break
@app.route('/video_feed')
def video_feed():
# Video streaming route. Put this in the src attribute of an img tag
return Response(rgb_detection(), mimetype='multipart/x-mixed-replace; boundary=frame')
# a generator with yield expression
def rgb_event_data():
while True:
time.sleep(0.3)
_data = json.dumps({"red": r, "green": g, "blue": b})
# DO NOT forget the prefix and suffix
yield f"id: 1\ndata: {_data}\nevent: online\n\n"
@app.route('/sse_rgb')
def sse_rgb():
return Response(
rgb_event_data(), mimetype='text/event-stream' # mark as a stream response
)
if __name__ == "__main__":
app.run(host='127.0.0.1', port=5000, debug=True)
Klik icon Play atau icon Debug pada Pycharm IDE untuk menjalankan aplikasi.
Setelah icon diklik dan jika tidak ada error, maka pada jendela console akan tampil url untuk menjalankan aplikasi di web browser.
Berikut tampilan OpenCV Color Detection Web Application:
2. Upload node-pixel Firmata ke Arudino Uno
Untuk cara upload node-pixel Firmata bisa dilihat di laman github-nya ajfisher yaitu https://github.com/ajfisher/node-pixel
3. Membuat Runtime Environment EventSource Client Menggunakan node.js
Langkah-langkahnya adalah sebagai berikut:
- Buat folder project di direktori yang anda inginkan.
- Install Johnny-Five, node-pixel dan eventSource Melalui Node Package Manager (npm)
- Edit File Javascript index.js
Di tutorial ini saya membuat folder j5_sse_client di dalam folder E:\triyonos\
Klik kanan file index.js kemudian Edit with Notepad++. Copy paste kode javascript di bawah ini:
const pixel = require("node-pixel");
var EventSource = require('eventsource')
var eventSource = new EventSource("http://127.0.0.1:5000/sse_rgb")
const {Board} = require("johnny-five");
const board = new Board({ port: "COM11" });
var strip = null;
board.on("ready", function() {
strip = new pixel.Strip({
board: this,
controller: "FIRMATA",
strips: [ {pin: 7, length: 12}, ],
gamma: 2.8,
});
eventSource.addEventListener("online", function(e) {
console.log(e.data)
var jsonObject = JSON.parse(e.data.toString());
var red = jsonObject.red;
var green = jsonObject.green;
var blue = jsonObject.blue;
for (var i = 0; i < strip.length; i++) {
strip.pixel( i ).color( [red, green, blue] );
}
strip.show();
}, true)
});
4. Rangkaian Arduino Uno & LED Strip WS2812
Setelah Arduino Uno diupload program Firmata seperti pada tahapan nomor 2, hubungkan pin-pin LED strip ke pin-pin Arduino Uno seperti pada wiring diagram berikut ini: