Untitled

 avatar
unknown
plain_text
2 years ago
5.3 kB
11
Indexable
#include <Arduino.h>

// dht sensor
#include <DHTesp.h>
DHTesp dht;
#define dht_pin 32

// mq sensor
#include <MQUnifiedsensor.h>
#define vres 3.3
#define mq_pin 35
#define ADC_Bit_Resolution 12
#define RatioMQ135CleanAir 3.6
MQUnifiedsensor MQ135("ESP-32", vres, ADC_Bit_Resolution, mq_pin, "MQ-135");

// save data like eeprom
#include <Preferences.h>
Preferences preferences;

// wifi
#include <WiFi.h>
WiFiClient espClient;
char ssid[] = "Silas";
char pass[] = "silas123";

// esp32 ntp
#include <WiFiUdp.h>
#include <NTPClient.h>
#define WIB 25200
WiFiUDP espudp;
NTPClient moment(espudp);
int day_temp;
int days;

// dimmer
#include <RBDdimmer.h>
#define heat_pin 4
#define zerocross 5
dimmerLamp heat(heat_pin, zerocross);

// pid
#include "PID.h"
PIDController pid;
float kp = 2; // sensor error reading
float ki = 5; // output power
float kd = 1;

// exhaust
#define exhaust_pin 4

//fan
#define fan_pin 26

// wdt
#include <esp_task_wdt.h>

// lcd
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

void set_fan(float suhu) {
    if (!isnan(suhu)) {
        if (suhu < pid.getpoint())
            digitalWrite(fan_pin, 1);
        else digitalWrite(fan_pin, 0);
    }
}

void set_heat(float suhu) {
    if(!isnan(suhu)) { 
        int pid_output = pid.compute(int(suhu));
        Serial.println("temp: " + String(suhu));
        Serial.println("pid output: " + String(pid_output));
        heat.setPower(pid_output);
    }
    else Serial.print("nan");
}

void set_exhaust(float NH4) {
    if(NH4 >= 10.0) digitalWrite(exhaust_pin, 1);
    else digitalWrite(exhaust_pin, 0);
}

void set_lcd(float temp, float hum, float am) {
    lcd.setCursor(0, 0);
    lcd.print("t: " + String(temp) + "C | h: " + String(hum) + "%");

    lcd.setCursor(0, 1);
    lcd.print("NH4: " + String(am) + "ppm");
    
    lcd.setCursor(0, 2);
    lcd.print(" kp     ki     kd");
    
    lcd.setCursor(0, 3);
    lcd.print(String(kp) + " " + String(ki) + " " + String(kd));
}

void mq_calibrate() {
    Serial.print("Calibrating MQ135 please wait.");
    float calcR0 = 0;
    for(int i = 1; i<=10; i ++)
    {
        MQ135.update();
        calcR0 += MQ135.calibrate(RatioMQ135CleanAir);
        Serial.print(".");
    }
    MQ135.setR0(calcR0/10);
    Serial.println("  done!");
}

/**
 * @brief ini le buat setting setpoint rtcnya disini. ini gapake rtc, pakenya jam ntp dari internet
 * 
 */
void check_day() {
    int day = moment.getDay();
    if(day != day_temp) {
        day_temp = day;
        days++;
    }

    // misalnya ini hari pertama sampai hari ke2
    if(days >= 0 && days <= 2) pid.setpoint(32);

    // misalnya ini hari ke3 sampai hari ke4
    else if(days > 2 && days <= 4) pid.setpoint(31);

    // misalnya ini hari ke5 sampai hari ke7
    else if(days > 4 && days <= 7) pid.setpoint(30);
}

void startTaskOnCore(TaskFunction_t task, const char taskname[], BaseType_t cpu_number) {
    xTaskCreatePinnedToCore(
        task,
        taskname,
        configMINIMAL_STACK_SIZE * 6, NULL, 2 | portPRIVILEGE_BIT,
        NULL,
        cpu_number
    );
}

/**
 * @brief ini kalo lu mau masukin program tambahan buatan sendiri biar ga ganggu main program.
 * 
 */
void second_core(void *args) {
    // anggap aja void setup disini. contoh:
    Serial.println("void setupnya");

    while(1) {
        // anggap aja void loop disini kalo butuh, kalo ngga dibiarin aja.
    }
}

void first_core(void *args) {
    heat.begin(NORMAL_MODE, ON);
    heat.setPower(0);

    lcd.init();
    lcd.backlight();

    MQ135.setRegressionMethod(1);
    MQ135.setA(102.2);
    MQ135.setB(-2.473);
    MQ135.init(); 
    mq_calibrate();

    pid.begin();
    pid.setpoint(32);
    pid.tune(kp, ki, kd);
    pid.limit(0, 100);

    pinMode(exhaust_pin, OUTPUT);

    dht.setup(dht_pin, DHTesp::DHT11);

    moment.begin();
    moment.setTimeOffset(WIB);

    while(1) {
        TempAndHumidity dht_data = dht.getTempAndHumidity();
        MQ135.update();
        moment.update();
        check_day();

        float temperature = dht_data.temperature;
        float humidity = dht_data.humidity;
        float NH4 = MQ135.readSensor();

        set_lcd(temperature, humidity, NH4);
        set_fan(temperature);
        set_heat(temperature);
        set_exhaust(NH4);

        Serial.println(
            String(moment.getFormattedTime()) + " - "
            + String(temperature) + "°C, " 
            + String(humidity) + "%, "
            + String(NH4) + "ppm"
        );

        vTaskDelay(1000);
    }
}

void setup() {
    Serial.begin(9600);
    startTaskOnCore(&first_core, "main_task", PRO_CPU_NUM);
    startTaskOnCore(&second_core, "fleet_task", PRO_CPU_NUM);

    Serial.print("Connecting to WiFi");
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        Serial.print(".");
    }
    Serial.println(" Connected!");

    // https://randomnerdtutorials.com/esp32-save-data-permanently-preferences/
    preferences.begin("chicken", false); 

    // watchdog 30 minutes
    esp_task_wdt_init(1800, true);
}

// biarin kosong
void loop() {}
Editor is loading...