ESP32 Challenge #11: Plotting Sensor Reading
Selamat datang di challenge ke-11! Jadi, kita bakal ditantang apa nih kali ini? Ikutin terus ya!
Sebelumnya, kita telah menampilkan hasil pembacaan sensor BMP280 ke dalam database MySQL. Challenge kali ini kita akan membuat web page yang menampilkan plot kurva pembacaan sensor. Pastinya bakal keren banget!
—
DAFTAR KOMPONEN DAN PERANGKAT
Silahkan kalian siapkan komponen dan perangkat berikut:
- ESP32 Development Board (disini aku menggunakan ESP32 DOIT DEVKIT V1)
- Breadboard
- Sensor BMP280
- Kabel male to male (bisa disesuaikan)
- Micro USB Cable
- Laptop/komputer yang terdapat aplikasi Arduino IDE (sudah terinstall package board ESP32)
- Wi-Fi
- Hosting server and domain name
- PHP Application
- MySQL Database
Komponennya masih sama seperti challenge sebelumnya, kok!
—
DIAGRAM SKEMA
Untuk skemanya sendiri juga masih sama seperti pada challenge sebelumnya!
GPIO 22 (D22) terhubung dengan SCL sensor BMP 280, GPIO 21 (D21) terhubung dengan SDA sensor BMP 280, 3V3 terhubung dengan VCC sensor BMP 280, dan GND ESP32 terhubung dengan GND sensor BMP 280, serta Micro USB Cable digunakan untuk menghubungkan ESP32 Development Board dengan komputer/laptop kalian!
—
EKSPERIMEN DAN DEMO
Nah, disini aku masih menggunakan 000webhost.com sebagai hosting server. Untuk site yang aku gunakan masih menggunakan site pada challenge sebelumnya, kok! Oke, kita langsung aja ke langkah2nya!
- Di bagian samping kiri, pilih Tool > Database Manager. Akan muncul halaman seperti pada gambar berikut.
2. Kemudian, kita akan membuat database baru dengan cara pilih New Database. Lalu isikan database name, username, dan password, silahkan disesuaikan ya!
Jangan lupa untuk mencatat database name, username, dan password karena akan digunakan pada langkah-langkah selanjutnya.
3. Klik Manage > PhpMyAdmin dan kalian akan menuju ke halaman phpMyAdmin.
5. Setelah itu, kalian akan diminta log in phpMyAdmin, silahkan isikan user DB dan password yang telah kalian catat sebelumnya. Kemudian, kita akan membuat tabel dengan nama Sensor. Atribut-atribut tabel tersebut adalah id dengan tipe integer, value1 dengan tipe VARCHAR(10), value2 dengan tipe VARCHAR(10), value3 dengan tipe VARCHAR(10), dan reading_time dengan tipe TIMESTAMP. Berikut adalah syntax yang digunakan.
CREATE TABLE Sensor (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
value1 VARCHAR(10),
value2 VARCHAR(10),
value3 VARCHAR(10),
reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
Setelah itu, klik tombol Go.
Jika berhasil maka akan terdapat tabel dengan nama Sensor dan atribut-atribut id, value1, value2, value3, dan reading_time.
6. Lalu, kembali pada halaman 000webhost.com dan pilih File Manager pada pilihan menu disebelah kiri. Pilih Upload Files.
7. Kalian akan menuju ke halaman seperti pada gambar berikut. Lalu, buka folder public_html.
8. Pilih tombol New File untuk membuat file baru dengan nama index.php.
Silahkan masukkan kode program berikut:
<?php
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/$servername = "localhost";// REPLACE with your Database name
$dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
// REPLACE with Database user
$username = "REPLACE_WITH_YOUR_USERNAME";
// REPLACE with Database user password
$password = "REPLACE_WITH_YOUR_PASSWORD";// Keep this API Key value to be compatible with the ESP32 code provided in the project page. If you change this value, the ESP32 sketch needs to match
$api_key_value = "tPmAT5Ab3j7F9";$api_key = $value1 = $value2 = $value3 = "";if ($_SERVER["REQUEST_METHOD"] == "POST") {
$api_key = test_input($_POST["api_key"]);
if($api_key == $api_key_value) {
$value1 = test_input($_POST["value1"]);
$value2 = test_input($_POST["value2"]);
$value3 = test_input($_POST["value3"]);
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO Sensor (value1, value2, value3)
VALUES ('" . $value1 . "', '" . $value2 . "', '" . $value3 . "')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
}
else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
}
else {
echo "Wrong API Key provided.";
}}
else {
echo "No data posted with HTTP POST.";
}function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
Jangan lupa untuk mengganti database name, username, dan password sesuai dengan database yang kalian buat sebelumnya.
// REPLACE with your Database name
$dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
// REPLACE with Database user
$username = "REPLACE_WITH_YOUR_USERNAME";
// REPLACE with Database user password
$password = "REPLACE_WITH_YOUR_PASSWORD";
9. Jika kalian mencoba membuka domain name kalian seperti contoh berikut.
https://projectseitb.000webhostapp.com/index.php
Akan muncul pesan seperti gambar berikut.
Jika kalian lupa cara mengecek website name kalian, pada bagian menu kiri 000webhost.com, silahkan buka Website Settings > General, akan muncul website name yang kalian miliki!
10. Kemudian, pada file manager tambahkan kembali file esp-chart.php
Kode program yang digunakan sebagai berikut.
<!--
Rui Santos
Complete project details at https://RandomNerdTutorials.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.-->
<?php$servername = "localhost";// REPLACE with your Database name
$dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
// REPLACE with Database user
$username = "REPLACE_WITH_YOUR_USERNAME";
// REPLACE with Database user password
$password = "REPLACE_WITH_YOUR_PASSWORD";// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}$sql = "SELECT id, value1, value2, value3, reading_time FROM Sensor order by reading_time desc limit 40";$result = $conn->query($sql);while ($data = $result->fetch_assoc()){
$sensor_data[] = $data;
}$readings_time = array_column($sensor_data, 'reading_time');// ******* Uncomment to convert readings time array to your timezone ********
// $i = 0;
// foreach ($readings_time as $reading){
// Uncomment to set timezone to - 1 hour (you can change 1 to any number)
// $readings_time[$i] = date("Y-m-d H:i:s", strtotime("$reading - 1 hours"));
// Uncomment to set timezone to + 4 hours (you can change 4 to any number)
//$readings_time[$i] = date("Y-m-d H:i:s", strtotime("$reading + 4 hours"));
// $i += 1;
// }$value1 = json_encode(array_reverse(array_column($sensor_data, 'value1')), JSON_NUMERIC_CHECK);
$value2 = json_encode(array_reverse(array_column($sensor_data, 'value2')), JSON_NUMERIC_CHECK);
$value3 = json_encode(array_reverse(array_column($sensor_data, 'value3')), JSON_NUMERIC_CHECK);
$reading_time = json_encode(array_reverse($readings_time), JSON_NUMERIC_CHECK);/*echo $value1;
echo $value2;
echo $value3;
echo $reading_time;*/$result->free();
$conn->close();
?><!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.highcharts.com/highcharts.js"></script>
<style>
body {
min-width: 310px;
max-width: 1280px;
height: 500px;
margin: 0 auto;
}
h2 {
font-family: Arial;
font-size: 2.5rem;
text-align: center;
}
</style>
<body>
<h2>ESP Weather Station</h2>
<div id="chart-temperature" class="container"></div>
<div id="chart-altitude" class="container"></div>
<div id="chart-pressure" class="container"></div>
<script>var value1 = <?php echo $value1; ?>;
var value2 = <?php echo $value2; ?>;
var value3 = <?php echo $value3; ?>;
var reading_time = <?php echo $reading_time; ?>;var chartT = new Highcharts.Chart({
chart:{ renderTo : 'chart-temperature' },
title: { text: 'BMP280 Temperature' },
series: [{
showInLegend: false,
data: value1
}],
plotOptions: {
line: { animation: false,
dataLabels: { enabled: true }
},
series: { color: '#059e8a' }
},
xAxis: {
type: 'datetime',
categories: reading_time
},
yAxis: {
title: { text: 'Temperature (Celsius)' }
//title: { text: 'Temperature (Fahrenheit)' }
},
credits: { enabled: false }
});var chartA = new Highcharts.Chart({
chart:{ renderTo:'chart-altitude' },
title: { text: 'BMP280 Altitude' },
series: [{
showInLegend: false,
data: value2
}],
plotOptions: {
line: { animation: false,
dataLabels: { enabled: true }
}
},
xAxis: {
type: 'datetime',
//dateTimeLabelFormats: { second: '%H:%M:%S' },
categories: reading_time
},
yAxis: {
title: { text: 'Altitude (m)' }
},
credits: { enabled: false }
});var chartP = new Highcharts.Chart({
chart:{ renderTo:'chart-pressure' },
title: { text: 'BMP280 Pressure' },
series: [{
showInLegend: false,
data: value3
}],
plotOptions: {
line: { animation: false,
dataLabels: { enabled: true }
},
series: { color: '#18009c' }
},
xAxis: {
type: 'datetime',
categories: reading_time
},
yAxis: {
title: { text: 'Pressure (hPa)' }
},
credits: { enabled: false }
});</script>
</body>
</html>
Jangan lupa untuk mengganti database name, username, dan password sesuai dengan database yang kalian buat sebelumnya.
// REPLACE with your Database name
$dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
// REPLACE with Database user
$username = "REPLACE_WITH_YOUR_USERNAME";
// REPLACE with Database user password
$password = "REPLACE_WITH_YOUR_PASSWORD";
11. Jika kalian mencoba membuka domain name kalian seperti berikut.
https://projectseitb.000webhostapp.com/esp-chart.php
Akan muncul seperti berikut.
12. Setelah itu, silahkan buka aplikasi Arduino IDE, dan masukkan kode program berikut.
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.*/#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://example.com/index.php";// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "tPmAT5Ab3j7F9";String sensorName = "BMP280";
String sensorLocation = "Office";#define SEALEVELPRESSURE_HPA (1013.25)Adafruit_BMP280 bmp; // I2Cvoid setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());// (you can also pass in a Wire library object like &Wire2)
bool status = bmp.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BMP280 sensor, check wiring or change I2C address!");
while (1);
}
}void loop() {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare your HTTP POST request data
String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
+ "&location=" + sensorLocation + "&value1=" + String(bmp.readTemperature())
+ "&value2=" + String(bmp.readAltitude(SEALEVELPRESSURE_HPA)) + "&value3=" + String(bmp.readPressure()/100.0F) + "";
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);
// You can comment the httpRequestData variable above
// then, use the httpRequestData variable below (for testing purposes without the BMP280 sensor)
//String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BMP280&location=Office&value1=24.75&value2=49.54&value3=1005.14";// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
// If you need an HTTP request with a content type: text/plain
//http.addHeader("Content-Type", "text/plain");
//int httpResponseCode = http.POST("Hello, World!");
// If you need an HTTP request with a content type: application/json, use the following:
//http.addHeader("Content-Type", "application/json");
//int httpResponseCode = http.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
//Send an HTTP POST request every 30 seconds
delay(30000);
}
Keterangan program:
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
Seperti biasa pada awal program kita harus mengimpor semua library yang ingin kita gunakan.
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Jangan lupa mengganti SSID dan password sesuai dengan nama WiFi dan password WiFi kalian yaa!
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://example.com/index.php";
Silahkan sesuaikan link serverName dengan website name kalian juga yaa.
String apiKeyValue = "tPmAT5Ab3j7F9";
Setelah itu, kita set apiKeyValue. Nah, apiKeyValue adalah sebuah String random yang bisa kalian modifikasi, tetapi kalian juga harus menyamakan dengan $api_key_value pada index.php. Fungsinya adalah untuk alasan keamanan, jika memiliki API Key maka dapat mempublikasikan data ke database kalian.
Serial.begin(115200);
Lalu, pada bagian setup, akan dilakukan inisialisasi komunikasi serial dengan kecepatan 115200 baud.
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Akan dicek apakah WiFi sudah connect atau belum, jika sudah maka akan ditampilkan pesan Connected to WiFi network with IP Address: beserta IP Address-nya.
bool status = bmp.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BMP280 sensor, check wiring or change I2C address!");
while (1);
}
Selain itu, akan dicek apakah sensor dapat terbaca, jika tidak maka akan ditampilkan error message.
Kemudian, pada bagian loop, akan dicek WiFi connection status, jika sudah terhubung maka kita akan membuat HTTP POST request setiap 30 detik dengan hasil pembacaan temperatur, ketinggian dan tekanan sensor BMP 280 terbaru.
13. Oke, semuanya sudah siap! Silahkan klik verify dan compile pada aplikasi Arduino IDE kalian.
14. Lalu buka Tools > Serial Monitor. Jika Serial Monitor tidak menampilkan apa-apa, silahkan tekan tombol EN pada ESP32 Development Board.
15. Jika sudah terhubung, akan muncul HTTP Response code: 200.
16. Setelah itu, silahkan cek https://example.com/esp-chart.php
Taraa! Kalian bisa melihat hasil pembacaan sensor BMP280 kalian!
Nah, sensor BMP 280 akan terus membaca temperatur, ketinggian dan tekanan lalu menampilkannya dalam bentuk kurva pada link tersebut.
Nah, hasil pembacaan dalam bentuk kurva tersebut merupakan hasil pembacaan yang disimpan pada tabel Sensor database MySQL.
—
HASIL EKSPERIMEN DAN ANALISIS
Pada challenge kali ini, eksperimen dapat berjalan dengan lancar karena pengalaman mengotak-atik hosting server ini pada challenge sebelumnya dan langkah-langkahnya juga kurang lebih mirip. Perbedaan dengan challenge sebelumnya adalah pada challenge ini menggunakan chart sehingga hasil pembacaan sensor dapat ditampilkan dengan lebih menarik!
ESP32 Challenge kali ini adalah challenge terakhir yang diberikan. Selamat akhirnya kita bisa menyelesaikan semua challenge! Jangan berhenti bereksperimen dan sampai bertemu pada kesempatan selanjutnya!