Tutorial kali ini sangatlah menarik karena akan membahas tentang komunikasi antara 2 bahasa pemrograman yang sedang populer saat ini yaitu Python dan javascript yang masing-masing berperan sebagai Server dan Client. Keduanya akan berkomunikasi melalui WebSocket menggunakan library Socket.IO.
Dari sisi server saya menggunakan Pycharm sebagai IDE untuk menginstal package-package seperti Flask, OpenCV, MediaPipe dan SocketIO untuk membuat aplikasi finger tracking melalui web cam dan membaca jarak bentangan jari antara ibu jari dan jari telunjuk. Jarak bentangan jari ini yang akan diterima oleh client untuk mengontrol banyaknya lampu LED yang akan menyala pada lampu Addressable LED Strip WS2812 melalui microcontroller Arduino UNO.
Untuk tugas client tersebut saya menggunakan platform node.js untuk menginstal Johnny-five, node-pixel dan SocketIO-client melalui npm (Noce Package Manager).
Langkah-langkah Pembuatan Project
Aplikasi Sisi Server
-
Create New Project
Buka Pycharm IDE kemudian Create New Project dengan nama FlaskSocketio_Ledstrip.
-
Install Packages
Package-package yang harus diinstal antara lain:
- Flask
- opencv-python
- MediaPipe
- flask-socketio
-
Download & Extract File-file Pendukung
Silakan klik link fingerGestureWs2812_files.zip ini untuk mendownloadnya. Kemudian exctract ke dalam root folder project.
-
Buat File app.py
from flask import Flask, render_template, Response from flask_socketio import SocketIO, send, emit import cv2 import HandTrackingModule as htm import math app = Flask(__name__) app.config['SECRET_KEY'] = 'mysecret' socketio = SocketIO(app, cors_allowed_origins="*") def handTracking(): # generate frame by frame from camera wCam, hCam = 500, 300 cap = cv2.VideoCapture(0) cap.set(3, wCam) cap.set(4, hCam) detector = htm.handDetector(detectionCon=0.7) while True: success, img = cap.read() img = detector.findHands(img) lmList = detector.findPosition(img, draw=False) if len(lmList) != 0: x1, y1 = lmList[4][1], lmList[4][2] x2, y2 = lmList[8][1], lmList[8][2] cv2.circle(img, (x1,y1), 15, (255,0,255), cv2.FILLED ) cv2.circle(img, (x2,y2), 15, (255, 0, 255), cv2.FILLED) cv2.line(img, (x1,y1), (x2,y2), (255,0,255), 3) length = math.hypot(x2-x1, y2-y1) # print(length) if 50.0 < length < 220.0: w = ((length - 50.0) / 170) * 20.0 elif length >= 220.0: w = 20.0 else: w = 0 socketio.send(str(int(w)), broadcast=True) 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') 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(handTracking(), mimetype='multipart/x-mixed-replace; boundary=frame') @app.route('/') def index(): """Video streaming home page.""" return render_template('index.html') if __name__ == '__main__': # app.run(debug=True) # host = your IP Address app.run(host='192.168.0.111', port=5000, debug=True) socketio.run(app)
Aplikasi Sisi Client
Buat folder baru di direktori manapun sebagai folder kerja untuk project ini dengan nama socketio_client, saya akan membuatnya di direktori E:\triyonos\
Seteleh itu buka Windows command prompt dan arahkan ke directory yang baru saja dibuat.
Setelah itu lakukan langkah-langkah berikut:
- Upload sketch firmata neo-pixel dari ajfisher ke Arduino UNO.
-
Install Packages Melalui npm
Package-package yang harus diinstal antara lain:
- johnny-five
- node-pixel
- socket.io-client
-
Buat file javascript baru di dalam root direktori dengan nama client.js
Copy paste script javascript di bawah ini:
const pixel = require("node-pixel"); const io = require('socket.io-client'); const socket = io.connect('http://192.168.0.111:5000', {reconnect: true}); // your IP Address const {Board} = require("johnny-five"); const board = new Board({ port: "COM10" }); var strip = null; board.on("ready", function() { strip = new pixel.Strip({ board: this, controller: "FIRMATA", strips: [ {pin: 6, length: 20}, ], gamma: 0.8, }); // Add a connect listener socket.on('connect', function (socket) { console.log('Connected!'); }); socket.on('message', function (msg) { console.log(msg); strip.color("black"); let leds = Number(msg); for(let i = 0; i < leds; i++) { strip.pixel( i ).color("yellow"); } strip.show(); }); });