#define DEBUG_ON 1
#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "Communicator.hh"
#include "LCD.hh"
#include "LCDCustomChars.hh"
#include "I2CDeviceScanner.hh"
#include "ButtonInfo.hh"
#include "LEDIndicator.hh"
#include "SystemDiagnostics.hh"
#include "DebugHelpers.h"
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSPHRASE = "";
const int32_t WIFI_CHANNEL = 6;
Communicator communicator = Communicator(WIFI_SSID, WIFI_PASSPHRASE, WIFI_CHANNEL);
LiquidCrystal_I2C liquidCrystal_I2c = LiquidCrystal_I2C(0x27, 16, 2);
LCD lcd = LCD(&liquidCrystal_I2c);
ButtonInfo selectButton = ButtonInfo(GPIO_NUM_23, INPUT_PULLUP, "SelectButton");
ButtonInfo enterButton = ButtonInfo(GPIO_NUM_15, INPUT_PULLUP, "EnterButton");
ButtonInfo leftButton = ButtonInfo(GPIO_NUM_18, INPUT_PULLUP, "LeftButton");
ButtonInfo rightButton = ButtonInfo(GPIO_NUM_5, INPUT_PULLUP, "RightButton");
#define NUM_BUTTON_INFOS 4
ButtonInfo* buttonInfos[NUM_BUTTON_INFOS] =
{
&selectButton,
&enterButton,
&leftButton,
&rightButton
};
LedIndicator led1 = LedIndicator(GPIO_NUM_13, OUTPUT, "Led1-13: ");
LedIndicator led2 = LedIndicator(GPIO_NUM_12, OUTPUT, "Led2-12: ");
LedIndicator led3 = LedIndicator(GPIO_NUM_27, OUTPUT, "Led3-27: ");
LedIndicator led4 = LedIndicator(GPIO_NUM_14, OUTPUT, "Led4-14: ");
#define NUM_LED_INDICATORS 4
LedIndicator* ledIndicators[NUM_LED_INDICATORS] =
{
&led1,
&led2,
&led3,
&led4
};
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 0
#define UTC_OFFSET_DST 0
void printLocalTime() {
lcd.Clear();
lcd.PrintlnRow0("Online");
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
lcd.PrintlnRow1("Connection Err");
return;
}
liquidCrystal_I2c.setCursor(8, 0);
liquidCrystal_I2c.println(&timeinfo, "%H:%M:%S");
liquidCrystal_I2c.setCursor(0, 1);
liquidCrystal_I2c.println(&timeinfo, "%d/%m/%Y %Z");
}
void setup() {
Serial.begin(115200);
// while the serial stream is not open, do nothing:
while (!Serial) ;
selectButton.Setup();
enterButton.Setup();
leftButton.Setup();
rightButton.Setup();
led1.Setup();
led2.Setup();
led3.Setup();
led4.Setup();
Serial.println("Init LCD");
lcd.GetLiquidCrystal_I2C()->init();
Serial.println("Init LCD Complete");
SystemDiagnostics::PrintFreeHeap(true, &lcd);
//This is only for diagnosis to verify wiring of lcd is correct.
I2CDeviceScanner i2cDeviceScanner;
i2cDeviceScanner.PrintScanToSerial();
SystemDiagnostics::RunLedTests(true, &lcd, ledIndicators, NUM_LED_INDICATORS);
SystemDiagnostics::PrintFreeHeap(true, &lcd);
//For low power consumption you might want to turn this off after x seconds of inactivity.
lcd.GetLiquidCrystal_I2C()->backlight();
lcd.PrintlnRow0("Connecting to ");
lcd.PrintlnRow1("WiFi ");
communicator.ConnectToWifi();
//WARNING: I'm adding extra long delay to simulate lengthy connect time
for(int i = 0; i < 20; i++)
{
delay(250);
lcd.IncrementSpinner();
}
while (WiFi.status() != WL_CONNECTED) {
delay(250);
lcd.IncrementSpinner();
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
lcd.PrintlnRow0("Online");
lcd.PrintlnRow1("Updating time...");
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
SystemDiagnostics::PrintFreeHeap(true, &lcd);
}
void fastLoop(int totalDelay)
{
int intervals = totalDelay / 100;
for(int i = 0; i <= intervals; i++)
{
delay(100);
ButtonTransition transition = selectButton.CheckButtonChange();
if(transition == ButtonDownTransition)
{
Serial.print("TODO: ");
Serial.print(selectButton.GetFriendlyName());
Serial.println(" ButtonDown");
}
else if(transition == ButtonUpTransition)
{
Serial.print("TODO: ");
Serial.print(selectButton.GetFriendlyName());
Serial.println(" ButtonUp");
}
//TODO: Refactor so we aren't repeating for each button. Also look into using interupts.
transition = enterButton.CheckButtonChange();
if(transition == ButtonDownTransition)
{
Serial.print("TODO: ");
Serial.print(enterButton.GetFriendlyName());
Serial.println(" ButtonDown");
}
else if(transition == ButtonUpTransition)
{
Serial.print("TODO: ");
Serial.print(enterButton.GetFriendlyName());
Serial.println(" ButtonUp");
}
//TODO: Refactor so we aren't repeating for each button. Also look into using interupts.
transition = leftButton.CheckButtonChange();
if(transition == ButtonDownTransition)
{
Serial.print("TODO: ");
Serial.print(leftButton.GetFriendlyName());
Serial.println(" ButtonDown");
}
else if(transition == ButtonUpTransition)
{
Serial.print("TODO: ");
Serial.print(leftButton.GetFriendlyName());
Serial.println(" ButtonUp");
}
//TODO: Refactor so we aren't repeating for each button. Also look into using interupts.
transition = rightButton.CheckButtonChange();
if(transition == ButtonDownTransition)
{
Serial.print("TODO: ");
Serial.print(rightButton.GetFriendlyName());
Serial.println(" ButtonDown");
}
else if(transition == ButtonUpTransition)
{
Serial.print("TODO: ");
Serial.print(rightButton.GetFriendlyName());
Serial.println(" ButtonUp");
}
int testValue = digitalRead(selectButton.GetGpioPinNum());
Serial.println(testValue);
}
}
void loop()
{
SystemDiagnostics::PrintFreeHeap(true, &lcd);
fastLoop(2000);
printLocalTime();
led1.WriteHigh();
led2.WriteHigh();
led3.WriteHigh();
led4.WriteHigh();
fastLoop(2000);
lcd.Clear();
lcd.PrintlnRow0("hello");
lcd.PrintlnRow1("bob");
led1.WriteLow();
led2.WriteLow();
led3.WriteLow();
led4.WriteLow();
fastLoop(1000);
//ConvertWLStatusToEnumMemberName
lcd.Clear();
}