Mengirim data melalui jaringan Wifi menggunakan ESP01 dengan metode POST (kasus IOT ThingSpeak)

ESP8266 adalah modul Wi-Fi dengan fitur TCP/IP yang lengkap dan bisa dihubungkan dengan mikrokontroler melalui protokon AT-Command. TCP/IP (Transmission Control Protocol / Internet Protocol)  adalah protokol komunikasi antara dua perangkat yang terhubung dengan sebuah metode paket termasuk metode pengalamatan dan metode transmisi dalam jaringan internet.

Dalam komunikasi TCP/IP dikenal beberapa metode request/permintaan yaitu : HEAD, GET, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH.

Metode POST  sering digunakan untuk mengirimkan data-data ter-enkripsi dan langsung ke server sehingga lebih menjamin kerahasiaan data. berbeda dengan metode GET yang mengirimkan requeat dalam bentuk URL.

Skematik ESP8266/ESP01 (+Arduino Uno) request metode post:

Sketch/koding pemrograman komunikasi ESP01 + arduino dengan server menggunakan metode POST :

char ssid[]             = "xxxx";            // your network SSID (name)
char pass[]             = "xxxxxxxx";        // your network password

char server[]           = "api.thingspeak.com";
byte port               = 80;
char APIKey[]           = "XXXXXXXXXXXXXX";
uint32_t periodeKirim   = 20000;

#include <WiFiEsp.h>
#include <SoftwareSerial.h>

SoftwareSerial SerialEsp(10, 11);
WiFiEspClient client;
int status = WL_IDLE_STATUS;     // the Wifi radio's status
uint32_t millisKirim;
bool statusKirim;

void setup()
{
  Serial.begin(9600);
  Serial.println("Mengirim data melalui jaringan Wifi menggunakan ESP01 dengan metode POST");
  Serial.println("https://www.project.semesin.com/");
  Serial.println();

  SerialEsp.begin(115200);
  SerialEsp.println("AT+UART_DEF=9600,8,1,0,0");
  delay(500);
  SerialEsp.begin(9600);

  WiFi.init(&SerialEsp);

  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
  }
  millisKirim = millis();
}

void loop()
{
  if (millisKirim < millis())
  {
    millisKirim = millis() + periodeKirim;
    
    // hubungkan ke jaringan wifi jika belum tersambung atau terputus (auto reconnect)
    if (WiFi.status() != WL_CONNECTED)
    {
      Serial.print("Menghubungkan ke jaringan SSID: ");
      Serial.println(ssid);
      while (WiFi.status() != WL_CONNECTED)
      {
        WiFi.begin(ssid, pass);
        Serial.print(".");
        delay(5000);
      }
      printWifiStatus();
      Serial.println("Berhasil terhubung ke jaringan");
    }


    if (WiFi.status() == WL_CONNECTED)
    {
      Serial.println();
      Serial.println("Menghubungkan dengan server...");
      if (client.connect(server, port))
      {
        Serial.println();
        Serial.println("Terhubung dengan server.");

        char content[30];
        sprintf(content, "field1=%d", millis() % 100);

        client.println("POST /update HTTP/1.1");
        client.println("Host: api.thingspeak.com");
        client.println("User-Agent: tslib-arduino/1.5.0");
        client.print("X-THINGSPEAKAPIKEY: ");
        client.println(APIKey);
        client.println("Content-Type: application/x-www-form-urlencoded");
        client.print("Content-Length: ");
        client.println(strlen(content));
        client.println("Connection: close");
        client.println();

        client.print(content);

        statusKirim = true;
      }
    }
  }

  if (statusKirim)
  {
    while (client.available())
    {
      char c = client.read();
      Serial.write(c);
    }

    if (!client.connected()) 
    {
      Serial.println();
      Serial.println("Memutuskan hubungan dengan server...");
      delay(10);
      client.stop();

      statusKirim = 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");
}

Library :

 

Pin mapping board ESP8266

Board ESP8266 yang ada dipasaran membawa standar penamaan sendiri-sendiri, berikut tabel persamaannya:

Generik Alias Keterangan D1 D1 mini Espectro Inven tone Node MCU Oak Wifi slot Wifi duino Wifinfo Wifio
0 boot high, pull-up D8 D3 D2 D3 P2 PIN_A1 D3 D3 E0
1 TX boot high D1 TX TX/TX0 TX D10 P4 D1/TX D10 E1
2 TX1 boot high, pull-up D9 D4 TX1 D4 D4 P0 D2 D4 E2
3 RX boot high D0 RX RX/RX0 RX D9 P3 PIN_A0 D0/RX D9 E3
4 SDA D4/D14 D2 D6 D2 P5 PIN_A6 D4 D2 E4
5 SCL D3/D15 D1 D5 D1 P1 PIN_A4 D5 D1 E5
12 MISO D6/D12 D6 D8 D6 P8 PIN_A7 D8/D12 D6 E12
13 MOSI D7/D11 D7 D7 D7 P7 PIN_A3 D9/D11 D7 E13
14 SCK D5/D13 D5 D3 D5 P9 PIN_A5 D7/D13 D5 E14
15 SS boot low, pull-down, no pull-up D10 D8 D1 D8 P6 D10 D8 E15
16 no interrupt, no pull-up D2 D0 D9 D0 P10 PIN_A2 D6 D0 E16

Sedangkan aksesoris seperti LED dan button terpasa seperti tabel berikut:

Board LED Button
Adafruit 0
Arduino SPI 2
Arduino UART 14
D1 2
D1 mini 2
ESP8285 1
Espectro 15 0/2
Espino 2/4/5 0
Espinotee 16
Espresso lite v1 16
Espresso lite v2 2
Inventone 2
Modwifi 1
NodeMCU 16
Oak 5
phoenix v1 16
phoenix v2 2
Thing 5
Wifi slot 2
Wifiduino 2
Wifinfo 12
Wifio 2
Wiolink 2
Xinabox 5/12/13

Mengirim data detektor kebakaran dari arduino ke internet dengan antarmuka code igniter

Data sensor arduino

Sensor adalah instrumen atau komponen yang mampu mendeteksi perubahan kondisi objek dalam jangkauannya. Pengukuran besaran perubahan tersebut harus diubah dahulu menjadi bentuk digital sehingga dapat diproses oleh perangkat digital lainnya.

Data variabel ini bisa dimonitoring secara lokal melalui layar monitor maupun global melalui internet.

Hal yang mendukung keandalan sistem monitoring :

  1. realtime, yaitu data yang ditampilkan merupakan kondisi masa yang singkat, misalnya di perbarui setiap 1 detik.
  2. Data memiliki identitas seperti lokasi, waktu.
  3. Data yang diterima memiliki mekanisme penyaringan sehingga data yang ditampilkan terjamin.

Sensor detektor kebakaran

Terdapat beberapa Indikasi kebakaran yaitu :

  1. Api dideteksi dengan sensor flame
  2. Suhu dibaca dengan sensor suhu
  3. Asap dibaca dengan sensor asap (smoke detector)

Dalam hal pencegahan kebakaran, ketiga variabel ini terus menerus dimonitoring secara lokal.

Monitoring detektor kebakaran ini secara global juga diperlukan untuk memberikan informasi kepada pihak terkait.

Dalam contoh ini ketiga (modul) sensor ini digunakan bersama arduino dan akan dikirimkan ke mysql server.

Akses informasi sensor dengan codeIgniter

Informasi data saat ini dapat dengan mudah diakses dimanapun, namun dengan menggunakan codeIgniter diperoleh beberapa keuntungan yaitu :

  1. Pengembangan lebih mudah dengan baris program yang dapat disederhanakan.
  2. Aksesibilitas dapat dengan mudah dikontrol.
  3. Perlindungan terhadap server terutama server data lebih terjamin.

Skema Monitoring detektor kebakaran dengan codeIgniter

Komponen yang digunakan :

  1. Arduino Uno
  2. ESP8266
  3. Flame detector
  4. Sensor asap MQ7
  5. Sensor suhu dht11
  6. Relay
  7. Buzzer

Sketch / koding monitoring detektor kebakaran esp8266 – WebServer.

#include "WiFiEsp.h"
#include <SoftwareSerial.h>
#include "DHT.h"
 
char ssid[] = "****";        // Isi dengan nama profil Wifi
char pass[] = "********";            // password wifi
char server[] = "x.x.x.x";

long waktuMintaData = 1000; //minta data setiap 1000ms

#define pinFlame    A0
#define pinMQ       A1
#define pinDHT      A2
#define pinBuzzer   8
#define pinRelay    9

float setSuhu = 31.0;

String Respon = "";
long waktuMulai;
bool responDariServer = false;
bool prosesKirimDataKeServer = false;
 
WiFiEspClient client;
int status = WL_IDLE_STATUS;

SoftwareSerial wifi(2,3);
DHT dht(pinDHT, DHT11);
 
void setup()
{
  pinMode(pinFlame, INPUT_PULLUP);
  pinMode(pinMQ, INPUT_PULLUP);
  pinMode(pinDHT, INPUT_PULLUP);
  pinMode(pinBuzzer, OUTPUT);
  digitalWrite(pinRelay, HIGH);
  pinMode(pinRelay, OUTPUT);

  Serial.begin(115200);
 
  wifi.begin(115200);
  WiFi.init(&wifi);
 
  // 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();
  dht.begin();
  waktuMulai = millis();
}
 
void loop()
{
  float suhu = dht.readTemperature();
//print status
  Serial.println();
  Serial.print("Api = ");
  Serial.println(digitalRead(pinFlame));
  Serial.print("Asap = ");
  Serial.println(digitalRead(pinMQ));
  Serial.print("suhu = ");
  Serial.println(suhu);
  
  if(!digitalRead(pinFlame) && !digitalRead(pinMQ) && (suhu < setSuhu))
  {
    digitalWrite(pinRelay, HIGH);
    digitalWrite(pinBuzzer, LOW);
    
  }
  if(digitalRead(pinFlame))
  {
    digitalWrite(pinRelay, LOW);
    digitalWrite(pinBuzzer, HIGH);
  }
  if(digitalRead(pinMQ))
  {
    digitalWrite(pinRelay, LOW);
    digitalWrite(pinBuzzer, HIGH);
  }
  if(suhu >= setSuhu)
  {
    digitalWrite(pinBuzzer, HIGH);
  }
  //kirim data
  if(waktuMintaData < millis() - waktuMulai)
  {
    waktuMulai = millis();
    prosesKirimDataKeServer = kirimDataKeServer();
  }

  while (client.available()) 
  {
    char c = client.read();
    Respon += c;
  }

  Serial.print("prosesKirimDataKeServer = ");
  Serial.println(prosesKirimDataKeServer);

  if (!client.connected() && prosesKirimDataKeServer) {
    Serial.println("Disconnecting from server...");
    client.stop();
    responDariServer = true;
    prosesKirimDataKeServer = false;
  }

  // penanganan data yang diterima 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
      if(variabel == "setSuhu")
      {
        setSuhu = nilai.toFloat();
      }
//      Serial.print(variabel);
//      Serial.print(" = ");
//      Serial.println(nilai);
    }
    Respon = "";
  }
}

bool kirimDataKeServer()
{
  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 /index.php/databaseArduino/dariArduino");
    client.print("?Api=");
    client.print(digitalRead(pinFlame));
     
    client.print("&Asap=");
    client.print(digitalRead(pinMQ));

    client.print("&Suhu=");
    client.print(dht.readTemperature());
     
    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(" ");
}

program codeIgniter untuk monitoring data sensor arduino:

databaseArduino.php

<?php
class databaseArduino extends CI_Controller {
  public function __construct() {
    parent::__construct();
  }

  public function dariBrowser() {
    $this->load->model('Model_databaseArduino');
    $this->Model_databaseArduino->salinDataDariBrowser();
    $data['dataSensor'] = $this->Model_databaseArduino->ambilDataDariArduino();
    $data['dataParameter'] = $this->Model_databaseArduino->ambilDataDariBrowser();

    $this->load->view("data_sensor", $data);
  }

    public function dariArduino() {
    $this->load->model('Model_databaseArduino');
    $this->Model_databaseArduino->salinDataDariArduino();
    $data['dataParameter'] = $this->Model_databaseArduino->ambilDataDariBrowser();

    $this->load->view("data_parameter", $data);
  }
}
?>

Model_databaseArduino.php

<?php
class Model_databaseArduino extends CI_Model {

  public $title;
  public $content;
  public $date;

  public function ambilDataDariArduino()
  {
    $this->load->database();
    $query = $this->db->query("SELECT * FROM (
    SELECT * FROM `data_sensor` ORDER BY `nomor` DESC LIMIT 10
    ) sub
    ORDER BY `nomor` ASC");
    $this->db->close();  
    return $query->result();
  }

  public function salinDataDariArduino()
  {
    date_default_timezone_set('Asia/Jakarta'); # add your city to set local time zone
    $now = date('Y-m-d H:i:s');

    $this->load->database();
    $this->db->set('waktu', $now);
    $this->db->set('api', $this->input->get('Api'));
    $this->db->set('asap', $this->input->get('Asap'));
    $this->db->set('suhu', $this->input->get('Suhu'));
    $this->db->insert('data_sensor');
    $this->db->close();
  }

  public function ambilDataDariBrowser()
  {
    $this->load->database();
    $query = $this->db->query("SELECT * FROM `data_parameter` ORDER BY `nomor` DESC LIMIT 1");
    $this->db->close();  
    return $query->row();
  }

  public function salinDataDariBrowser()
  {
    date_default_timezone_set('Asia/Jakarta'); # add your city to set local time zone
    $now = date('Y-m-d H:i:s');

    $this->load->database();
    $this->db->set('waktu', $now);
    $this->db->set('setSuhu', $this->input->post('setSuhu'));
    $this->db->insert('data_parameter');
    $this->db->close();  
  }
}
?>

data_sensor.php

<?php
  defined('BASEPATH') OR exit('No direct script access allowed');

  if(isset($dataParameter))
  {
    echo "setSuhu=";
    echo $dataParameter->setSuhu;
  }
?>

data_parameter.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Welcome to CodeIgniter</title>

  <style type="text/css">

  ::selection { background-color: #E13300; color: white; }
  ::-moz-selection { background-color: #E13300; color: white; }

  body {
    background-color: #fff;
    margin: 40px;
    font: 13px/20px normal Helvetica, Arial, sans-serif;
    color: #4F5155;
  }

  a {
    color: #003399;
    background-color: transparent;
    font-weight: normal;
  }

  h1 {
    color: #444;
    background-color: transparent;
    border-bottom: 1px solid #D0D0D0;
    font-size: 19px;
    font-weight: normal;
    margin: 0 0 14px 0;
    padding: 14px 15px 10px 15px;
  }

  code {
    font-family: Consolas, Monaco, Courier New, Courier, monospace;
    font-size: 12px;
    background-color: #f9f9f9;
    border: 1px solid #D0D0D0;
    color: #002166;
    display: block;
    margin: 14px 0 14px 0;
    padding: 12px 10px 12px 10px;
  }

  #body {
    margin: 0 15px 0 15px;
  }

  p.footer {
    text-align: right;
    font-size: 11px;
    border-top: 1px solid #D0D0D0;
    line-height: 32px;
    padding: 0 10px 0 10px;
    margin: 20px 0 0 0;
  }

  #container {
    margin: 10px;
    border: 1px solid #D0D0D0;
    box-shadow: 0 0 8px #D0D0D0;
  }
  </style>
</head>
<body>



<!--
<form action="/form/data_submitted" method="get">
User Name: <input type="text" name="u_name" placeholder="Please Enter User Name" class="input_box">
<br>
User email: <input type="text" name="u_email" placeholder="Please Enter Email Address" class="input_box">
<input type="submit" value="Submit" class="submit">
</form>
-->

<?php

// echo $this->input->post('setSuhu');

echo form_open('databaseArduino/dariBrowser');
if(isset($dataParameter->setSuhu))
{
  echo form_input('setSuhu', $dataParameter->setSuhu);
}
else
{
  echo form_input('setSuhu', '30.0');
}
echo form_submit('suhuSubmit', 'Set Temperatur');
echo form_close();

echo "<br>";
echo "<strong>Data pembacaan sensor</strong>";
echo "<br>";
echo "<table>";

  echo "<tr>";
  echo "<td width='50'>Nomor</td>";
  echo "<td width='200'>Waktu</td>";
  echo "<td width='50'>Api</td>";
  echo "<td width='50'>Asap</td>";
  echo "<td width='50'>Suhu</td>";
  echo "</tr>";

  foreach ($dataSensor as $row)
{
  echo "<tr>";
  echo "<td>".$row->nomor."</td>";
  echo "<td>".$row->waktu."</td>";
  echo "<td>".$row->api."</td>";
  echo "<td>".$row->asap."</td>";
  echo "<td>".$row->suhu."</td>";
  echo "</tr>";
}
echo "</table>";
?>
</body>
</html>

file server : htdocs.zip

Mengirim file di SDCard ke PC melalui ESP8266 dengan Arduino

Mengunduh file (download) dari web server melaui web browser biasa kita lakukan. protokol yang umum digunakan adalah FTP atau HTTP. Perancangan kali ini menggunakan Arduino sebagai file server. File-filenya disimpan dalam SDCard, dan untuk berkomunikasi dengan jaringan menggunakan modul wifi ESP8266.

Perancangan sistem file server arduino ini mampu menampilkan File SDCard ke web browser, daftar file file ini merupakan isi dari root direktori kartu memori.

Untuk mendownload file dari arduino, buka browser di halaman sesuai alamat IP Wifi ESP8266 kemudian klik file yang akan didownload, atau jika ingin mendownload secara langsung bisa melalui link http://(alamat ip ESP8266)/namafile.ext.

Komponen yang digunakan :

  1. Arduino Mega
  2. Modul MicroSD
  3. Modul ESP8266 ESP12E

skema download file dari kartu memori melalui ESP8266 :

Sebelum digunakan edit dulu bagian ini :

#include <SPI.h>
#include <SD.h>
#include "WiFiEsp.h"

char ssid[] = "Twim";
char pass[] = "12345678";
int status = WL_IDLE_STATUS;

WiFiEspServer server(80);
File FileSDCard;

void setup() {
  Serial.begin(115200);
  Serial.println("Mengirim file di SDCard ke PC melalui ESP8266 dengan Arduino");
  Serial.println("https://www.project.semesin.com");

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

  if (!SD.begin(53)) 
  {
    Serial.println("Gagal memulai kartu memori!");
    while (true);
  }
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("Modul ESP8266 tidak ditemukan");
    while (true);
  }

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

  Serial.println("You're connected to the network");
  printWifiStatus();
  server.begin();
}

void loop() {
  WiFiEspClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    String request = "";

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        request += c;
        if (c == '\n' && currentLineIsBlank) {
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    client.println("HTTP/1.1 200 OK");
    client.println("Connection: close");

    Serial.println(request);
    Serial.println();
    Serial.println("Mengirim respon");

    int startFilename = request.indexOf('/') + 1;
    int endFilename = request.indexOf("HTTP/1.1") - 1;

    String fileRquest = request.substring(startFilename, endFilename);
    Serial.print("Permintaan file : ");
    Serial.println(fileRquest);

    if(fileRquest == "")
    {
      File root = SD.open("/");
      client.println("Content-Type: text/html");
      client.println();
      client.print("<!DOCTYPE HTML>");
      client.print("<html>");
      client.print("Daftar file:<br>");

      while (true) 
      {
        File entry =  root.openNextFile();
        if (! entry) {
          break;
        }
        client.print("<a href=\"");
        client.print(entry.name());
        client.print("\">");
        client.print(entry.name());
        client.print("</a><br>");
        entry.close();
      }
      client.print("</html>\r\n");
    }
    else if (!SD.exists(fileRquest)) 
    {
      client.println("Content-Type: text/html");
      client.println();
      client.print("<!DOCTYPE HTML>");
      client.print("<html>");
      client.print("Maaf file tidak ditemukan");
      client.print("</html>");
    } 
    else 
    {
      Serial.print("Mengirim file : ");
      Serial.println(fileRquest);
      FileSDCard = SD.open(fileRquest, FILE_READ);

      client.print("Content-Length:");
      client.println((String)FileSDCard.size());
      client.println("Content-Type: text/plain");
      client.print("Content-Disposition: attachment; filename=\"");
      client.print(fileRquest);
      client.println("\"");
      client.println("Content-Transfer-Encoding: binary");
      client.println();

      for(uint16_t i=0;i<FileSDCard.size();i++)
      {
        client.write(FileSDCard.read());
      }
      FileSDCard.close();
    }
    delay(10);
    client.stop();
    Serial.println("Client disconnected");
  }
}
void printWifiStatus()
{
  IPAddress ip = WiFi.localIP();
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}

keluaran serial monitor:

library yang digunakan :
WifiEsp.zip

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