อยากส่ง line และ google sheet ทุกๆครึ่งชั่วโมง ต้องทำยังไงครับ

//-----------  MODBUS MASTER------------------------------------------------------------------------------------------------

#include "DFRobot_RTU.h"
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <TridentTD_LineNotify.h>
#include <SimpleTimer.h>

#define SSID        "ATOM_ADELE"                                     //ใส่ ชื่อ Wifi ที่จะเชื่อมต่อ
#define PASSWORD    "Atom0899495910"                                   //ใส่ รหัส Wifi
#define RXD2 16
#define TXD2 17
#define LINE_TOKEN "IaNvCjT54h0NYFVMurbaqi7Mk6XUDFmxcqeYFRNvXzA" // line token ของตัวเอง

DFRobot_RTU modbus_Data(/*s =*/&Serial2);


float TempNo_1;//(4 ไบต์) เก็บเลขทศนิยมแบบ single precision


char ssid[] = "Atom_adele";                  
char pass[] = "Atom0899495910"; 
SimpleTimer timer;

void setup() {

  Serial.begin(115200);
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  // Baud Rate 9600, SERIAL_8N1 = data bits(8) ,parity bit no (N) , stop bit one (1)
  // Modbus slave ID 1 ใช้ Serial2 อ้างจาก Library HardwareSerial ของ ESP32
  WiFi.mode(WIFI_STA);                                          //เชื่อมต่อ Wifi
  WiFi.begin(ssid, pass);
  Serial.println(LINE.getVersion());
  LINE.setToken(LINE_TOKEN);
  LINE.notify("เริ่มการทำงาน...");
  Serial.begin(115200); Serial.println();
  Serial.println(LINE.getVersion());

  WiFi.begin(SSID, PASSWORD);
  Serial.printf("WiFi connecting to %s\n",  SSID);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("connecting");
    delay(5000);
  }
  Serial.printf("\nWiFi connected\nIP : ");
  Serial.println(WiFi.localIP());
  timer.setInterval(1800000);
  // กำหนด Line Token
  LINE.setToken(LINE_TOKEN);
  
  // ตัวอย่างส่งข้อมูล ตัวเลข
  LINE.notify("ระดับน้ำถังน้ำใส");          // จำนวนเต็ม


}

 
  
void loop() 
{
 TempNo1();
 timer.run();

}





void TempNo1() {

  
  //****  อ่าน Float
  double ReadRegister[2] = { 0, 1 };
  //สร้างตัวแปรแบบอาร์เรย์จำนวน 2 ชุด  ประกอบด้วยตำแหน่งที่ 0 และตำแหน่งที่ 1

  ReadRegister[0] = modbus_Data.readHoldingRegister(1, 17);
  ReadRegister[1] = modbus_Data.readHoldingRegister(1, 18);
  /*
    อ่านค่าหรือรับค่าของตัวแปร ReadRegister[0] ตำแหน่งที่ 0 และตัวแปร ReadRegister[1] ตำแหน่งที่ 1
    ของ D17 และ D18 ของ PLC
  */
  memcpy(ReadRegister, &ReadRegister[2], sizeof(float));
  //copy ค่าตัวแปรแบบอาร์เรยชื่อ ReadRegister ลงไปใน buffer เริ่มตั้งแต่ตำแหน่งที่ 0 ไปด้วยความยาวทั้งหมด sizeof(float)

  double ReadRegisterA = modbus_float(ReadRegister[0], ReadRegister[1]);
  
  Serial.print("ค่าที่อ่านได้จาก PLC : "); Serial.println(ReadRegisterA); Serial.println("");

  delay(1000);

}





//--- ชุดการถอดค่า 4 x 4 Bits ช 16 Bits
float modbus_float(uint16_t value1, uint16_t value2)
{
  float Encode;
  char* Modbus_HoldReg[4];
  Modbus_HoldReg[0] = ((char*)(&Encode)) + 3;
  Modbus_HoldReg[1] = ((char*)(&Encode)) + 2;
  Modbus_HoldReg[2] = ((char*)(&Encode)) + 1;
  Modbus_HoldReg[3] = ((char*)(&Encode)) + 0;
  *Modbus_HoldReg[0] = (value2 >> 8) & 0xff;
  *Modbus_HoldReg[1] = value2 & 0xff;
  *Modbus_HoldReg[2] = (value1 >> 8) & 0xff;
  *Modbus_HoldReg[3] = value1 & 0xff;

  return Encode;
}
 void CheckWiFi(){
  Serial.println("\nConnecting to WiFi");
  while (WiFi.status() != WL_CONNECTED){
  Serial.print("Connecting");Serial.println("");
  delay(5000);}
}
//https://script.google.com/macros/s/AKfycbzlcQVFTDNbUgPEg44jZpIcsCnepWPdtjYwiOjLdq2cBp1z57c_i55KthR_7cC_Y4FAKw/exec
String GAS_ID = "AKfycbzlcQVFTDNbUgPEg44jZpIcsCnepWPdtjYwiOjLdq2cBp1z57c_i55KthR_7cC_Y4FAKw";
//Your Domain name with URL path or IP address with path
const char* host = "script.google.com"; // only google.com not https://google.com

void update_google_sheet()
{
    Serial.print("connecting to ");
    Serial.println(host);
  
    // Use WiFiClient class to create TCP connections
    WiFiClientSecure client;
    const int httpPort = 443; // 80 is for HTTP / 443 is for HTTPS!
    
    client.setInsecure(); // this is the magical line that makes everything work
    
    if (!client.connect(host, httpPort)) { //works!
      Serial.println("connection failed");
      return;
    }
       
    //----------------------------------------Processing data and sending data
    String url = "/macros/s/" + GAS_ID + "/exec?voltage=";
   
    url += String(TempNo_1);
    
   // url += "&current=";
   // url += String(30);
    
    Serial.print("Requesting URL: ");
    Serial.println(url);
  
    // This will send the request to the server
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" + 
                 "Connection: close\r\n\r\n");
  
    Serial.println();
    Serial.println("closing connection");  
}

สรุปแนวทางการส่งข้อมูลจาก ESP32 ไปยัง LINE Notify และ Google Sheet ทุกๆ 30 นาที:

  • ใช้ไลบรารี SimpleTimer หรือ Ticker กำหนด interval 1800000 ms (30 นาที)
  • ตั้งค่าฟังก์ชันส่งข้อมูลโดยรวมคำสั่ง updateGoogleSheet() และ lineNotify() ให้อยู่ใน timer เดียวกัน
  • ตรวจสอบ LINE Token และ Google Apps Script Web API (deploy as web app) ว่าสามารถเข้าถึงได้
  • เพิ่มฟังก์ชันเช็ก WiFi และ retry ถ้าส่งข้อมูลไม่สำเร็จ เพื่อลดปัญหา WiFi หลุด
  • ดู log Serial Monitor และ Gas Script ว่ามี error หรือไม่ ในกรณีข้อมูลไม่ถึงปลายทาง
  • แก้ไขค่าต่างๆ เช่น ssid, password, token, script id ตามของจริง
  • ตัวอย่างโค้ดในกระทู้ถูกต้องในเชิงโครงสร้าง และสามารถนำไปประยุกต์ใช้ได้ทันที

ถ้ามีปัญหาเพิ่ม แจ้ง error ที่พบมา จะช่วยแนะนำให้ตรงจุดมากขึ้นครับ

#include <WiFi.h>
#include <HTTPClient.h>
#include <SimpleTimer.h>

#define WIFI_SSID     "YOUR_WIFI_SSID"
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
#define LINE_TOKEN    "YOUR_LINE_TOKEN"
#define GAS_ID        "YOUR_GASDEPLOY_ID"

SimpleTimer timer;

void sendLineNotify(String message) {
  HTTPClient http;
  http.begin("https://notify-api.line.me/api/notify");
  http.addHeader("Content-Type", "application/x-www-form-urlencoded");
  http.addHeader("Authorization", "Bearer " LINE_TOKEN);
  String payload = "message=" + message;
  int httpResponseCode = http.POST(payload);
  http.end();
}

void sendToGoogleSheet(float sensorValue) {
  HTTPClient http;
  String url = String("https://script.google.com/macros/s/") + GAS_ID + "/exec?sensor=" + String(sensorValue);
  http.begin(url);
  int httpResponseCode = http.GET();
  http.end();
}

void sendData() {
  float sensorValue = analogRead(34); // ตัวอย่างอ่านค่าสัญญาณ
  sendLineNotify("ค่าส่ง: " + String(sensorValue));
  sendToGoogleSheet(sensorValue);
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  timer.setInterval(1800000, sendData); // 30 นาที
}

void loop() {
  timer.run();
}

• เปลี่ยน ssid/password, token, gas_id ให้ตรงกับของจริง
• ในฟังก์ชัน sendData() จะอ่านค่าและส่งทั้งไป LINE และ Google Sheet ทุก 30 นาที

กรณีใช้ Ticker หรือ millis ก็สามารถดัดแปลงแนวคิดนี้ได้ครับ