"I am from Thailand, and I am working on a project that I need to submit to my university, with a deadline on February 9th. I need the data, such as servo1, distancePercent, and kilogram, to be sent to an Apps Script that will insert it into a Google Sheet. I have edited it repeatedly, and the URL is correct and set to be accessible by everyone. I am feeling hopeless. I really need help."
This is my Arduino Iot Cloud Code.
#include "arduino_secrets.h"
#include "thingProperties.h"
#include <Servo.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
const int trigPin = 5; // GPIO5
const int echoPin = 4; // GPIO4
Servo myservo1;
int distancePercent = 0;
bool lastServoState = false;
unsigned long lastReadTime = 0;
const unsigned long readInterval = 500; // 0.5 seconds
const int maxDistance = 34; // Maximum distance
const int minDistance = 8; // Minimum distance
const float maxKilogram = 7.0; // 100% = 7 kg
void setup() {
Serial.begin(115200);
delay(1000);
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
WiFi.persistent(true); // Disable saving Wi-Fi to Flash
WiFi.mode(WIFI_STA); // Set mode to Station mode
WiFi.setSleepMode(WIFI_NONE_SLEEP); // Disable power saving mode
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
myservo1.attach(14);
myservo1.write(0);
configTime(7 * 3600, 0, "pool.ntp.org", "time.nist.gov");
setenv("TZ", "ICT-7", 1); // Set timezone to ICT
tzset(); // Update timezone info
}
void loop() {
ArduinoCloud.update(); // Check the IoT Cloud status
handleServoControl();
handleSensorUpdate();
}
void handleServoControl() {
// Check the status of servo1, schedule, schedule2, and schedule3
bool currentServoState = servo1 || schedule.isActive() || schedule2.isActive() || schedule3.isActive();
// Control servo movement
myservo1.write(currentServoState ? 70 : 0);
// Check for servo state change and send notification
if (currentServoState != lastServoState) {
notifyServoState(currentServoState);
lastServoState = currentServoState;
}
}
void handleSensorUpdate() {
if (millis() - lastReadTime > readInterval) {
lastReadTime = millis();
updateSensorDistance();
}
}
void updateSensorDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2;
if (distance < minDistance) {
distancePercent = 100;
} else if (distance <= maxDistance) {
distancePercent = map(distance, minDistance, maxDistance, 100, 0);
} else {
distancePercent = 0;
}
// Calculate food weight as a decimal
kilogram = (distancePercent * maxKilogram * 1000.0) / 100.0;
Serial.print("Distance Percent: ");
Serial.println(distancePercent);
Serial.print("Kilogram (float): ");
Serial.println(kilogram, 2); // Display two decimal points
if (distancePercent != dogFood) {
dogFood = distancePercent;
Serial.print("Distance: ");
Serial.print(distance);
Serial.print(" cm | Percentage: ");
Serial.print(distancePercent);
Serial.print(" % | Kilogram: ");
Serial.print(kilogram); // Display weight in decimal format
Serial.println(" kg");
}
}
// Function to send data to Google Apps Script
void sendDataToGoogleSheet(String servoState, int distancePercent, float kilogram) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// Construct URL to send data to Google Apps Script with parameters
String url = "https://script.google.com/macros/s/XXXXXXX/exec?"; // i have my url, I will add it later.
url += "servo1=" + servoState + "&distancePercent=" + String(distancePercent) + "&kilogram=" + String(kilogram, 2);
Serial.println("Sending data to Google Sheet...");
http.begin(url.c_str()); // Specify the URL and certificate
int httpCode = http.GET();
String payload;
if (httpCode > 0) { // Check for the returning code
payload = http.getString();
Serial.println(httpCode);
Serial.println(payload);
} else {
Serial.println("Error occurred and failed to send");
}
http.end();
}
}
String getFormattedDate() {
time_t now = time(nullptr); // Get current time
struct tm *timeinfo = localtime(&now); // Convert time to structure
char buffer[30];
strftime(buffer, sizeof(buffer), "%d-%m-%Y", timeinfo); // Format date
return String(buffer);
}
String getFormattedTime() {
time_t now = time(nullptr); // Get current time
struct tm *timeinfo = localtime(&now); // Convert time to structure
char buffer[30];
strftime(buffer, sizeof(buffer), "%H:%M:%S", timeinfo); // Format time
return String(buffer);
}
void notifyServoState(bool currentState) {
String header = "====================\n";
String footer = "\n====================";
String date = String("📅 Date: ") + getFormattedDate();
String time = String("⏰ Time: ") + getFormattedTime();
String message;
if (currentState) {
message = "💡 Status: Feeding\n" + date + "\n" + time;
} else {
message = "🛑 Status: Feeding Stopped\n" + date + "\n" + time;
}
String alert = header + message + footer;
Serial.println(alert);
}
void onServo1Change() {
myservo1.write(servo1 ? 70 : 0);
notifyServoState(servo1);
}
void onDogFoodChange() {
Serial.print("DogFood Changed to: ");
Serial.println(dogFood);
}
void onScheduleChange() {
Serial.println("Schedule Changed");
}
void onAlertChange() {
Serial.println("Alert Changed");
}
void onSchedule2Change() {
Serial.println("Schedule2 Changed");
}
void onSchedule3Change() {
Serial.println("Schedule3 Changed");
}
void onKilogramChange() {
Serial.println("Kilogram value has changed!");
// Add any processing you want when the kilogram changes
}
===========================================================
and my AppScript Code
function doGet(e) {
Logger.log(JSON.stringify(e));
var result = 'Ok';
if (!e.parameter || Object.keys(e.parameter).length === 0) {
result = 'No Parameters';
} else {
var sheet_id = 'XXXXXXXX'; // I have Spreadsheet ID, i will add it later.
var sheet = SpreadsheetApp.openById(sheet_id).getActiveSheet();
var newRow = sheet.getLastRow() + 1;
var rowData = [];
var Curr_Date = new Date();
rowData[0] = Curr_Date; // Date in column A
var Curr_Time = Utilities.formatDate(Curr_Date, "Asia/Bangkok", 'HH:mm:ss');
rowData[1] = Curr_Time; // Time in column B
for (var param in e.parameter) {
Logger.log('In for loop, param=' + param);
var value = stripQuotes(e.parameter[param]);
Logger.log(param + ':' + e.parameter[param]);
switch (param) {
case 'servo1':
if (value === "ON") {
rowData[2] = "Dispensing Food"; // Write "Dispensing Food" in column C
result = 'Dispensing Food written to column C';
} else if (value === "OFF") {
rowData[2] = "Stopped Dispensing Food"; // Write "Stopped Dispensing Food" in column C
result = 'Stopped Dispensing Food written to column C';
} else {
result = 'Invalid value received (should be ON or OFF)';
}
break;
case 'distancePercent':
rowData[3] = value; // Write distancePercent value to column D
result = 'distancePercent written to column D';
break;
case 'kilogram':
rowData[4] = value; // Write kilogram value to column E
result = 'kilogram written to column E';
break;
default:
Logger.log('Unsupported parameter: ' + param);
}
}
Logger.log(JSON.stringify(rowData));
var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
return ContentService.createTextOutput(result);
}
function stripQuotes(value) {
return value.replace(/^["']|['"]$/g, "");
}