#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <ESP32Servo.h>
#include "icons.h"
#include <Wire.h>
#include "WiFi.h"
#include <esp_wifi.h>
#include "ThingsBoard.h"
#include "DHTesp.h"
#ifdef CORE_DEBUG_LEVEL
#undef CORE_DEBUG_LEVEL
#endif
#define CURRENT_FIRMWARE_TITLE "TEST"
#define CURRENT_FIRMWARE_VERSION "1.0.0"
#define CORE_DEBUG_LEVEL 3
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
// ini re-map pin SDA dan SCL
#define I2C_SDA 1
#define I2C_SCL 2
TwoWire I2CBME = TwoWire(0);
/* Locking mechanism definitions */
#define SERVO_PIN 41
#define SERVO_LOCK_POS 20
#define SERVO_UNLOCK_POS 90
Servo ServoMotor; // menamakan objek servo
int buzzpin = 4;
int pinPIR = 42;
int PIRState = LOW;
//int pinRelay1 = 7; //kipas angin
int kipasAngin = 7; // hidup kalau suhu tinggi
int pengkabut = 8; // hidup kalau kelembaban tinggi
int pemanas = 9; // hidup kalau suhu rendah
int exhauseFan = 10; // hidup kalau kipas angin hidup
int fanAmonia = 11; // hidup kalau amonia >= 20 ppm, exhause fan juga hidup
int fanCO2 = 12; // hidup kalau CO2 > 0,21% exhause juga hidup
int lampudalam = 13; // hidup kalau mulai agak gelap
int lampuluar = 14; // hidup kalau sudah gelap
int lampuDalamLDR = 16; // ini lampu dalam kandang
int lampuLuarLDR = 17; // ini lampu luar kandangss
int gelapkandang; // batas kandang dikatakan gelap
// sekalian memicu lampu dalam aktif
int gelapluar; // batas luar kandang dikatakan gelap.
// sekalian memicu PIR aktif dan lampu luar aktif
int RedpinLock = 18; // indikator terkunci
int GreenpinUnlock = 15; //indikator terbuka
int position = 0;
char* password = "789";
boolean bolehMasuk = false;
//deklarasi milis checkpoint dan set ke 0
unsigned long millis_check = 0;
unsigned long millis_skrg = 0;
//unsigned long millis_sebelumnya = 0;
//delay penyususup
unsigned long millis_cekPenyusup_sblm = 0;
LiquidCrystal_I2C lcd(0x27,20,4);
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
uint8_t colPins[COLS] = { 26, 21, 20, 19 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 36, 35, 34, 33 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
#define WIFI_SSID "Wokwi-GUEST" //deklarasi ssid wifi yang digunakan, disesuiakan dengan wifi yang digunakan
#define WIFI_PASSWORD "" //deklarasi password wifi yang digunakan
// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
//define TOKEN "p8ycSsCzIpcJMi6ZCeS5" //SESUAIKAN token masing-masing
#define TOKEN "QVpRARW4LR1GWJC9Rb8O" //SESUAIKAN token masing-masing
#define THINGSBOARD_SERVER "thingsboard.cloud" //alamat server dari thingsboard, jika menggunakan server probadi alamatnya bisa disesuaikan, apabila menggunakan server yang disediakan thingsboard alamatnya adalah thingsboar.cloud
const int DHTSuhuHuma_PIN = 5; //deklarasi nomor pin dht
const int DHTAmoniaCO2_PIN = 3; //deklarasi nomor pin dht
DHTesp dhtSuhu; // deklarasi objek suhu dan kelembaban
DHTesp dhtGas; // deklarasi objek gas amonia dan metana
// Deklarasi Thingsboard client dan mengubah perintah WiFiClient menjadi espClient
WiFiClient espClient;
// Deklarasi untuk mengubah perintah Thingsboard menjadi tb dan memasukkan perintah WiFiClient yang sudah diubah menjadi espClient ke dalam library Thingsboard
ThingsBoard tb(espClient);
int status = WL_IDLE_STATUS; //deklarasi status wifi yang dimasukkan dalam variabel status
uint8_t newMACAddress[] = {0x32, 0xAE, 0xA4, 0x07, 0x0D, 0x66};
// uint8_t newMACAddress[] = {0x32, 0xAE, 0xA4, 0x07, 0x0D, 0x44};
// uint8_t newMACAddress[] = {0x32, 0xAE, 0xA4, 0x07, 0x0D, 0x55};
void connect() //void mengoneksikan esp dengan wifi pertama kali
{
Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
while (!tb.connected()) {
Serial.print("Connecting to ThingsBoard node ...");
// Attempt to connect (clientId, username, password)
if ( tb.connect(THINGSBOARD_SERVER, TOKEN) ) {
Serial.println( "[DONE]" );
} else {
Serial.print( "[FAILED]" );
Serial.println( " : retrying in 5 seconds" );
// Wait 5 seconds before retrying
delay( 500 );
}
}
}
void reconnect() { //perintah recconect wifi apabila esp terputus dengan jaringan wifinya
// Loop until we're reconnected
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
}
int delay_milis( unsigned long millis_sebelumnya, unsigned long threshold ){
millis_skrg = millis();
if (millis_skrg - millis_sebelumnya >= threshold ){
// millis_sebelumnya = millis_skrg;//
return 1;
}else{
return 0;
}
}
void showStartupMessage() {
lcd.setCursor(4, 0);
lcd.print("Welcome!");
delay(500);
lcd.setCursor(0,1);
lcd.println("IoT4 Kelompok 4");
lcd.setCursor(0, 2);
String message = "Farm Controller";
for (byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(50);
}
delay(500);
}
void setup() {
Wire.setPins(I2C_SDA, I2C_SCL); // re-map
lcd.init();
lcd.backlight();
lcd.begin(16,2);
Serial.begin(9600);
pinMode(SERVO_PIN, OUTPUT);
pinMode(buzzpin, OUTPUT);
pinMode(kipasAngin, OUTPUT);
pinMode(pengkabut, OUTPUT);
pinMode(pemanas, OUTPUT);
pinMode(exhauseFan, OUTPUT);
pinMode(fanAmonia, OUTPUT);
pinMode(fanCO2, OUTPUT);
pinMode(lampudalam, OUTPUT);
pinMode(lampuluar, OUTPUT);
pinMode(RedpinLock, OUTPUT); // indikator terkunci
pinMode(GreenpinUnlock, OUTPUT); //indikator terbuka
pinMode(lampuDalamLDR, INPUT);
pinMode(lampuLuarLDR, INPUT);
pinMode(pinPIR, INPUT);
gelapkandang = analogRead(lampuDalamLDR);
gelapluar = analogRead(lampuLuarLDR);
digitalWrite(RedpinLock, HIGH); // indikator terkunci
digitalWrite(GreenpinUnlock, LOW); //indikator terbuka
dhtSuhu.setup(DHTSuhuHuma_PIN, DHTesp::DHT22); // suhu dan kelembaban
dhtGas.setup(DHTAmoniaCO2_PIN, DHTesp::DHT22); // amonia dan CO2
// Serial.print("[OLD] ESP32 Board MAC Address: ");
// Serial.println(WiFi.macAddress());
// esp_wifi_set_mac(WIFI_IF_STA, &newMACAddress[0]);
// Serial.print("[NEW] ESP32 Board MAC Address: ");
// Serial.println(WiFi.macAddress());
init_icons(lcd);
/*
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
ServoMotor.setPeriodHertz(50); // standard 50 hz servo
*/
showStartupMessage();
delay(500);
position = 0; // posisi servo
ServoMotor.attach(SERVO_PIN, 500, 2400);
LockedPosition(true);
connect() ;
Serial.print("[OLD] ESP32 Board MAC Address: ");
Serial.println(WiFi.macAddress());
// ESP32 Board add-on before version < 1.0.5
//esp_wifi_set_mac(ESP_IF_WIFI_STA, &newMACAddress[0]);
// ESP32 Board add-on after version > 1.0.5
//esp_wifi_set_mac(WIFI_IF_STA, &newMACAddress[0]);
Serial.print("[NEW] ESP32 Board MAC Address: ");
Serial.println(WiFi.macAddress());
}
void loop()
{
char key = keypad.getKey();
if (key == '*' || key == '#')
{
position = 0;
LockedPosition(true);
}
if (key == password[position])
{
position ++;
}
if (position == 3)
{
LockedPosition(false);
}
delay(100);
if (bolehMasuk)
{
lcd.clear();
cekPenyusup();
cekLampuLuar();
cekLampuKandang();
cekSuhuKelembaban();
cekAmoniaCO2();
}
}
void LockedPosition(int locked)
{
if (locked)
{
lcd.clear();
lcd.setCursor(4,0);
lcd.print("Masukkan kode"); // lode 789
digitalWrite(RedpinLock, HIGH);
digitalWrite(GreenpinUnlock, LOW);
ServoMotor.write(180);
}
else
{
digitalWrite(RedpinLock, LOW);
digitalWrite(GreenpinUnlock, HIGH);
ServoMotor.write(90);
delay(15);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Kunci terbuka");
delay(3000);
bolehMasuk = true;
}
}
void cekLampuKandang()
{
int gelapkandang = analogRead(lampuDalamLDR);
if(gelapkandang < 800)
{
digitalWrite (lampudalam, HIGH);
delay(1000);
}
else
{
digitalWrite (lampudalam, LOW);
delay(1000);
}
}
void cekLampuLuar()
{
int gelapluar = digitalRead(lampuLuarLDR);
if(gelapluar < 200)
{
analogWrite (lampuluar, HIGH);
delay(1000);
}
else
{
digitalWrite (lampuluar, LOW);
delay(1000);
}
}
void cekSuhuKelembaban()
{
float t = dhtSuhu.getTemperature();
float h = dhtSuhu.getHumidity();
tb.sendTelemetryFloat("Temperature", t);
tb.sendTelemetryFloat("Humidity", h);
if(t > 24 )
{
tone(buzzpin,1500, 250);
digitalWrite(kipasAngin, HIGH);
digitalWrite(exhauseFan, HIGH);
digitalWrite(pengkabut, HIGH);
digitalWrite(pemanas, LOW);
// delay(1000);
} else
{
tone(buzzpin,1500, 250);
digitalWrite(pemanas, HIGH);
digitalWrite(exhauseFan, HIGH);
digitalWrite(pengkabut, LOW);
// delay(1000);
}
if(h > 70 )
{
tone(buzzpin,1000,250);
digitalWrite(kipasAngin, HIGH);
digitalWrite(exhauseFan, HIGH);
digitalWrite(pengkabut, HIGH);
digitalWrite(pemanas, HIGH);
// delay(1000);
} else
{
tone(buzzpin,1000, 250);
digitalWrite(pemanas, LOW);
digitalWrite(pengkabut, LOW);
digitalWrite(exhauseFan, HIGH);
// delay(1000);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Suhu & Kelembaban");
lcd.setCursor(0,1);
lcd.print("Temp: " + String(t, 2) + "°C");
lcd.setCursor(0,2);
lcd.print("Humidity: " + String(h, 1) + "%");
delay(1000);
}
void cekAmoniaCO2()
{
float a = dhtGas.getTemperature(); // amonia
float c = dhtGas.getHumidity(); // co2
tb.sendTelemetryFloat("CO2", c);
tb.sendTelemetryFloat("amonia", a);
if (a > 25)
{
tone(buzzpin,1750, 250);
digitalWrite(kipasAngin, HIGH);
digitalWrite(exhauseFan, HIGH);
digitalWrite(fanAmonia, HIGH);
// delay(1000);
}
else
{
tone(buzzpin,1750, 250);
digitalWrite(pemanas, LOW);
digitalWrite(pengkabut, LOW);
digitalWrite(exhauseFan, HIGH);
// delay(1000);
}
if (c > 50)
{
tone(buzzpin,1950, 250);
digitalWrite(kipasAngin, HIGH);
digitalWrite(exhauseFan, HIGH);
digitalWrite(fanCO2, HIGH);
// delay(1000);
}
else
{
tone(buzzpin,1950, 250);
digitalWrite(pemanas, LOW);
digitalWrite(pengkabut, LOW);
digitalWrite(exhauseFan, LOW);
// delay(1000);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Amonia & CO2");
lcd.setCursor(0,1);
lcd.print("Amonia: " + String(a, 2) + "ppm");
lcd.setCursor(0,2);
lcd.print("CO2 : " + String(c, 1) + "%");
delay(1000);
}
void cekPenyusup()
{
// millis_check = millis();
// jika delta 5 menit, lanjut loop, jika tidak
// Serial.println("millis_cekPenyusup_sblm:" + String(millis_cekPenyusup_sblm) );
if(delay_milis(millis_cekPenyusup_sblm,5000) || millis_cekPenyusup_sblm ==0.0 ){
unsigned long delta = millis_cekPenyusup_sblm - millis() ;
millis_cekPenyusup_sblm = millis();
// Serial.println("millis_cekPenyusup_sblm:" + String(millis_cekPenyusup_sblm) );
// Serial.println("delta reach 5 minutes");
int val = digitalRead(pinPIR);
if (val == HIGH) {
if (PIRState == LOW) {
tone(buzzpin, 800, 150);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Motion detected!");
Serial.println("Motion Detected:" + String(millis_cekPenyusup_sblm) + "|" + String( millis() ) + "|" + String( delta ) );
PIRState = HIGH;
digitalWrite(pinPIR, HIGH);
// delay(1000);
}
} else {
if (PIRState == HIGH) {
tone(buzzpin,800,150);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Motion ended!");
Serial.println("Motion ended:" + String(millis_cekPenyusup_sblm) + "|" + String( millis() ) + "|" + String( delta ) );
Serial.println("---------------" );
PIRState = LOW;
// delay(1000);
}
}
}
}