ArduinoEsp32esp8266Internet Of ThingsTutorial Arduino

Tutorial Data Logger Arduino ESP8266 Ke Google Sheet

Pendahuluan – Latar Belakang Data Logger Dengan Google Sheet

Di era IoT (Internet of Things), penggunaan data logger menjadi semakin penting untuk memantau dan merekam data dari berbagai sensor secara real-time. Jenis Data Logger adalah beberapa jenis tergantung daripada media penyimpanan datanya, Ada yang menyimpan data ke memori internal mikrokontroler, Ada yang menyimpan ke memori eksternal seperti microSD, dan yang paling terbaru di era IoT ini teman-teman bisa mengirim dan menyimpan data ke Google sheet. Salah satu cara praktis untuk menyimpan data adalah dengan mengirimkannya langsung ke Google Sheets menggunakan Arduino dan ESP8266.

Dalam tutorial ini, kita akan mempelajari cara membuat data logger sederhana yang mengirim data sensor ke Google Sheets secara otomatis. Dengan metode ini, Anda dapat memantau suhu, kelembaban, atau parameter lainnya dari mana saja.

Apa saja Tools dan Bahan yang di butuhkan dalam Tutorial Arduino kali ini?

Berikut adalah komponen yang diperlukan untuk proyek ini:

  1. Arduino Uno/Nano (atau board Arduino lainnya)
  2. Modul Wi-Fi ESP8266 (NodeMCU atau ESP-01)
  3. Sensor (misalnya DHT11/DHT22 untuk suhu & kelembaban)
  4. Kabel jumper
  5. Breadboard (opsional)
  6. Akun Google (untuk mengakses Google Sheets)

Langkah 1: Menyiapkan Google Sheets dan Google Apps Script

Sebelum memprogram Arduino, kita perlu menyiapkan Google Sheets untuk menerima data.

1. Buat Spreadsheet Baru
Buka Google Sheets dan buat spreadsheet baru.

Beri nama kolom seperti “Tanggal”, “Waktu”, “Suhu”, “Kelembaban”, dll.

2. Buat Script dengan Google Apps Script
Klik Extensions > Apps Script.

Ganti kode default dengan script berikut:

// Enter Spreadsheet ID here
var SS = SpreadsheetApp.openById(‘1xH1VJZ7jo_N111FBcvEHN707iv-CknmQSmh_S4vGarY’);

var str = “”;
function doPost(e) {

var parsedData;
var result = {};

try {
parsedData = JSON.parse(e.postData.contents);
}
catch(f){
return ContentService.createTextOutput(“Error in parsing request body: ” + f.message);
}

if (parsedData !== undefined){
var flag = parsedData.format;
if (flag === undefined){
flag = 0;
}

var sheet = SS.getSheetByName(parsedData.sheet_name); // sheet name to publish data to is specified in Arduino code
var dataArr = parsedData.values.split(“,”); // creates an array of the values to publish

var date_now = Utilities.formatDate(new Date(), “CST”, “yyyy/MM/dd”); // gets the current date
var time_now = Utilities.formatDate(new Date(), “CST”, “hh:mm:ss a”); // gets the current time

var value0 = dataArr [0]; // h
var value1 = dataArr [1]; // t
var value2 = dataArr [2]; // mq135

var value3 = dataArr [3]; // ldr
var value4 = dataArr [4]; // pm25

// var value5 = dataArr [5]; // value2 from Arduino code
// var value6 = dataArr [6]; // value0 from Arduino code

// read and execute command from the “payload_base” string specified in Arduino code
switch (parsedData.command) {

case “insert_row”:

sheet.insertRows(3); // insert full row directly below header text

sheet.getRange(‘A3’).setValue(date_now); // Date
sheet.getRange(‘B3’).setValue(time_now); // Time

sheet.getRange(‘C3’).setValue(value0); // h
sheet.getRange(‘D3’).setValue(value1); // t
sheet.getRange(‘E3’).setValue(value2); // mq135

sheet.getRange(‘F3’).setValue(value3); // ldr
sheet.getRange(‘G3’).setValue(value4); // pm25

str = “Success”; // string to return back to Arduino serial console
SpreadsheetApp.flush();
break;

case “append_row”:

var publish_array = new Array(); // create a new array

//publish_array [0]= date_now;
//publish_array [1]= time_now;

publish_array [0]= value0;
publish_array [1]= value1;
publish_array [2]= value2;
publish_array [3]= value3;
publish_array [4]= value4;
publish_array [5]= value5;

var date_now = Utilities.formatDate(new Date(), “CST”, “yyyy/MM/dd”); // gets the current date
var time_now = Utilities.formatDate(new Date(), “CST”, “hh:mm:ss a”); // gets the current time

publish_array [6]= date_now;

sheet.appendRow(publish_array); // publish data in publish_array after the last row of data in the sheet

str = “Success”; // string to return back to Arduino serial console
SpreadsheetApp.flush();
break;
}

return ContentService.createTextOutput(str);
} // endif (parsedData !== undefined)

else {
return ContentService.createTextOutput(“Error! Request body empty or in incorrect format.”);
}
}

3. Buat Script di Arduino IDE

#include <WiFi.h>
#include <DallasTemperature.h>
#include “HTTPSRedirect.h”
#include “DHT.h”
#include “HTTPSRedirect.h”
#include <WiFiClientSecure.h>
#include <MQUnifiedsensor.h>
#include <SD_ZH03B.h>
#include <HardwareSerial.h>
//Definitions
#define placa “Arduino UNO”
#define Voltage_Resolution 3.3
#define pin 35 //Analog input 0 of your arduino
#define type “MQ-135” //MQ135
#define ADC_Bit_Resolution 12 // For arduino UNO/MEGA/NANO
#define RatioMQ135CleanAir 3.6//RS / R0 = 3.6 ppm
#define WIFI_SSID “SAYUSWA_2.4G”
#define WIFI_PASSWORD “no-covid20”
#define DHTPIN 5
#define DHTTYPE DHT22
#define LDRPIN  32
HardwareSerial zh03bSerial(1);  // Use UART1
DHT dht(DHTPIN, DHTTYPE);
const int RX_PIN = 16; // Connect ZH03B TXD to ESP32 RX
const int TX_PIN = 17; // Connect ZH03B RXD to ESP32 TX
// Enter command (insert_row or append_row) and your Google Sheets sheet name (default is Sheet1):
String payload_base = “{\”command\”: \”insert_row\”, \”sheet_name\”: \”Sheet1\”, \”values\”: “;
String payload = “”;
const char* GScriptId = “AKfycbyPm4VZGYHG4AJANMoXdR9a-F7inYJ0L29z41CdK25lGz5WYoQHXJ0t1CWSOrgAdq8VCA”; //”AKfycbxqF68pkczlZZfE1rW2JLjBwMROL0zf7-gIFEjSmXNIuT61YKvKvIFQhVH840rXSPBH”;
// Google Sheets setup (do not edit)
const char* host = “script.google.com”;
const int httpsPort = 443;
const char* fingerprint = “”;
unsigned char CounterSheet;
String url = String(“/macros/s/”) + GScriptId + “/exec”;
HTTPSRedirect* client = nullptr;
MQUnifiedsensor MQ135(placa, Voltage_Resolution, ADC_Bit_Resolution, pin, type);
SD_ZH03B ZH03B( Serial2, SD_ZH03B::SENSOR_ZH03B );  // same as the line above
String ttemp = “”;
float mq135, vLDR, h, t, pm25;
uint32_t tLastTime= 0;
void setup() {
  Serial.begin(9600);
  zh03bSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); // ZH03B UART config
  delay(1000);
  dht.begin();
  MQ135.setRegressionMethod(1); //_PPM =  a*ratio^b
  MQ135.setA(102.2); MQ135.setB(-2.473); // Configure the equation to to calculate NH4 concentration
  MQ135.init();
  // Explanation:
   // In this routine the sensor will measure the resistance of the sensor supposedly before being pre-heated
  // and on clean air (Calibration conditions), setting up R0 value.
  // We recomend executing this routine only on setup in laboratory conditions.
  // This routine does not need to be executed on each restart, you can load your R0 value from eeprom.
  // Acknowledgements: https://jayconsystems.com/blog/understanding-a-gas-sensor
  Serial.print(“Calibrating please wait.”);
  float calcR0 = 0;
  for(int i = 1; i<=10; i ++)
  {
    MQ135.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ135.calibrate(RatioMQ135CleanAir);
    Serial.print(“.”);
  }
  MQ135.setR0(calcR0/10);
  Serial.println(”  done!.”);
  if(isinf(calcR0)) {Serial.println(“Warning: Conection issue, R0 is infinite (Open circuit detected) please check your wiring and supply”); while(1);}
  if(calcR0 == 0){Serial.println(“Warning: Conection issue found, R0 is zero (Analog pin shorts to ground) please check your wiring and supply”); while(1);}
  MQ135.serialDebug(false);
  Serial2.begin(9600);
  delay(100);
  ZH03B.setMode( SD_ZH03B::IU_MODE );
  Serial.println(“– Reading ZH03B –“);
  delay(200);
  // attempt to connect to Wifi network:
  Serial.print(“Connecting to Wifi SSID “);
  Serial.print(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(“.”);
    delay(500);
  }
  Serial.print(“\nWiFi connected. IP address: “);
  Serial.println(WiFi.localIP());
  // Use HTTPSRedirect class to create a new TLS connection
  // client = new HTTPSRedirect(httpsPort);
  // client->setInsecure();
  // client->setPrintResponseBody(true);
  // client->setContentTypeHeader(“application/json”);
  // Serial.print(“Connecting to “);
  // Serial.println(host);
  // // Try to connect for a maximum of 5 times
  // bool flag = false;
  // for (int i = 0; i < 5; i++) {
  //   int retval = client->connect(host, httpsPort);
  //   if (retval == 1) {
  //     flag = true;
  //     Serial.println(“Connected”);
  //     break;
  //   } else
  //     Serial.println(“Connection failed. Retrying…”);
  // }
  // if (!flag) {
  //   Serial.print(“Could not connect to server: “);
  //   Serial.println(host);
  //   return;
  // }
  //delete client;     // delete HTTPSRedirect object
  //client = nullptr;  // delete HTTPSRedirect object
}
void loop() {
  delay(2000);
  h = dht.readHumidity();
  t = dht.readTemperature();
  MQ135.update(); // Update data, the arduino will read the voltage from the analog pin
  mq135= MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup
  int ldrValue = analogRead(LDRPIN);  // Membaca nilai ADC (0 – 4095)
  vLDR = (ldrValue / 4095.0) * 3.3;  // Konversi ke Volt
  if (zh03bSerial.available()) {
    uint8_t buffer[9];
    zh03bSerial.readBytes(buffer, 9);  // Read 9 bytes from ZH03B
    if (buffer[0] == 0x42 && buffer[1] == 0x4d) {  // Check start bytes
      pm25 = (buffer[3] << 8) | buffer[4];    // PM2.5 value
      int pm10 = (buffer[5] << 8) | buffer[6];     // PM10 value
      /*
      Serial.print(“PM2.5: “);
      Serial.print(pm2_5);
      Serial.println(” µg/m³”);
      Serial.print(“PM10: “);
      Serial.print(pm10);
      Serial.println(” µg/m³”);
      */
    }
  }
  Serial.print(h);
  Serial.print(“,”);
  Serial.print(t);
  Serial.print(“,”);
  Serial.print(mq135);
  Serial.print(“,”);
  Serial.print(vLDR);
  Serial.print(“,”);
  Serial.print(pm25);
  Serial.println();
  if(millis()- tLastTime > 10000){
    Serial.println(“Send to google…”);
    updatesheet(String(h), String(t), String(mq135), String(vLDR), String(pm25));
    tLastTime= millis();
  }
}
void updatesheet(String hum, String temp, String mq135, String ldr, String pm25) {
  client = new HTTPSRedirect(httpsPort);
  client->setInsecure();
  client->setPrintResponseBody(true);
  client->setContentTypeHeader(“application/json”);
  Serial.print(“Connecting to “);
  Serial.println(host);
  // Try to connect for a maximum of 5 times
  bool flagConnect = false;
  for (int i = 0; i < 5; i++) {
    int retval = client->connect(host, httpsPort);
    if (retval == 1) {
      flagConnect = true;
      Serial.println(“Connected”);
      break;
    } else
      Serial.println(“Connection failed. Retrying…”);
  }
  if (!flagConnect) {
    Serial.print(“Could not connect to server: “);
    Serial.println(host);
    return;
  }
  delete client;     // delete HTTPSRedirect object
  client = nullptr;  // delete HTTPSRedirect object
  static bool flag = false;
  if (!flag) {
    client = new HTTPSRedirect(httpsPort);
    client->setInsecure();
    flag = true;
    client->setPrintResponseBody(true);
    client->setContentTypeHeader(“application/json”);
  }
  if (client != nullptr) {
    if (!client->connected()) {
      client->connect(host, httpsPort);
    }
  } else {
    Serial.println(“Error creating client object!”);
  }
  // Create json object string to send to Google Sheets
  payload = payload_base + “\”” + hum + “,” + temp + “,” + mq135 + “,” + vLDR + “,” + pm25 + “\”}”;
  // Publish data to Google Sheets
  Serial.println(“Publishing data…”);
  Serial.println(payload);
  if (client->POST(url, host, payload)) {
    // do stuff here if publish was successful
    Serial.println(“Success send data”);
  } else {
    // do stuff here if publish was not successful
    Serial.println(“Error while connecting”);
    //ESP.restart();
  }
  // a delay of several seconds is required before publishing again
}

Related Articles

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button
0
Would love your thoughts, please comment.x
()
x