#include "incubator_cfg.h"
LiquidCrystal_I2C lcd(0x27, LCD_ROW_LEN ,LCD_COLUMN_LEN); // set the LCD address to 0x27 for a 16 chars and 2 line display
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 rtc;
TaskHandle_t Task1;
TaskHandle_t Task2;
float cur_TEMP = 0, cur_HUM = 0;
time_t last_time_sec = 1715640024; //future edit
uint32_t motorON_sec = 0 ;
uint8_t MenuButtonState = 0;
uint8_t IncButtonState = 0;
uint8_t DecButtonState = 0;
uint32_t MenuB_On_time = 0;
uint32_t IncB_On_time = 0;
uint32_t DecB_On_time = 0;
uint8_t TERMINATE_TASK_1 = 0;
uint8_t LOCK_LCD_USAGE = 0;
Button menu_pin= {"MenuPin",MENU_PIN_NUM, 0, false, true, 0, 0, 0};
Button inc_pin = {"IncPin", INCREASE_PIN_NUM, 0, false, true, 0, 0, 0};
Button dec_pin = {"DecPin", DECREASE_PIN_NUM, 0, false, true, 0, 0, 0};
uint8_t set_hour = 0, set_min = 0, set_sec = 25; //future edit
uint8_t motorDealy_min = 0, motorDealy_sec = 10; //future edit.
float max_temp = 40, min_temp = 35, max_hum = 80, min_hum = 60; //future edit
void console_print(char* print_str)
{
Serial.print(print_str);
}
void lcd_init()
{
lcd.init();
lcd.backlight();
}
void dht_init()
{
dht.begin();
}
void FS_init()
{
if (FILE_SYSTEM.begin(true))
{
Serial.println("FILE SYSTEM BEGIN SUCCESSFULL :)");
}
else
{
Serial.println("FILE SYSTEM BEGIN FAILED !!!");
}
File fp_1 = FILE_SYSTEM.open( "sample.txt" , "w");
if(!fp_1)
{
Serial.printf("Failed to open for Writing !!!\n");
}
}
void rtc_init()
{
if (! rtc.begin())
{
Serial.println("Couldn't find RTC");
Serial.flush();
}
else
{
Serial.println("RTC BEGIN SUCCESSFUL");
}
if (! rtc.isrunning())
{
Serial.println("RTC is NOT running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void init_system()
{
for(int cnt =0 ; cnt < LCD_ROW_LEN -strlen(LOADING_STR_NAME) ; cnt++)
{
switch(cnt)
{
case 0:
{
console_print("Initializing LCD...\n");
lcd_init();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(LOADING_STR_NAME);
break;
}
case 1:
{
console_print("Initializing DHT sensor...\n");
dht_init();
break;
}
case 2:
{
console_print("Initializing File system...\n");
FS_init();
break;
}
case 3:
{
console_print("Initializing RTC...\n");
rtc_init();
break;
}
}
lcd.setCursor(strlen(LOADING_STR_NAME) + cnt, 0);
lcd.print(".");
delay(50);
}
}
void dht_read()
{
float cal_t = 1.0;
float cal_h = 1.0;
float h = dht.readHumidity();
float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
cur_TEMP = (t-cal_t);
cur_HUM = (h-cal_h);
if (isnan(h) || isnan(t))
{
Serial.println("Failed to read from DHT sensor !!!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Failed To");
lcd.setCursor(0, 1);
lcd.print("Read Sensor!");
lcd.clear();
lcd.setCursor(0, 0);
return;
}
char lcd_buf[LCD_BUF_SIZE];
memset(&lcd_buf, 0 , LCD_BUF_SIZE);
sprintf(lcd_buf, "T:%0.2f H:%0.2f",cur_TEMP, cur_HUM);
if(LOCK_LCD_USAGE != 1)
{
// lcd.clear();
lcd.setCursor(0, 0);
strncat(lcd_buf, SPACE_STRING,LCD_BUF_SIZE-strlen(lcd_buf)-1);
lcd.print(lcd_buf);
}
Serial.printf("DHT DATUM : cur_TEMP: %f cur_HUM: %f\n",cur_TEMP, cur_HUM);
Serial.printf("max_temp : %f min_temp: %f\n",max_temp,min_temp);
if(cur_TEMP < min_temp)
{
// Masukan Perintah
// lcd.setCursor(0, 1);
// lcd.print("Alert! Temp high");
Serial.printf("Alert! Temp LOW\n");
digitalWrite(HEATER_PIN, HIGH);
}
if(cur_TEMP > max_temp)
{
// Masukan Perintah
// lcd.setCursor(0, 1);
// lcd.print("Alert! Temp high");
Serial.printf("Alert! Temp HIGH\n");
digitalWrite(HEATER_PIN, LOW);
}
if(cur_HUM < min_hum)
{
Serial.printf("Alert! Hum LOW\n");
digitalWrite(HUMIDIFIER_PIN, HIGH);
}
if(cur_HUM > max_hum)
{
// Masukan Perintah
// lcd.setCursor(0, 1);
// lcd.print("Alert! Temp high");
Serial.printf("Alert! Hum HIGH\n");
digitalWrite(HUMIDIFIER_PIN, LOW);
}
}
void rtc_read()
{
while(1)
{
DateTime curr_time = rtc.now();
uint32_t curr_sec = curr_time.unixtime();
uint32_t sec_overed = curr_sec-last_time_sec;
Serial.printf("curr_time.unixtime() : %d\n",curr_time.unixtime());
//Full Timestamp
Serial.println(String("DateTime::TIMESTAMP_FULL:\t")+curr_time.timestamp(DateTime::TIMESTAMP_FULL));
//Date Only
Serial.println(String("DateTime::TIMESTAMP_DATE:\t")+curr_time.timestamp(DateTime::TIMESTAMP_DATE));
//Full Timestamp
Serial.println(String("DateTime::TIMESTAMP_TIME:\t")+curr_time.timestamp(DateTime::TIMESTAMP_TIME));
Serial.println("\n");
uint32_t wait_sec = (set_hour * 3600) + (set_min * 60) + set_sec;
uint32_t sec_left = wait_sec - sec_overed;
Serial.printf("SEC left : %d\n",sec_left);
uint8_t hour = (sec_left/3600);
uint8_t min = (sec_left%3600 ) / 60;
uint8_t sec = (sec_left%3600 ) % 60;
Serial.printf("REMAINING hr: %d min: %d sec: %d\n",hour, min, sec);
if(LOCK_LCD_USAGE != 1)
{
lcd.setCursor(0, 1);
}
char lcd_buf[LCD_BUF_SIZE];
memset(&lcd_buf, 0, LCD_BUF_SIZE);
if(sec_overed >= wait_sec)
{
uint16_t motorDelay_sec = (motorDealy_min * 60) + motorDealy_sec;
Serial.printf("curr_sec : %u motor_on_sec : %u motorDelay_sec : %u\n",curr_sec,motorON_sec,motorDelay_sec);
if(motorON_sec == 0)
{
motorON_sec = curr_sec;
digitalWrite(MOTOR_PIN, HIGH);
Serial.printf("MOTOR ON\n");
}
else if ( (curr_sec - motorON_sec) >= motorDelay_sec)
{
digitalWrite(MOTOR_PIN, LOW);
curr_time = rtc.now();
last_time_sec = curr_time.unixtime();
motorON_sec = 0;
Serial.printf("MOTOR OFF\n");
continue;
}
min = (motorDelay_sec - (curr_sec - motorON_sec)) / 60;
sec = (motorDelay_sec - (curr_sec - motorON_sec)) %60;
Serial.printf("curr_sec : %u motor_on_sec : %u motorDelay_sec : %u\n",curr_sec,motorON_sec,motorDelay_sec);
sprintf(lcd_buf, "M ON [%02u:%02u]",min, sec);
// Serial.printf("MIN : %02u sec : %02u\n",min, sec);
}
else
{
sprintf(lcd_buf, "M OFF %02u:%02u:%02u",hour, min, sec);
}
strncat(lcd_buf, SPACE_STRING,LCD_BUF_SIZE-strlen(lcd_buf)-1);
if(LOCK_LCD_USAGE != 1)
{
lcd.print(lcd_buf);
}
Serial.printf("RTC LCD PRINTED DATUM : ==%s==\n",lcd_buf);
break;
}
}
void factory_reset()
{
TERMINATE_TASK_1 = 1;
delay(1000);
Serial.printf("Factory Resetting ");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(RESETTING_STR_NAME);
for(int cnt =0 ; cnt < LCD_ROW_LEN -strlen(RESETTING_STR_NAME) ; cnt++)
{
//...........
//future work
//..........
lcd.setCursor(strlen(RESETTING_STR_NAME) + cnt, 0);
lcd.print(".");
delay(1000);
Serial.printf(".");
}
lcd.clear();
Serial.printf("\n>> RESTARTING DEVICE <<\n");
delay(2000);
ESP.restart();
}
void buttons_read()
{
// Serial.println("\n\nFree HEAP memory AT STARTING THE PROGRAM : " + String(xPortGetFreeHeapSize()) + " bytes");
// if (menu_pin.pressed)
// {
// Serial.printf("MENU button has been pressed %lu times\n", menu_pin.numberKeyPresses);
// menu_pin.pressed = false;
// }
// if (inc_pin.pressed)
// {
// Serial.printf("INC button has been pressed %lu times\n", inc_pin.numberKeyPresses);
// inc_pin.pressed = false;
// }
// if (dec_pin.pressed)
// {
// Serial.printf("DEC button has been pressed %lu times\n", dec_pin.numberKeyPresses);
// dec_pin.pressed = false;
// }
if( ( (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) > 5000) ) &&
( (inc_pin.pressed == true) && ((millis() -inc_pin.pressed_time) > 5000) ) &&
( (dec_pin.pressed == true) && ((millis() -dec_pin.pressed_time) > 5000) ) )
{
Serial.printf("MENU button pressed time : %ld curr_time : %ld pressed %lu times\n", menu_pin.pressed_time, millis(), menu_pin.numberKeyPresses);
factory_reset();
}
if ( (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) > 2500) )
{
uint8_t SET_EN = 0, blynk_pos= 0, first_tym = 1, digit_start_pos =0 , digit_len =0;
uint32_t last_blnk_time = 0;
LOCK_LCD_USAGE =1;
char lcd_buf[LCD_BUF_SIZE];
int display_state = 1;
int menu_key_prs_cnt = menu_pin.numberKeyPresses;
int inc_key_prs_cnt = inc_pin.numberKeyPresses;
int dec_key_prs_cnt = dec_pin.numberKeyPresses;
lcd.clear();
char min_temp_str[8], max_temp_str[8], min_hum_str[8], max_hum_str[8];
memset(min_temp_str, 0, sizeof(min_temp_str));
memset(max_temp_str, 0, sizeof(max_temp_str));
memset(min_hum_str , 0, sizeof(min_hum_str));
memset(max_hum_str , 0, sizeof(max_hum_str));
sprintf(min_temp_str, "%0.3f",min_temp);
sprintf(max_temp_str, "%0.3f",max_temp);
sprintf(min_hum_str, "%0.3f",min_hum);
sprintf(max_hum_str, "%0.3f",max_hum);
char *str_ptr;
while(1) //BUTTON MAIN
{
lcd.setCursor(0, 0);
memset(&lcd_buf, 0, LCD_BUF_SIZE);
switch(display_state)
{
case 1:
// str_ptr = min_temp_str;
// sprintf(str_ptr, "%f", min_temp_str);
snprintf(lcd_buf, LCD_BUF_SIZE, "MinTEMP : %s",min_temp_str); //causing stack err
break;
case 2:
// str_ptr = max_temp_str;
snprintf(lcd_buf, LCD_BUF_SIZE, "MaxTEMP : %s",max_temp_str); //causing stack err
break;
case 3:
// str_ptr = min_hum_str;
snprintf(lcd_buf, LCD_BUF_SIZE, "MinHUM : %s",min_hum_str); //causing stack err
break;
case 4:
// str_ptr = max_hum_str;
snprintf(lcd_buf, LCD_BUF_SIZE, "MaxHUM : %s",max_hum_str); //causing stack err
break;
}
// lcd.print(lcd_buf);
// lcd.print("sanjay");
if(SET_EN == 1)
{
while(first_tym == 1)
{
if(isDigit(lcd_buf[blynk_pos]) == 1)
{
digit_start_pos = blynk_pos;
digit_len = strlen(lcd_buf);
first_tym = 0;
break;
}
blynk_pos++;
}
if( (millis()-last_blnk_time) >= 250 )
{
lcd_buf[blynk_pos] = ' ';
if( (millis()-last_blnk_time) >= 400 )
{
last_blnk_time =millis();
}
}
if( (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) >2500) )
{
Serial.printf("SETTING DATUM...\n");
SET_EN = 0;
first_tym =1;
}
}
lcd.print(lcd_buf);
if( ((millis()-menu_pin.state_ch_time) > 4000) &&
((millis()-inc_pin.state_ch_time) > 4000) &&
((millis()-dec_pin.state_ch_time) > 4000) )
{
Serial.printf("####### Released time: %ld cur time: %ld \n",menu_pin.released_time,millis());
LOCK_LCD_USAGE =0;
break;
}
if ( (SET_EN == 1) && (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) > 2500) )
{
switch(display_state)
{
case 1:
// Serial.printf("SANJAY.... min str : %s\n",min_temp_str);
min_temp = atof(min_temp_str);
// Serial.printf("FLOAT VAL MIN TEMP : %0.3f",min_temp);
// snprintf(lcd_buf, LCD_BUF_SIZE, "MinTEMP : %s",min_temp_str); //causing stack err
break;
case 2:
max_temp = atof(max_temp_str);
// snprintf(lcd_buf, LCD_BUF_SIZE, "MaxTEMP : %s",max_temp_str); //causing stack err
break;
case 3:
min_hum = atof(min_hum_str);
// snprintf(lcd_buf, LCD_BUF_SIZE, "MinHUM : %s",min_hum_str); //causing stack err
break;
case 4:
max_hum = atof(max_hum_str);
// snprintf(lcd_buf, LCD_BUF_SIZE, "MaxHUM : %s",max_hum_str); //causing stack err
break;
}
SET_EN =0;
}
if ( (menu_key_prs_cnt != menu_pin.numberKeyPresses) )
{
menu_key_prs_cnt = menu_pin.numberKeyPresses;
Serial.printf("####### MENU pin Released time: %ld cur time: %ld \n",menu_pin.released_time,millis());
// lcd.clear(); //pos fixed
if(SET_EN == 1)
{
blynk_pos==digit_len-1 ? blynk_pos = digit_start_pos : blynk_pos++;
lcd_buf[blynk_pos] == '.' ? blynk_pos++ : 0;
}
else
{
SET_EN = 1;
}
Serial.printf("Setting Enable : %d\n", SET_EN);
}
if ( (inc_key_prs_cnt != inc_pin.numberKeyPresses) )
{
inc_key_prs_cnt = inc_pin.numberKeyPresses;
Serial.printf("####### INC pin Released time: %ld cur time: %ld \n",inc_pin.released_time,millis());
Serial.printf("SET_EN : %d\n", SET_EN);
if(SET_EN == 0)
{
display_state==4 ? display_state = 1 : display_state++;
lcd.clear(); //pos fixed
}
else
{
Serial.printf("min_temp_str[blynk_pos] : %c\n", min_temp_str[blynk_pos-digit_start_pos]);
// str_ptr[blynk_pos-digit_start_pos] = str_ptr[blynk_pos-digit_start_pos]+1;
// Serial.printf("STR_PTR [%d] : %s\n",blynk_pos-digit_start_pos,str_ptr[0] );
(min_temp_str[blynk_pos-digit_start_pos] == '9' ) ? min_temp_str[blynk_pos-digit_start_pos] = '0':min_temp_str[blynk_pos-digit_start_pos] += 1;
}
// else
// {
// blynk_pos==digit_len-1 ? blynk_pos = digit_start_pos : blynk_pos++;
// }
}
if ( (dec_key_prs_cnt != dec_pin.numberKeyPresses) )
{
dec_key_prs_cnt = dec_pin.numberKeyPresses;
Serial.printf("####### DEC pin Released time: %ld cur time: %ld \n",dec_pin.released_time,millis());
if(SET_EN == 0)
{
display_state==1 ? display_state = 4 : display_state--;
lcd.clear(); //pos fixed
}
else
{
(min_temp_str[blynk_pos-digit_start_pos] == '0' ) ? min_temp_str[blynk_pos-digit_start_pos] = '9':min_temp_str[blynk_pos-digit_start_pos] -= 1;
}
}
// Serial.printf("inside loop \n");
}
// Serial.printf("####### Menu pressed time : %ld curr time : %ld press_num : %d #######33\n",menu_pin.pressed_time, millis(), menu_pin.numberKeyPresses);
}
if(menu_pin.pressed == true)
{
Serial.printf("####### MENU pressed time : %ld curr time : %ld press_num : %d #######33\n",menu_pin.pressed_time, millis(), menu_pin.numberKeyPresses);
}
if(inc_pin.pressed == true)
{
Serial.printf("####### INC pressed time : %ld curr time : %ld press_num : %d #######33\n",inc_pin.pressed_time, millis(), inc_pin.numberKeyPresses);
}
// MenuButtonState = digitalRead(MENU_PIN_NUM);
// IncButtonState = digitalRead(INCREASE_PIN_NUM);
// DecButtonState = digitalRead(DECREASE_PIN_NUM);
// DateTime curr_time = rtc.now(); //pos fixed
// Serial.printf("Button States\nMenu : %d\nINC : %d\nDEC : %d\n",MenuButtonState, IncButtonState, DecButtonState);
// ( (MenuButtonState == true) && (MenuB_On_time == 0) ) ? MenuB_On_time = curr_time.unixtime() : 0;
// ( (IncButtonState == LOW) && (IncB_On_time == 0) ) ? IncB_On_time = curr_time.unixtime() : 0;
// ( (DecButtonState == LOW) && (DecB_On_time == 0) ) ? DecB_On_time = curr_time.unixtime() : 0;
// ( (MenuButtonState == HIGH) && (MenuB_On_time != 0) ) ? MenuB_On_time = 0 : 0;
// ( (IncButtonState == HIGH) && (IncB_On_time != 0) ) ? IncB_On_time = 0 : 0;
// ( (DecButtonState == HIGH) && (DecB_On_time != 0) ) ? DecB_On_time = 0 : 0;
// if ( (MenuButtonState == LOW) && (IncButtonState == LOW) && (DecButtonState == LOW))
// {
// curr_time = rtc.now();
// if ( ((curr_time.unixtime()-MenuB_On_time) > 120) && ((curr_time.unixtime()-IncButtonState) > 120) && ((curr_time.unixtime()-DecButtonState) > 120) )
// {
// factory_reset();
// }
// }
// Serial.println("\n\nFree HEAP memory AT ENDING THE PROGRAM : " + String(xPortGetFreeHeapSize()) + " bytes");
// Serial.printf("Button States\nMenu : %d\nINC : %d\nDEC : %d\n",MenuButtonState, IncButtonState, DecButtonState);
// Serial.printf("PRITINNG NOTHING\n");
// delay(200);
return;
}
void ARDUINO_ISR_ATTR isr(void *arg)
{
Button *s = static_cast<Button *>(arg);
if( (s->released == true) && ((millis()-s->state_ch_time) > 5))
{
s->pressed = true;
s->released = false;
s->pressed_time = millis();
s->state_ch_time = millis();
s->numberKeyPresses += 1;
}
else if( (s->pressed == true) && ((millis()-s->state_ch_time) > 5))
{
s->released = true;
s->pressed = false;
s->released_time = millis();
s->state_ch_time = millis();
// s->numberKeyPresses += 1;
}
Serial.printf("############# %s is pressed ###########\n",s->pin_name);
}
//Task1code
void Task1code( void * pvParameters )
{
while (!TERMINATE_TASK_1)
{
Serial.printf("CORE_%d : Reading DHT data\n", xPortGetCoreID());
dht_read();
rtc_read();
delay(800);
}
Serial.printf("CORE_%d : TASK 1 Terminated Successfully\n");
while(1)
{
delay(10000);
}
}
//Task2code
void Task2code( void * pvParameters )
{
while(1)
{
Serial.printf("CORE_%d : Reading BUTTONS state\n", xPortGetCoreID());
buttons_read();
// static uint32_t lastMillis = 0;
// if (millis() - lastMillis > 10000)
// {
// printf("*********** checking ***********\n");
// lastMillis = millis();
// // detachInterrupt(menu_pin.PIN);
// // detachInterrupt(inc_pin.PIN);
// // detachInterrupt(dec_pin.PIN);
// }
// Serial.printf("HLO TN....\n");
delay(100);
}
}
void init_tasks()
{
//create a task that will be executed in the Task1code() function,
//with priority 1 and executed on core 0
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, // Task handle to keep track of created task
0 /* pin task to core 0 */
);
delay(500);
//Task 2 on core 1
xTaskCreatePinnedToCore(
Task2code, /* Task function. */
"Task2", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task2, /* Task handle to keep track of created task */
1); /* pin task to core 1 */
delay(500);
}
void setup()
{
Serial.begin(115200);
pinMode(MENU_PIN_NUM, INPUT_PULLUP );
attachInterruptArg(menu_pin.pin_num, isr, &menu_pin, CHANGE);
pinMode(INCREASE_PIN_NUM, INPUT_PULLUP );
attachInterruptArg(inc_pin.pin_num, isr, &inc_pin, CHANGE);
pinMode(DECREASE_PIN_NUM, INPUT_PULLUP );
attachInterruptArg(dec_pin.pin_num, isr, &dec_pin, CHANGE);
Serial.printf("PIN: %d\tpin nam: %s\n",menu_pin.pin_num, menu_pin.pin_name);
Serial.printf("PIN: %d\tpin nam: %s\n",inc_pin.pin_num, inc_pin.pin_name);
Serial.printf("PIN: %d\tpin nam: %s\n",dec_pin.pin_num, dec_pin.pin_name);
pinMode(MOTOR_PIN, OUTPUT);
pinMode(HEATER_PIN, OUTPUT);
pinMode(HUMIDIFIER_PIN, OUTPUT);
digitalWrite(MOTOR_PIN, LOW);
digitalWrite(HEATER_PIN, LOW);
digitalWrite(HUMIDIFIER_PIN, LOW);
init_system();
init_tasks();
}
void loop() //dummy won't work
{
delay(100);
}