I was able to get it working, thanks to the guidance of PaulS. The problem was that I needed to add 'getResponseBody();' outside of the 'if' statement. The data was not remaining in the string once the statement completed. I have some basic questions of why it is behaving this way:
1.I tried to change the name of the string to 'flag' but received an error messege "'flag' was not declared in scope". Why can't I change this to anything other than 'str'?
- I am reading from another cell using the GET request "client->GET(url2, host);" and assigning it to the same name 'str'. How am I getting the output of url3 and not url 2? My guess is that I'm just reassigning the data I receive from the spreadsheet to 'str'.
3.Why do I need to get the data again using 'getresponseBody();' if it was declared in the 'if' statement just above it?
Here is the full code:
/* HTTPS on ESP8266 with follow redirects, chunked encoding support
* Version 2.1
* Author: Sujay Phadke
* Github: @electronicsguy
* Copyright (C) 2017 Sujay Phadke <electronicsguy123@gmail.com>
* All rights reserved.
*
* Example Arduino program
*/
#include <LiquidCrystal_I2C.h>
#include <ESP8266WiFi.h>
#include <DebugMacros.h>
#include <HTTPSRedirect.h>
#include <SPI.h>
#include <Wire.h>
#define LCDWIDTH 16
#define LCDHEIGHT 2
/*
* SDA to nodeMCU D4
* SCL to nodeMCU D3
*/
// for stack analytics
extern "C" {
#include <cont.h>
extern cont_t g_cont;
}
// Fill ssid and password with your network credentials
const char* ssid = "SSID";
const char* password = "PASSWORD";
const char* host = "script.google.com";
// Replace with your own script id to make server side changes
const char *GScriptId = "Gscript ID Goes HERE";
const int httpsPort = 443;
// echo | openssl s_client -connect script.google.com:443 |& openssl x509 -fingerprint -noout
const char* fingerprint = "";
// Write to Google Spreadsheet
String url = String("/macros/s/") + GScriptId + "/exec?value=Hello";
// Read from Google Spreadsheet: Beer Owner
String url2 = String("/macros/s/") + GScriptId + "/exec?readE1";
// Read from Google Spreadsheet: Beer Purchased Flag
String url3 = String("/macros/s/") + GScriptId + "/exec?readD1";
String payload_base = "{\"command\": \"appendRow\", \
\"sheet_name\": \"Sheet1\", \
\"values\:";
String payload = "";
HTTPSRedirect* client = nullptr;
// used to store the values of free stack and heap
// before the HTTPSRedirect object is instantiated
// so that they can be written to Google sheets
// upon instantiation
// Construct an LCD object and pass it the I2C address, width (in characters) and height (in characters). Depending on the
// Actual device, the IC2 address may change.
// Wemos D2 to LCD SDA
// Wemos D1 to LCD SCL
//Define LDR pin and create timer variable
const int ldrPin = A0;
unsigned long previousMillis= 0;
//How often do we check back on the LDR state
unsigned long interval=1000;
//Create timer variable for checking Google sheet
unsigned long previousMillisCell= 0;
unsigned long intervalCell=4000;
LiquidCrystal_I2C lcd(0x27, 16, 2);//Ox27 OR 0x3F
void setup() {
Serial.begin(115200);
Serial.flush();
Serial.setDebugOutput(false);
pinMode(ldrPin, INPUT);
//Wire.begin(2,0); //Uncomment for Node MCU only
//lcd.begin(16, 2); //Uncomment for Node MCU only
lcd.init(); // initialize the lcd, WEMOS
lcd.init();
lcd.backlight(); // Enable or Turn On the backlight
//Establish Wifi Connection
Serial.println();
Serial.print("Connecting to wifi: ");
Serial.println(ssid);
// flush() is needed to print the above (connecting...) message reliably,
// in case the wireless connection doesn't go through
Serial.flush();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
//Display connection status on LCD
lcd.setCursor(0,0);
lcd.print("Connected to: ");
lcd.setCursor(0,1);
lcd.print(ssid);
delay(2000);
lcd.clear();
// Use HTTPSRedirect class to create a new TLS connection
client = new HTTPSRedirect(httpsPort);
client->setPrintResponseBody(false);
client->setContentTypeHeader("application/json");
Serial.print("Connected 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;
break;
}
else
Serial.println("Connection failed. Retrying...");
}
if (!flag){
Serial.print("Could not connect to server: ");
Serial.println(host);
Serial.println("Exiting...");
return;
}
if (client->verify(fingerprint, host)) {
Serial.println("Certificate match.");
} else {
Serial.println("Certificate mis-match");
}
// Note: setup() must finish within approx. 1s, or the the watchdog timer
// will reset the chip. Hence don't put too many requests in setup()
// ref: https://github.com/esp8266/Arduino/issues/34
Serial.println(" Write into cell 'A1'");
Serial.println("=========================");
// fetch spreadsheet data
client->GET(url, host);
// fetch spreadsheet data
client->GET(url2, host);
// fetch spreadsheet data
client->GET(url3, host);
}
void loop() {
//-----------------------------This section reads from a single google cell to display its contents on the LCD screen------------------------------
//Check the current time to start the ldr timer AND for the Google cell check
unsigned long currentMillis=millis();
//Subtract the current time from the previous time, then check if it has passed the interval time
if(currentMillis - previousMillisCell>= intervalCell) {
//If interval time is met, reset current timer
previousMillisCell=currentMillis;
static int error_count = 0;
static int connect_count = 0;
const unsigned int MAX_CONNECT = 20;
static bool flag = false;
//Read Data from cell E1 and display on screen
if (client->GET(url2, host)){
++connect_count;
String str = client->getResponseBody();
Serial.print("Who's beer is this?:");
Serial.print(str);
//Refresh the LCD before displaying the most current cell contents
lcd.clear();
//The following was written by Goet:https://forum.arduino.cc/index.php?topic=216486.0 to center the contects on the LCD screen
int pinnedRow = 0; // LCDHEIGHT / 2;
String pinnedText = str;
int l = pinnedText.length();
lcd.setCursor(l % 2 == 0 ? LCDWIDTH / 2 - (l / 2) : LCDWIDTH / 2 - (l / 2) - 1, pinnedRow);
pinnedText= pinnedText.substring(0, pinnedText.length() - 2);
lcd.print (pinnedText);
//Read Data from cell D1, if it matched the string "Beer Purchased", then open the solenoid for x seconds (or turn off back light for testing purposes)
if (client->GET(url3, host)){
++connect_count;
//assign the output string of the readD3 Google appps function to a string called 'str'
String paid= client->getResponseBody();
}
else{
++error_count;
DPRINT("Error-count while connecting: ");
Serial.print("First Error while connecting");
DPRINTLN(error_count);
}
//create a string to compare the output of the google sheet to
String purchase = "Beer Purchased";
//Grab the output of cell D1 on the Google sheet to use in the comparison, then trim of the extra carriage return
str= client->getResponseBody();
str.trim();
if(str == purchase){
//Print the "Beer Purchased" flag to the serial.
Serial.print ("Beer Purchased");
lcd.noBacklight();
delay (4000);
}
else{
++error_count;
DPRINT("Error-count while connecting: ");
Serial.print("Error: [");
Serial.print(str);
Serial.print("] is not equal to [");
Serial.print(purchase);
Serial.print("]")
DPRINTLN(error_count);
}
//May want to send the command to clear D1 from Arduino, instead of the apps script.
// In my testing on a ESP-01, a delay of less than 1500 resulted
// in a crash and reboot after about 50 loop runs.
}
}
}