#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHTesp.h>
// OLED Set Up
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// ENCODER Pin Set Up
#define enCLK 5
#define enDT 18
#define enSW 19
// DHT Set Up
#define DHTPin 12
#define DHTType DHT22
// Create object for using SSD1306 library
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Create object for using DHT22
DHTesp dht;
// Encoder Value
volatile int enCounter;
// Menu Configuration
int page = 0;
int menu = 0;
const int minMenu = 0;
const int maxMenu = 4;
String menu1 = "INI MENU1";
String menu2 = "INI MENU2";
String menu3 = "INI MENU3";
String menu4 = "INI MENU4";
String menu5 = "INI MENU5";
String menu6 = "INI MENU6";
String menu7;
bool menu1Highlight = false;
bool menu2Highlight = false;
bool menu3Highlight = false;
bool menu4Highlight = false;
bool menu5Highlight = false;
bool menu6Highlight = false;
bool menu7Highlight = false;
// Button Press Time
unsigned long currentTime;
unsigned long btnMinLongPressDuration = 3000;
unsigned long btnLongPressTime;
unsigned long btnPrevTime = 0;
unsigned long btnPressDuration;
const int btnPressInterval = 50;
int btnPrevState = LOW;
bool btnLongPressState = false;
// Function to display data / string
// Parameter = ( x1, y1, string1, highlight, x2, y2, data2, convert float to int )
void dpShow(int x = 0, int y = 0, String text = "", bool highlight = false, int a = 0, int b = 0, float value = 0, bool convertInt = 0){
if(highlight){
display.setTextColor(BLACK, WHITE);
}else{
display.setTextColor(WHITE, BLACK);
}
display.setCursor(x,y);
display.println(text);
if(value){
display.setCursor(a,b);
if(convertInt){
display.println(String(int(value)));
}else{
display.println(String(value));
}
}
display.display();
}
void readEncoder(){
volatile int dtVal = digitalRead(enDT);
if(dtVal == HIGH){
enCounter++;
}
if(dtVal == LOW){
enCounter--;
}
}
void readButton(){
int btnState = !digitalRead(enSW);
if(currentTime - btnPrevTime > btnPressInterval){
// Jika tombol ditekan DAN
// Jika status tombol sebelumnya LOW DAN
// Jika status long press belum diidentifikasi
if(btnState == HIGH && btnPrevState == LOW && !btnLongPressState){
btnLongPressTime = currentTime;
btnPrevState = HIGH;
Serial.println("TOmbol ditekan");
}
// Hitung lama waktu tekan
btnPressDuration = currentTime - btnLongPressTime;
// Jika tombol ditekan DAN
// Jika status long press belum diidentifikasi DAN
// Jika durasi tekan lebih besar dari durasi long press
if(btnState == HIGH && !btnLongPressState && btnPressDuration >= btnMinLongPressDuration){
btnLongPressState = true;
Serial.println("Long press");
}
// Jika status tombol sekarang LOW DAN
// Jika status tombol sebelum HIGH
if(btnState == LOW && btnPrevState == HIGH){
btnPrevState = LOW;
btnLongPressState = false;
Serial.println("Tombol dilepas");
// Jika status long press belum teridentifikasi DAN
// Jika durasi tekan < minimal long press
if(!btnLongPressState && btnPressDuration < btnMinLongPressDuration){
Serial.println("Tombol ditekan singkat");
}
}
}
// Simpan timestamp ke btnPrevTime
btnPrevTime = currentTime;
}
// menu start dari 1
// bool start dari 0
// 0 = 1 , 2 = 1
void menuPointer(){
if(enCounter >= maxMenu){
enCounter = minMenu;
}
if(enCounter < minMenu){
enCounter = maxMenu-1;
}
if(enCounter == 0){
menu1Highlight = true;
menu2Highlight = false;
menu3Highlight = false;
menu4Highlight = false;
menu5Highlight = false;
menu6Highlight = false;
menu7Highlight = false;
}
if(enCounter == 1){
menu1Highlight = false;
menu2Highlight = true;
menu3Highlight = false;
menu4Highlight = false;
menu5Highlight = false;
menu6Highlight = false;
menu7Highlight = false;
}
if(enCounter == 2){
menu1Highlight = false;
menu2Highlight = false;
menu3Highlight = true;
menu4Highlight = false;
menu5Highlight = false;
menu6Highlight = false;
menu7Highlight = false;
}
if(enCounter == 3){
menu1Highlight = false;
menu2Highlight = false;
menu3Highlight = false;
menu4Highlight = true;
menu5Highlight = false;
menu6Highlight = false;
menu7Highlight = false;
}
}
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)){
Serial.println("Display allocation failled");
}
pinMode(enCLK, INPUT);
pinMode(enDT, INPUT);
pinMode(enSW, INPUT_PULLUP);
dht.setup(DHTPin, DHTesp::DHT22);
if(dht.getStatus() != 0){
Serial.println("DHT eror status : " + String(dht.getStatusString()));
}
display.clearDisplay();
display.setTextColor(WHITE, BLACK);
display.setTextSize(1.2);
display.setCursor(40, 30);
display.println("Starting");
display.display();
delay(2000);
display.clearDisplay();
display.display();
attachInterrupt(digitalPinToInterrupt(5), readEncoder, FALLING); // Detect encoder value with interuption
}
void loop() {
TempAndHumidity data = dht.getTempAndHumidity(); // temp and humidity struct
float DHTTemp = data.temperature;
float DHTHumi = data.humidity;
currentTime = millis();
bool clear = false;
readButton();
if(btnLongPressState){
clear = true;
if(page == 0){
page = 1;
}
else if(page == 1){
page = 2;
}
}
if(clear){
display.clearDisplay();
display.display();
clear = false;
}
if(page == 0){
dpShow(30, 0, "Thermostat", 1);
dpShow(0, 20, "Waktu : ", false, 50, 20, millis()/1000, true);
dpShow(0, 30, "Kelembaban : ", false, 70, 30, DHTHumi, false);
}
if(page == 1){
dpShow(40, 0, "SETTING", 0);
menuPointer();
dpShow(10, 12, menu1, menu1Highlight);
dpShow(10, 24, menu2, menu2Highlight);
dpShow(10, 36, menu3, menu3Highlight);
dpShow(10, 48, menu4, menu4Highlight);
display.display();
}
if(page == 2){
if(enCounter+1 == 1){
menu = 1;
dpShow(40, 0, "MENU 1", 0);
display.display();
}
}
delay(10);
}