#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Preferences.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
//#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3d ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
//define SCREEN_ADDRESS 0x3c //for 128x32 screen address
Adafruit_SSD1306 Display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// char ssid[] = "Pluttox 2.4Ghz"; // Your WiFi SSID
// char pass[] = "pluttox@1"; // Your WiFi password
char ssid[] = "Wokwi-GUEST"; // Your WiFi SSID
char pass[] = ""; // Your WiFi password
const int nextButtonPin = 23; // Pin for the next button
const int prevButtonPin = 22; // Pin for the previous button
//const int nextButtonPin=D8;
//const int prevButtonPin=D7;
unsigned long lastButtonPressTime = 0; // Variable to store the time of last button press
unsigned int updateTime=5000;
// Google Apps Script web service URL
// const char* serverAddress = "script.google.com";
// const int serverPort = 443; // Use port 443 for HTTPS
// Command strings for different operations
const char* nextCommand = "next";
const char* previousCommand = "previous";
const char* currentCommand = "current";
const char* allCommand = "all";
//int row=1,column=1;
// Current row, column, and value variables
int currentRow=1, currentColumn=1;
int totalRows=1,totalColumns=1;
String value="";
const int MAX_ROWS = 10; // Maximum number of rows
const int MAX_COLUMNS = 10; // Maximum number of columns
String allCellValues[MAX_ROWS][MAX_COLUMNS]; // 2D array to store cell values
// Create HTTP object
HTTPClient http;
Preferences preferences; // Create a preferences object
void setup() {
// Initialize serial communication
Serial.begin(115200);
// Initialize buttons as inputs
pinMode(nextButtonPin, INPUT_PULLUP);
pinMode(prevButtonPin, INPUT_PULLUP);
// Load preferences
loadPreferences();
initOled128_32();
displayText(value);
connectToWifi();
}
void loop() {
if (digitalRead(nextButtonPin) == LOW) {
// Send HTTP GET request for "next" command
sendRequest(nextCommand, currentRow, currentColumn);
savePreferences();
displayText(value);
lastButtonPressTime = millis();
//delay(5000); // Delay for a while
}
// Check if the previous button is pressed
else if (digitalRead(prevButtonPin) == LOW) {
// Send HTTP GET request for "previous" command
sendRequest(previousCommand, currentRow, currentColumn);
savePreferences();
displayText(value);
lastButtonPressTime = millis();
// delay(5000); // Delay for a while
}
else if (millis() - lastButtonPressTime > updateTime) {
sendRequest(currentCommand, currentRow, currentColumn);
savePreferences();
displayText(value);
lastButtonPressTime = millis();
//delay(5000); // Delay for a while
}
// // Send HTTP GET request for "next" command
// sendRequest(nextCommand, currentRow, currentColumn);
// // Delay for a while
// delay(5000);
// // Send HTTP GET request for "previous" command
// sendRequest(previousCommand, currentRow, currentColumn);
// // Delay for a while
// delay(5000);
// // Send HTTP GET request for "current" command
// sendRequest(currentCommand, currentRow, currentColumn);
// // Delay for a while
// delay(5000);
// // Send HTTP GET request for "all" command
// sendRequest(allCommand, currentRow, currentColumn);
// // Delay for a while
// delay(5000);
}
void connectToWifi(){
Serial.println("Connected to WiFi");
// WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
}
void initOled128_32(){
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!Display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
Display.display();
delay(2000); // Pause for 2 seconds
// Clear the buffer
Display.clearDisplay();
}
void sendRequest(const char* command, int& row, int& column) {
// Construct the URL with command, row, and column parameters
String url = "https://script.google.com/macros/s/AKfycbxlZhhfkssDCkWLAvfUsxf0g_vYLuziIzH9X6dUWF2XQeeVx1ORyrVO4Qrt_eEN8WHA/exec?";
url += "command=";
url += command;
url += "&row=";
url += row;
url += "&column=";
url += column;
Serial.println(url);
// Send HTTP GET request
http.begin(url.c_str());
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
int httpResponseCode = http.GET();
if (httpResponseCode == 200) {
// Parse JSON response
if(command!= "all"){
parseResponse(http.getString());
}else{
parseAllResponse(http.getString());
}
// Print parsed values
if(command!= "all"){
Serial.print("Value: ");
Serial.println(value);
}
else{
printAllCellValues();
}
Serial.print("Row: ");
Serial.println(currentRow);
Serial.print("Column: ");
Serial.println(currentColumn);
Serial.print("TotalRow: ");
Serial.println(totalRows);
Serial.print("TotalColumn: ");
Serial.println(totalColumns);
} else {
Serial.print("Error: HTTP status code ");
Serial.println(httpResponseCode);
}
// Disconnect
http.end();
}
void parseResponse(String responseBody) {
// Parse JSON object
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, responseBody);
if (!error) {
// Extract values from JSON object
const char* newvalue = doc["value"];
value=String(newvalue);
currentRow = doc["row"];
currentColumn = doc["column"];
totalRows = doc["totalRows"];
totalColumns = doc["totalColumns"];
} else {
Serial.print("Error: Failed to parse JSON: ");
Serial.println(error.c_str());
}
}
void parseAllResponse(String responseBody) {
// Parse JSON object
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, responseBody);
if (!error) {
// Extract values from JSON object
JsonArray valueArray = doc["value"].as<JsonArray>();
totalRows = doc["totalRows"];
totalColumns = doc["totalColumns"];
// Iterate over the 2D array and store cell values
for (int i = 0; i < totalRows && i < MAX_ROWS; i++) {
JsonArray innerArray = valueArray[i].as<JsonArray>();
for (int j = 0; j < totalColumns && j < MAX_COLUMNS; j++) {
allCellValues[i][j] = innerArray[j].as<String>();
}
}
currentRow = doc["row"];
currentColumn = doc["column"];
} else {
Serial.print("Error: Failed to parse JSON: ");
Serial.println(error.c_str());
}
}
void printAllCellValues() {
Serial.println("All Cell Values:");
for (int i = 0; i < MAX_ROWS; i++) {
for (int j = 0; j < MAX_COLUMNS; j++) {
Serial.print(allCellValues[i][j]);
Serial.print("\t"); // Add tab for formatting
}
Serial.println(); // Move to the next line after printing each row
}
}
void savePreferences() {
preferences.begin("myPrefs", false); // Open preferences with read/write access
preferences.putInt("currentRow", currentRow);
preferences.putInt("currentColumn", currentColumn);
preferences.putString("value", value);
preferences.end(); // Close the preferences
}
void loadPreferences() {
preferences.begin("myPrefs", true); // Open preferences with read-only access
currentRow = preferences.getInt("currentRow", currentRow);
currentColumn = preferences.getInt("currentColumn", currentColumn);
value = preferences.getString("value", value);
preferences.end(); // Close the preferences
Serial.println("Loaded preferences values :");
Serial.print("value: ");
Serial.println(value);
Serial.print("Row: ");
Serial.println(currentRow);
Serial.print("Column: ");
Serial.println(currentColumn);
}
void displayText(String text) {
Serial.println("displaying current value on oled");
Display.clearDisplay(); // Clear the display buffer
Display.setTextSize(2); // Set text size (1 = 6x8 pixels, 2 = 12x16 pixels, etc.)
Display.setTextColor(SSD1306_WHITE); // Set text color (SSD1306_WHITE, SSD1306_BLACK, SSD1306_INVERT)
Display.setCursor((SCREEN_WIDTH - text.length() * 12) / 2, (SCREEN_HEIGHT - 16) / 2); // Center text
Display.println(text); // Print text
Display.display(); // Display the buffer
}