Assalamualaikum, jumpa lagi di triyonos.com dengan tutorial implementasi pemrograman menarik berikutnya.

Tutorial kali ini merupakan kelanjutan dari 2 tutorial sebelumnya, yaitu:

  1. Mengukur Kelembaban dengan Arduino Uno & DHT22 I2C Nano Backpack (Johnny Five Node.js)
  2. Komunikasi CodeIgniter 4 dan Arduino Menggunakan cURL dan REPL Johnny-Five Node.js

Jadi, bagi anda yang ingin mempraktikkan tutorial ini, harap membaca tutorial di atas dan juga menonton video youtube-nya terlebih dahulu agar bisa mengikuti tutorial ini dengan baik.

Pada tutorial ini, data hasil pengukuran kelembaban dari sensor DHT22 pada tutorial nomor 1 akan saya visualisasikan ke dalam grafik atau chart di halaman web yang sudah saya buat sebelumnya pada tutorial nomor 2, dengan menambahkan modul baru dan menginstal plugins jQuery Highcharts.

Pembahasan mengenai plotting data ke dalam chart pernah saya buat juga pada tutorial Plot Serial Print Arduino ke Dalam Chart.js Menggunakan Socket.IO Node.js. Di situ saya menggunakan teknologi websocket untuk mentransfer data dari Arduino ke halaman web, sedangkan front end-nya menggunakan express.js dan plugins chart.js dalam platform Node.js

Di tutorial ini saya menggunakan teknologi AJAX polling untuk mentransfer data kelembaban dari sensor DHT22 ke halaman web. Secara teknologi websocket tentu lebih mutakhir ketimbang AJAX, namun di sini saya sajikan tutorial ini sebagai teknologi alternatif dalam pentransferan data.
Proses kerja dari sistem adalah sebagai berikut:

  1. Arduino mengirim data kelembaban dan disimpan ke dalam database MySQL di server localhost melalui node.js application secara berkala.
  2. CodeIgniter merequest data kelembaban ke localhost server, kemudian respon dari server ditampilkan ke dalam chart

understanding ajax call

Sumber : https://systemoutofmemory.com/blogs/the-programmer-blog/javascript-understanding-ajax-calls

Berikut tampilan halaman web dari CodeIgniter 4 dan Highcharts.js

codeigniter 4 highcharts.js ajax node.js

Langkah-langkah yang Harus Ditempuh

A. Membuat Tabel humidity

Buat tabel baru dengan nama tabel humidity di database MySQL melalui phpMyAdmin. Saya akan buat tabel humidity di database flask_db yang pernah saya buat pada tutorial Pycharm Flask OpenCV Registrasi Face Recognition Menggunakan Database MySQL.

home page face recognition

Klik Tab SQL untuk menampilkan SQL Editor, kemudian copy perintah SQL di bawah ini:

CREATE TABLE `humidity` (
	`id` varchar(14) NOT NULL,
	`value` decimal(5,2) NOT NULL,
	`added` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

            

Klik Tab SQL untuk menampilkan SQL Editor, kemudian paste, kemudian klik tombol Go.

home page face recognition

B. Modifikasi File dht22.js Pada Project Measuring Humidity

Modifikasi yang akan dilakukan berupa function insert data ke database MySQL, oleh karena itu perlu menginstall package mysql terlebih dahulu ke dalam project melalui Node Package Manager (npm).

Buka windows command prompt dan arahkan ke root folder project j5_dht22.

johnny-five backpack

Ketik npm install mysql kemudian Enter.

home page face recognition

Buka file dht22.js pada project directory j5_dht22 yang sudah saya buat pada tutorial Mengukur Kelembaban dengan Arduino Uno & DHT22 I2C Nano Backpack (Johnny Five Node.js) melalui Notepad++ .

johnny-five backpack

Edit file tersebut dengan menghapus semua script, kemudian copy paste script javascript di bawah ini:

var five = require("johnny-five");
var mysql = require('mysql');
var board = new five.Board({ port: "COM5" });
var i = 0;

var con = mysql.createConnection({
	host: "localhost",
	user: "root",
	password: "p@s5w0rd",
	database: "flask_db"
});
 
board.on("ready", function() {
	var hygrometer = new five.Hygrometer({
		controller: "DHT22_I2C_NANO_BACKPACK"
	});
	
	con.connect(function(err) {
		if (err) throw err;
		console.log("Database Connected");
	});
 
	hygrometer.on("change", function() {
		if (parseFloat(this.relativeHumidity) > 0) {
			
			if (i == 10) {
				var today = new Date();
				var yyyymmdd = String(today.getFullYear()) + String(today.getMonth()+1).padStart(2, '0') + String(today.getDate()).padStart(2, '0');
				var hhiiss   = String(today.getHours()).padStart(2, '0') + String(today.getMinutes()+1).padStart(2, '0') + String(today.getSeconds()).padStart(2, '0');
				
				console.log("  relative humidity : ", this.relativeHumidity);
				console.log("--------------------------------------");
				
				var sql = "INSERT INTO humidity (id, value) VALUES ('"+yyyymmdd+hhiiss+"', "+this.relativeHumidity+")";
				con.query(sql, function (err, result) {
					if (err) throw err;
					console.log("1 record inserted");
				});

				i = 0;
			}
			
			i++;
		}
	});
	
});

			

C. Modifikasi Project CodeIgniter 4 ci4j5

Buka kembali project CodeIgniter 4 pada tutorial Komunikasi CodeIgniter 4 dan Arduino Menggunakan cURL dan REPL Johnny-Five Node.js yaitu folder ci4j5 melalui Visual Studio Code.

Edit file Database.php dan Routes.php pada folder App/Config

  • Edit file Config Routes.php, set default Controller ke Humidity
  • config routes.php
  • Edit file Config Database.php, assign username, password dan database
  • config database.php

Membuat File Controller, Model dan View untuk Humidity

Tambahkan file Humidity.php, Humidity_model.php dan v_humidity.php seperti pada gambar berikut:

mvc humidity files

  • File Controller Humidity.php
    <?php
    namespace App\Controllers;
    use App\Models\Humidity_model;
    use Config\Services;
    
    class Humidity extends BaseController
    {
        protected $M_humidity;
        protected $request;
    
        public function __construct() {
    		date_default_timezone_set('Asia/Jakarta');
    		$this->request = Services::request();
    		$this->M_humidity = new Humidity_model($this->request);
    	}
    
        public function index() {
            $data ['title']  = "DHT22 | Hygrometer";
    
            return view('v_humidity', $data);
        }
    
        public function getHumidityData() {
            $cek = $this->M_humidity->get_humidity_data(date('Y-m-d H:i'));
    
            $data = [
    		    'humid_time' => date('H:i:s'),
    		    'humid_data' => $cek->humid_val
    		];
    	
    		echo json_encode($data);
        }
    }
    
    						
  • File Model Humidity_model.php
    <?php
    
    namespace App\Models;
    
    use CodeIgniter\HTTP\RequestInterface;
    use CodeIgniter\Model;
    
    class Humidity_model extends Model
    {
        Protected $db;
    
        function __construct(RequestInterface $request) {
            parent::__construct();
            $this->db = db_connect();
            $this->request = $request;
        }
    
        function get_humidity_data($dt_tm) {
            $sql = "delete from humidity
                     where added < concat('".$dt_tm."', ':00')";
            $query = $this->db->query($sql);
            
    
            $sql = "select ifnull(max(h.value), 0) as humid_val
                      from humidity h
                     where h.added >= concat('".$dt_tm."', ':00') ";
            $data = $this->db->query($sql); 
    
            return $data->getRow();
        }
    }
    
    						
  • File View v_humidity.php
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Welcome to CodeIgniter 4!</title>
    	<meta name="description" content="The small framework with powerful features">
    	<meta name="viewport" content="width=device-width, initial-scale=1.0">
    	<link rel="shortcut icon" type="image/png" href="/favicon.ico"/>
    
    	<!-- STYLES -->
    
    	<style {csp-style-nonce}>
    		* {
    			transition: background-color 300ms ease, color 300ms ease;
    		}
    		*:focus {
    			background-color: rgba(221, 72, 20, .2);
    			outline: none;
    		}
    		html, body {
    			color: rgba(33, 37, 41, 1);
    			font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
    			font-size: 16px;
    			margin: 0;
    			padding: 0;
    			-webkit-font-smoothing: antialiased;
    			-moz-osx-font-smoothing: grayscale;
    			text-rendering: optimizeLegibility;
    		}
    		header {
    			background-color: rgba(247, 248, 249, 1);
    			padding: .4rem 0 0;
    		}
    		.menu {
    			padding: .4rem 2rem;
    		}
    		header ul {
    			border-bottom: 1px solid rgba(242, 242, 242, 1);
    			list-style-type: none;
    			margin: 0;
    			overflow: hidden;
    			padding: 0;
    			text-align: right;
    		}
    		header li {
    			display: inline-block;
    		}
    		header li a {
    			border-radius: 5px;
    			color: rgba(0, 0, 0, .5);
    			display: block;
    			height: 44px;
    			text-decoration: none;
    		}
    		header li.menu-item a {
    			border-radius: 5px;
    			margin: 5px 0;
    			height: 38px;
    			line-height: 36px;
    			padding: .4rem .65rem;
    			text-align: center;
    		}
    		header li.menu-item a:hover,
    		header li.menu-item a:focus {
    			background-color: rgba(221, 72, 20, .2);
    			color: rgba(221, 72, 20, 1);
    		}
    		header .logo {
    			float: left;
    			height: 44px;
    			padding: .4rem .5rem;
    		}
    		header .menu-toggle {
    			display: none;
    			float: right;
    			font-size: 2rem;
    			font-weight: bold;
    		}
    		header .menu-toggle button {
    			background-color: rgba(221, 72, 20, .6);
    			border: none;
    			border-radius: 3px;
    			color: rgba(255, 255, 255, 1);
    			cursor: pointer;
    			font: inherit;
    			font-size: 1.3rem;
    			height: 36px;
    			padding: 0;
    			margin: 11px 0;
    			overflow: visible;
    			width: 40px;
    		}
    		header .menu-toggle button:hover,
    		header .menu-toggle button:focus {
    			background-color: rgba(221, 72, 20, .8);
    			color: rgba(255, 255, 255, .8);
    		}
    		header .heroe {
    			margin: 0 auto;
    			max-width: 1100px;
    			padding: 1rem 1.75rem 1.75rem 1.75rem;
    		}
    		header .heroe h1 {
    			font-size: 2.5rem;
    			font-weight: 500;
    		}
    		header .heroe h2 {
    			font-size: 1.5rem;
    			font-weight: 300;
    		}
    		section {
    			margin: 0 auto;
    			max-width: 1100px;
    			padding: 2.5rem 1.75rem 3.5rem 1.75rem;
    		}
    		section h1 {
    			margin-bottom: 2.5rem;
    		}
    		section h2 {
    			font-size: 120%;
    			line-height: 2.5rem;
    			padding-top: 1.5rem;
    		}
    		section pre {
    			background-color: rgba(247, 248, 249, 1);
    			border: 1px solid rgba(242, 242, 242, 1);
    			display: block;
    			font-size: .9rem;
    			margin: 2rem 0;
    			padding: 1rem 1.5rem;
    			white-space: pre-wrap;
    			word-break: break-all;
    		}
    		section code {
    			display: block;
    		}
    		section a {
    			color: rgba(221, 72, 20, 1);
    		}
    		section svg {
    			margin-bottom: -5px;
    			margin-right: 5px;
    			width: 25px;
    		}
    		.further {
    			background-color: rgba(247, 248, 249, 1);
    			border-bottom: 1px solid rgba(242, 242, 242, 1);
    			border-top: 1px solid rgba(242, 242, 242, 1);
    		}
    		.further h2:first-of-type {
    			padding-top: 0;
    		}
    		footer {
    			background-color: rgba(221, 72, 20, .8);
    			text-align: center;
    		}
    		footer .environment {
    			color: rgba(255, 255, 255, 1);
    			padding: 2rem 1.75rem;
    		}
    		footer .copyrights {
    			background-color: rgba(62, 62, 62, 1);
    			color: rgba(200, 200, 200, 1);
    			padding: .25rem 1.75rem;
    		}
    		@media (max-width: 629px) {
    			header ul {
    				padding: 0;
    			}
    			header .menu-toggle {
    				padding: 0 1rem;
    			}
    			header .menu-item {
    				background-color: rgba(244, 245, 246, 1);
    				border-top: 1px solid rgba(242, 242, 242, 1);
    				margin: 0 15px;
    				width: calc(100% - 30px);
    			}
    			header .menu-toggle {
    				display: block;
    			}
    			header .hidden {
    				display: none;
    			}
    			header li.menu-item a {
    				background-color: rgba(221, 72, 20, .1);
    			}
    			header li.menu-item a:hover,
    			header li.menu-item a:focus {
    				background-color: rgba(221, 72, 20, .7);
    				color: rgba(255, 255, 255, .8);
    			}
    		}
    	</style>
    </head>
    <body>
    
    <!-- HEADER: MENU + HEROE SECTION -->
    <header>
    	<div class="menu">
    		<ul>
    			<li class="logo"><a href="https://codeigniter.com" target="_blank"><img height="44" title="CodeIgniter Logo"
    																					alt="Visit CodeIgniter.com official website!"
    																					src="data:image/png;base64,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"></a>
    			</li>
    			<li class="menu-toggle">
    				<button onclick="toggleMenu();">☰</button>
    			</li>
    			<li class="menu-item hidden"><a href="#">Home</a></li>
    			<li class="menu-item hidden"><a href="https://codeigniter4.github.io/userguide/" target="_blank">Docs</a>
    			</li>
    			<li class="menu-item hidden"><a href="https://forum.codeigniter.com/" target="_blank">Community</a></li>
    			<li class="menu-item hidden"><a
    					href="https://github.com/codeigniter4/CodeIgniter4/blob/develop/CONTRIBUTING.md" target="_blank">Contribute</a>
    			</li>
    		</ul>
    	</div>
    
    	<div class="heroe">
    		<h1>CodeIgniter 4 & DHT22 I2C Nano Backpack</h1>
    		<div id="chartHumid" style="width:100%; height:400px;"></div>
    	</div>
    </header>
        
    <!-- FOOTER: DEBUG INFO + COPYRIGHTS -->
    <footer>
    	<div class="environment">
    		<p>Page rendered in 0.0508 seconds</p>
    		<p>Environment: <?= ENVIRONMENT ?></p>
    	</div>
    
    	<div class="copyrights">
    		<p>© <?= date('Y') ?> CodeIgniter Foundation. CodeIgniter is open source project released under the MIT
    			open source licence.</p>
    	</div>
    
    </footer>
    
    <!-- SCRIPTS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script>
    	$(document).ready(function() {
    		getHumidData();
    
    		setInterval(getHumidData, 10000);
    
    		var myChart = new Highcharts.Chart({
                chart:{ 
    				renderTo : 'chartHumid', 
    				spacingTop: 30 
    			},
                title: { text: 'Highcharts DHT22 Humidity Chart' },
                series: [{
                    showInLegend: false,
                    data: []
                }],
                plotOptions: {
                    line: { animation: false,
                        dataLabels: { enabled: true }
                    },
                    series: { color: "blue" }
                },
                xAxis: {
                    type: 'category',
                    title: { text: 'Time' }
                },
                yAxis: {
                    title: { text: 'Humidity value' }
                },
                credits: { enabled: false }
            });
    
    		function getHumidData() {
    			$.ajax({
    				url : "Humidity/getHumidityData/",
    				type: "GET",
    				dataType: "JSON", 
    				success: function(data) {
    					// console.log(data.humid_data);
    
    					var x = data.humid_time,
    						y = parseFloat(data.humid_data);
    
    					if (y > 0) {
    						if(myChart.series[0].data.length > 16) {
    							myChart.series[0].addPoint([x, y], true, true, true);
    						} else {
    							myChart.series[0].addPoint([x, y], true, false, true);
    						}
    					}
    				}        
    			});
    		}
    	});
    
    	function toggleMenu() {
    		var menuItems = document.getElementsByClassName('menu-item');
    		for (var i = 0; i < menuItems.length; i++) {
    			var menuItem = menuItems[i];
    			menuItem.classList.toggle("hidden");
    		}
    	}
    </script>
    
    <!-- -->
    
    </body>
    </html>
    
    
    
    						

D. Running node dht22.js & Running php spark serve



Untuk lebih jelasnya silakan tonton video dari channel youtube Kode Erik di bawah ini. Kalau ada pertanyaan silakan komen di youtube dan jangan lupa subscribe: