Komunikasi dua arah Arduino dengan Web Browser menggunakan MySQL, XAMPP/web hosting dan ESP8266

Untuk komunikasi jarak jauh atau komunikasi tanpa kabel menggunakan Arduino bisa menggunakan ESP8266 (wifi shield) yang akan menghubungkan arduino ke internet/jaringan lokal. Disamping itu harus pula dibangun server yang berfungsi sebagai penyedia layanan sehingga sistem komunikasi bisa berjalan timbal balik. Dalam server juga dibutuhkan media untuk merekam komunikasi tersebut, salah satu yang populer adalah database MySQL. Ini adalah salah satu cara menghubungkan arduino dengan database yang paling efisien.

Menghubungkan MySQL – Arduino dibutuhkan bahasa php sebagai penerjemah query (bahasa database), baik permintaan (GET request) dari arduino – MySQL dan web browser – MySQL. Jika skema ini sudah terbangun maka kita bisa mengkomunikasikan arduino – web browser (lokal / internet).

Menyimpan data dari arduino ke mysql esp8266 bisa dilaksanakan dengan cara ini, data dari arduino ditransmisikan melalui jaringan wifi dan diterima oleh web server. Data tersebut kemudian di proses oleh php dan juka diizinkan maka data tersebut akan disimpan dalam database.

Mengirim perintah dari browser ke arduino dengan esp8266 juga dapat dilakukan dengan cara sebaliknya.

Webserver yang digunakan dalam perancangan ini adalah XAMPP di PC lokal dan jasa server hosting.

Langkah perancangannya sebagai berikut:

  1. Merangkai Arduino + ESP8266
  2. Membuat sketch Arduino untuk mengirim dan menerima data dari database
  3. Konfigurasi koneksi ESP8266 ke access point wifi (AP)
  4. Install XAMPP server dan mengaktifkannya
  5. Untuk web server hosting, membuat database, user account dan priveleged-nya
  6. Membuat program php, dariArduino.php, keArduino.php, dariBrowser.php serta program php pendukung.

Arduino + ESP8266

Rangkaian yang digunakan:

Diagram:

Untuk menghubungkan arduino dengan jaringan, salah satu yang bisa digunakan adalah modul wifi shiel ESP8266. kali ini saya menggunakan library “WiFiEsp.h”.

Catatan, untuk terhubung ke web hosting, pastikan wifi terhubung ke internet (bridge connection)

sebelum menggunakannya konfigurasi dahulu modul tersebut, editlah bagian berikut:


char ssid[] = "ArduinoMySQL";        // Isi dengan nama profil Wifi
char pass[] = "12345678";            // password wifi
//char server[] = "192.168.123.1";     // alamat access point yang 
char server[] = "semesin.com";     // alamat server hosting 

sketch atau program berikut memiliki fitur:

  1. Menerima masukan string/text dari serial monitor dan mengirimkannya ke webserver untuk disimpan ke database MySQL.
  2. Menerima data perintah dari webserver dalam jangka waktu tertentu contoh kali ini setiap 5 detik.

sketch atau program lengkapnya sebagai berikut:

#include "WiFiEsp.h"

char ssid[] = "ArduinoMySQL";        // Isi dengan nama profil Wifi
char pass[] = "12345678";            // password wifi
//char server[] = "192.168.123.1";     // alamat access point yang telah terinstall XAMPP local host
char server[] = "semesin.com";     // alamat web hosting

char namaVariabel[] = "Variabel";
String text = "";
String Respon = "";
bool responDariServer = false;

bool statusKomunikasiWifi = false;
long waktuMulai;
long waktuMintaData = 5000; //minta data setiap 5000ms

WiFiEspClient client;
int status = WL_IDLE_STATUS;

void setup()
{
  Serial.begin(9600);
  Serial.println("Koneksi arduino dengan mySql menggunakan ESp8266 dan XAMPP");
  Serial.println("Ketik pesan yang akan dikirim (pastikan setting serial ke \"both NL & CR\")");
  Serial.println("https://www.project.semesin.com");
  Serial.println();

  Serial1.begin(115200);
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  // you're connected now, so print out the data
  Serial.println("You're connected to the network");
  
  printWifiStatus();
  waktuMulai = millis();
}

void loop()
{
  //tunggu imputan nilai dari untuk dikirim ke server
  while(Serial.available())
  {
    char c = Serial.read();
    if((c != '\r') && (c != '\n'))
    {
      text += c;
    }
    if(c == '\n')
    {
      statusKomunikasiWifi = kirimKeDatabase("dataDariSerial",text);
      text = "";
      waktuMulai = millis();
    }
  }

  if(waktuMintaData < millis() - waktuMulai)
  {
    statusKomunikasiWifi = ambilDatabase("perintah");
    waktuMulai = millis();
  }
  
  // periksa respon dari server
  if(statusKomunikasiWifi)
  {
    // if there are incoming bytes available
    // from the server, read them and print them
    while (client.available()) 
    {
      char c = client.read();
      Respon += c;
    }
  
    // if the server's disconnected, stop the client
    if (!client.connected()) {
      Serial.println("Disconnecting from server...");
      client.stop();
      statusKomunikasiWifi = false;
      responDariServer = true;
    }
  }

  // penanganan data yang diretima dari server
  if(responDariServer)
  {
    responDariServer = false;
    //Serial.println(Respon);
    int posisiData = Respon.indexOf("\r\n\r\n");
    String Data = Respon.substring(posisiData+4);
    Data.trim();

    String variabel;
    String nilai;

    Serial.println("Data dari server");
    posisiData = Data.indexOf('=');
    if(posisiData > 0)
    {
      variabel = Data.substring(0,posisiData);
      nilai = Data.substring(posisiData+1);
  
      //===========Penanganan respon disini
      Serial.print(variabel);
      Serial.print(" = ");
      Serial.println(nilai);
    }
    Respon = "";
  }
}
bool ambilDatabase(String variabel)
{
  Serial.println();
  Serial.println("Starting connection to server...");
  // if you get a connection, report back via serial
  if (client.connect(server, 80)) {
    Serial.println("Connected to server");
    // Make a HTTP request
    client.print("GET /arduino_mysql/keArduino.php?variabel=");
    client.print(variabel);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();

    long _startMillis = millis();
    while (!client.available() and (millis() - _startMillis < 2000));

    return true;
  }
  return false;
}

bool kirimKeDatabase(String namaVariabel, String nilai)
{
  Serial.println();
  Serial.println("Starting connection to server...");
  // if you get a connection, report back via serial
  if (client.connect(server, 80)) {
    Serial.println("Connected to server");
    // Make a HTTP request

    // parameter 1
    client.print("GET /arduino_mysql/dariArduino.php?");
    client.print("variabel=");
    client.print(namaVariabel);
    
    // parameter 2 dan selanjutnya
    client.print("&");
    client.print("nilai=");
    client.print(nilai);
    
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();

    return true;
  }
  return false;
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

  IPAddress gateway = WiFi.gatewayIP();
  Serial.print("gateway:");
  Serial.print(gateway);
  Serial.println(" ");
}

tampilan serial monitor dari arduino:

 

XAMPP webserver + database MySQL

untuk membuat webserver di komputer lokal instal XAMPP (saya menggunakan v3.2.2) atau bundel webserver lain yang termasuk didalamnya MySQL.

untuk memulainya jalankan/aktifkan webserver dan MySQL

 

Web Hosting + Database MySQL

catatan: huruf besar/kecil berpengaruh (case-sensitif)

Server hosting umumnya memiliki fitur kemanan, untuk itu kita harus masuk ke cpanel kemudian membuat sebuah database dengan memilih menu ‘MySQL® Database Wizard‘ dan mengisi nama database, misalnya ‘arduino_mysql’.

selanjutnya ‘next step’ buatlah akun dengan memasukkan nama dan paswword (nama dan password ini akan dimasukkan ke ‘fungction.php’).

selanjutnya prilih privileges yang akan digunakan.

sebagai webserver dan database server yang akan berhubungan timbal balik dengan arduino, maka kita buat halaman web berbasis bahasa PHP dan memiliki fitur:

  1. Menerima data dari Arduino menggunakan metode ‘GET’ dengan parameter ‘variabel’, ‘nilai’, dan ‘status’.
  2. Menyimpan data dari entri data di webserver, dan akan mengirimkannya ke Arduino saat diminta.
  3. Menyedian halaman tampilan database ke halaman web.

fitur-fitur ini saya buatkan dalam beberapa program PHP, untuk menggunakannya extract file Arduino MySQL dan copy ke folder “/arduino_mysql” (untuk XAMPP root folder “C:\xampp\htdocs\arduino_mysql”, untuk web hosting “public_html/arduino_mysql”) dengan program berikut:

file php yang digunakan diuraikan disini:

function.php

sebelum menggunakan file ini edit dahulu bagian sesuai kebutuhan:

    $servername = "localhost";
    $username = "******_Arduino";
    $password = "Arduino";
    $database = "******_arduino_mysql";

kode lengkap function.php

  <?php

 function databaseConnect()
  {
    /* XAMPP
    $servername = "localhost";
    $username = "root";
    $password = "";
    $database = "arduino_mysql";
    */
    
    $servername = "localhost";
    $username = "******_Arduino";
    $password = "Arduino";
    $database = "******_arduino_mysql";
    
    // Create connection
    $conn = new mysqli($servername, $username, $password);

    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }
    echoDebug("Connected successfully<br>");
    
    // Create database
    $sql = "CREATE DATABASE IF NOT EXISTS ".$database;
    if ($conn->query($sql) === TRUE) {
      echoDebug("Database created successfully<br>");
    } else {
      echoDebug("Error creating database: " . $conn->error);
    }
    
    // Connect to database
    $conn = new mysqli($servername, $username, $password, $database);
    // Check connection
    if ($conn->connect_error) {
      die("Database connection failed: " . $conn->connect_error);
    }
    echoDebug("Database connected successfully<br>");
    
    // sql to create table
    $sql = "CREATE TABLE IF NOT EXISTS arduino_data (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    variabel VARCHAR(30) NOT NULL,
    nilai VARCHAR(30) NOT NULL
    )";
    
    if ($conn->query($sql) === TRUE) {
      echoDebug("Table arduino_data created successfully</br>");
    } else {
      echoDebug("Error creating table: " . $conn->error);
    }
    // sql to create table
    $sql = "CREATE TABLE IF NOT EXISTS browser_data (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    variabel VARCHAR(30) NOT NULL,
    nilai VARCHAR(30) NOT NULL
    )";
    
    if ($conn->query($sql) === TRUE) {
      echoDebug("Table arduino_data created successfully</br>");
    } else {
      echoDebug("Error creating table: " . $conn->error);
    }
    return $conn;
  }
  function echoDebug($message) 
  {
    // hapus komen '//' jika ingin men-debug pesan
    //echo $message;
  }
?> 

index.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();

  if(isset($_GET['message']))
  {
    echo $_GET['message'];
    echo "<br>";
    echo "<br>";
  }
  $sql = "SELECT * FROM arduino_data";
  $result = $conn->query($sql);

  echo "<html>";
  echo "<head>";
  echo "<meta http-equiv='refresh' content='10'>";
  echo "</head>";
  echo "<body>";
  echo "Arduino Data";
  echo "<table border='1'>";
  echo "<tr>";
  echo "<td width='50'>id</td><td width='100'>Variabel</td><td width='200'>Nilai</td>";
  echo "</tr>";
  if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
      echo "<tr>";
      echo "<td>".$row["id"]."</td><td>".$row["variabel"]."</td><td>".$row["nilai"]. "</td>";
      echo "</tr>";
    }
  } else {
    echo "<td colspan='3'>";
    echo("tidak ada hasil");
    echo "</td>";
  }
  echo "</table>";
  
  echo "<form action='dariBrowser.php' method=GET>";
  echo "<input type='hidden' name='aksi' value='hapus'><br>";
  echo "<input type='submit' value='Hapus semua data'>";
  echo "</form>";

  echo "<br>Kirim data ke Arduino<br>";
  echo "<form action='dariBrowser.php' method=GET>";
  echo "Nama variabel:<br><input type='text' name='variabel'><br>";
  echo "Nilai:<br><input type='text' name='nilai'><br>";
  echo "<input type='submit' value='Kirim'>";
  echo "</form>";
  echo "</body>";
  echo "</html>";

  $conn->close();
?> 

keArduino.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();
  
  // Kirim respon bila ada
  if(isset($_GET["variabel"]))
  {
    $variabel = $_GET["variabel"];
    $sql = "SELECT * FROM browser_data WHERE variabel='".$variabel."'";

    if($result = $conn->query($sql))
    {
      $row = $result->fetch_assoc();
      echo $row["variabel"]."=".$row["nilai"];
    }
  }
  
  $conn->close();
?> 

dariArduino.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();
  
  if(isset($_GET["variabel"]) && isset($_GET["nilai"]))
  {
    // Simpan data yang diterima ke database
    $variabel = $_GET["variabel"];
    $nilai = $_GET["nilai"];

    $sql = "INSERT INTO arduino_data (variabel, nilai) VALUES ('".$variabel."', '".$nilai."')";

    if ($conn->query($sql) === TRUE) {
      echoDebug("New record created successfully</br>");
    } else {
      echoDebug("Error: " . $sql . "<br>" . $conn->error);
    }
  }
  $conn->close();
?> 

dariBrowser.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();
  
  if(isset($_GET["variabel"]) && isset($_GET["nilai"]))
  {
    // Simpan data yang diterima ke database
    $variabel = $_GET["variabel"];
    $nilai = $_GET["nilai"];
    
    $sql = "SELECT * FROM browser_data WHERE variabel='".$variabel."'";
    $result = $conn->query($sql);

    if ($result->num_rows > 0)
    {
      $sql = "UPDATE browser_data SET nilai='".$nilai."' WHERE variabel='".$variabel."'";
      if ($conn->query($sql) === TRUE) {
        echoDebug("Record updated successfully</br>");
      } else {
        echoDebug("Error updating record: " . $sql . "<br>" . $conn->error);
      }
    }
    else
    {
      $sql = "INSERT INTO browser_data (variabel, nilai) VALUES ('".$variabel."', '".$nilai."')";
      if ($conn->query($sql) === TRUE) {
        echoDebug("New record created successfully</br>");
      } else {
        echoDebug("Error: " . $sql . "<br>" . $conn->error);
      }
    }
      echo "<script type='text/javascript'> document.location = 'index.php?message=Entri data berhasil'; </script>";
    exit();
  }
  else if(isset($_GET['aksi']))
  {
    if($_GET['aksi'] == "hapus")
    {
      // sql to delete a record
      $sql = "TRUNCATE arduino_data";

      if ($conn->query($sql) === TRUE) {
        echoDebug("Record deleted successfully");
      } else {
        echoDebug("Error deleting record: " . $conn->error);
      }
      echo "<script type='text/javascript'> document.location = 'index.php?message=database telah dikosongkan'; </script>";
      exit();
    }
  }
  $conn->close();
?> 

Cara penggunaan

  • Nyalakan wifi (pastikan terhubung ke internet)
  • Masukkan perintah dari serial monitor, data akan tercatat dalam tabel ‘arduino_data’, dalam contoh ini nama variabelnya adalah ‘dataDariSerial’ dengan nilai sesuai dengan entry dari Serial monitor (pastikan setting serial ke “both NL & CR”)
  • Buka halaman “localhost/arduino_mysql/” atau “**nama server**/arduino_mysql/” di browser untuk melihat data yang dikirim dari arduino.
  • Masukan perintah dari formulir di halaman web, dan klik kirim untuk mengirim data ke Arduino, (dalam contoh ini arduino membaca variabel ‘perintah’ jadi masukkan nama variabel sebagai ‘perintah’ serta isikan juga kotak ‘nilai’nya)
  • Arduino akan membaca perintah setiap 5 detik dan akan dilaporkan di Serial monitor.

tampilan halaman web:

library : WiFiEsp.zip