#define BLYNK_TEMPLATE_ID   "TMPL45BlzYkp9"
#define BLYNK_TEMPLATE_NAME "TemperatureRelay"
#define BLYNK_AUTH_TOKEN    "1roCHsL4MLO24Q-JqysPVjzeJjKEhZOe"
#define BLYNK_PRINT Serial
#define BLYNK_TEMP_1 V0
#define BLYNK_TEMP_2 V1
#define BLYNK_TEMP_3 V2
#define BLYNK_RELAY_1 V3
#define BLYNK_RELAY_2 V4
#define BLYNK_RELAY_3 V5
#define BLYNK_RELAY_4 V6
#define BLYNK_RELAY_5 V7
#define BLYNK_RELAY_6 V8
#define BLYNK_RELAY_7 V9
#define BLYNK_RELAY_8 V10
#define BLYNK_TEMP_SETTING V11

#include <Arduino.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <OneButton.h>
#include <PCF8575.h>

#if defined(ESP8266)
    #include <ESP8266WiFi.h>
    #include <BlynkSimpleEsp8266.h>
    #define ONE_WIRE_BUS D5
    #define T_INC_BUTTON D8
    #define T_DEC_BUTTON D7
    #define RESET_BUTTON D6
#elif defined(ESP32)
    #include <WiFi.h>
    #include <WiFiClient.h>
    #include <BlynkSimpleEsp32.h>
    #define ONE_WIRE_BUS 15
    #define T_INC_BUTTON 20
    #define T_DEC_BUTTON 21
    #define RESET_BUTTON 19
#else
    #error "ESP8266 or ESP32 only!"
#endif

#define RELAY_R1 0
#define RELAY_R2 1
#define RELAY_R3 2
#define RELAY_R4 3
#define RELAY_R5 4
#define RELAY_R6 5
#define RELAY_R7 6
#define RELAY_R8 7
#define BUTTON_G1 8
#define BUTTON_G2 9
#define BUTTON_G3 10
#define BUTTON_G4 11
#define BUTTON_Z1 12
#define BUTTON_Z2 13
#define BUTTON_Z3 14

#define T_SENSOR_LCD     0
#define T_SENSOR_BLYNK_2 1
#define T_SENSOR_BLYNK_3 2
#define NO_OF_RELAYS 8
#define NO_OF_RELAY_BUTTONS 7
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASS ""


LiquidCrystal_I2C lcd(0x27, 16, 2);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature temperatureSensors(&oneWire);
OneButton tIncButton(T_INC_BUTTON);
OneButton tDecButton(T_DEC_BUTTON);
OneButton resetButton(RESET_BUTTON);
PCF8575 pcf8575(0x20);

float tLcd = 0.0f;
float tZad = 60.0;
bool relaysState[NO_OF_RELAYS];
bool lastButtonState[NO_OF_RELAY_BUTTONS];
bool isRelay1Locked = true;


float getTemperature(uint8_t sensorID)
{
    float t = temperatureSensors.getTempCByIndex(sensorID);

    if (t == DEVICE_DISCONNECTED_C)
    {
        t = 0.0f;
    }

    return t;
}

void updateLcd()
{
    String akt = "AKT:" + String(tLcd, 1) + "C";
    String zad = "ZAD:" + String(tZad, 1) + "C";
    String r1 = "R1:" + String(relaysState[0] ? "ON" : "OFF");
    String g = "G ";

    for (uint8_t i = 0; i < 4; i++)
    {
        g += String(relaysState[1 + i] ? "1" : "0");
    }

    while(akt.length() < 10) akt += ' ';
    while(zad.length() < 10) zad += ' ';
    while(r1.length() < 6) r1 += ' ';
    while(g.length() < 6) g += ' ';

    lcd.setCursor(0, 0);
    lcd.print(akt);
    lcd.print(r1);
    lcd.setCursor(0, 1);
    lcd.print(zad);
    lcd.print(g);
}

void duringLongPress(void *button)
{
    OneButton* btn = (OneButton*)button;

    tZad += btn->pin() == T_INC_BUTTON ? 3 : -3;
    tZad = constrain(tZad, 5.0, 100.0);
    Blynk.virtualWrite(BLYNK_TEMP_SETTING, tZad);
    updateLcd();
}

void buttonPress(void *button)
{
    OneButton* btn = (OneButton*)button;

    if (btn->pin() == RESET_BUTTON)
    {
        isRelay1Locked = false;
    }
    else
    {
        tZad += btn->pin() == T_INC_BUTTON ? 1 : -1;
        tZad = constrain(tZad, 5.0, 100.0);
        Blynk.virtualWrite(BLYNK_TEMP_SETTING, tZad);
        updateLcd();
    }
}

void updateCurrentTemperature()
{
    static unsigned long lastUpdate = 0;

    if (millis() - lastUpdate >= 500)
    {
        lastUpdate = millis();
        temperatureSensors.requestTemperatures();
        tLcd = getTemperature(T_SENSOR_LCD);

        Blynk.virtualWrite(BLYNK_TEMP_2, getTemperature(T_SENSOR_BLYNK_2));
        Blynk.virtualWrite(BLYNK_TEMP_3, getTemperature(T_SENSOR_BLYNK_3));
        Blynk.virtualWrite(BLYNK_TEMP_1, tLcd);

        bool lastRelay1State = relaysState[0];
        relaysState[0] = (tLcd < tZad);

        if (lastRelay1State && !relaysState[0])
        {
            isRelay1Locked = true;
        }

        if (isRelay1Locked)
        {
            relaysState[0] = false;
        }

        pcf8575.write(RELAY_R1, relaysState[0]);
        updateLcd();
    }
}

BLYNK_WRITE(BLYNK_RELAY_1)
{
    if (relaysState[0] == true)
    {
        relaysState[0] = false;
        isRelay1Locked = true;
        Blynk.virtualWrite(BLYNK_RELAY_1, false);
        pcf8575.write(RELAY_R1, relaysState[0]);
        updateLcd();
    }
}

BLYNK_WRITE(BLYNK_RELAY_2)
{
    relaysState[1] = (param.asInt() == 1);
    pcf8575.write(RELAY_R2, relaysState[1]);
    updateLcd();
}

BLYNK_WRITE(BLYNK_RELAY_3)
{
    relaysState[2] = (param.asInt() == 1);
    pcf8575.write(RELAY_R3, relaysState[2]);
    updateLcd();
}

BLYNK_WRITE(BLYNK_RELAY_4)
{
    relaysState[3] = (param.asInt() == 1);
    pcf8575.write(RELAY_R4, relaysState[3]);
    updateLcd();
}

BLYNK_WRITE(BLYNK_RELAY_5)
{
    relaysState[4] = (param.asInt() == 1);
    pcf8575.write(RELAY_R5, relaysState[4]);
    updateLcd();
}

BLYNK_WRITE(BLYNK_RELAY_6)
{
    relaysState[5] = (param.asInt() == 1);
    pcf8575.write(RELAY_R6, relaysState[5]);
    updateLcd();
}

BLYNK_WRITE(BLYNK_RELAY_7)
{
    relaysState[6] = (param.asInt() == 1);
    pcf8575.write(RELAY_R7, relaysState[6]);
    updateLcd();
}

BLYNK_WRITE(BLYNK_RELAY_8)
{
    relaysState[7] = (param.asInt() == 1);
    pcf8575.write(RELAY_R8, relaysState[7]);
    updateLcd();
}

BLYNK_WRITE(BLYNK_TEMP_SETTING)
{
    tZad = param.asInt();
    updateLcd();
}

void setup()
{
    Serial.begin(9600);

    lcd.init();
    lcd.backlight();
    lcd.print("Connecting...");

    temperatureSensors.begin();

    Wire.begin();
    pcf8575.begin();
    pcf8575.write16(0x0000);

    for (uint8_t i = 0; i < NO_OF_RELAYS; i++)
    {
        relaysState[i] = false;
    }

    for (uint8_t i = 0; i < NO_OF_RELAY_BUTTONS; i++)
    {
        lastButtonState[i] = false;
    }

    tIncButton.attachDuringLongPress(duringLongPress, &tIncButton);
    tDecButton.attachDuringLongPress(duringLongPress, &tDecButton);
    tIncButton.attachClick(buttonPress, &tIncButton);
    tDecButton.attachClick(buttonPress, &tDecButton);
    resetButton.attachClick(buttonPress, &resetButton);
    tIncButton.setLongPressIntervalMs(1000);
    tDecButton.setLongPressIntervalMs(1000);

    Blynk.begin(BLYNK_AUTH_TOKEN, WIFI_SSID, WIFI_PASS);
    Blynk.virtualWrite(BLYNK_RELAY_1, 0);
    Blynk.virtualWrite(BLYNK_RELAY_2, 0);
    Blynk.virtualWrite(BLYNK_RELAY_3, 0);
    Blynk.virtualWrite(BLYNK_RELAY_4, 0);
    Blynk.virtualWrite(BLYNK_RELAY_5, 0);
    Blynk.virtualWrite(BLYNK_RELAY_6, 0);
    Blynk.virtualWrite(BLYNK_RELAY_7, 0);
    Blynk.virtualWrite(BLYNK_RELAY_8, 0);
    Blynk.virtualWrite(BLYNK_TEMP_SETTING, tZad);
}

void loop()
{
    pcf8575.write(0, pcf8575.read(BUTTON_G1));
    pcf8575.write(1, pcf8575.read(BUTTON_G2));
    delay(100);

    // Blynk.run();
    // tDecButton.tick();
    // tIncButton.tick();
    // resetButton.tick();

    // for (uint8_t i = 0; i < NO_OF_RELAY_BUTTONS; i++)
    // {
    //     bool currentButtonState = pcf8575.readButton(BUTTON_G1 + i);
        
    //     if (currentButtonState != lastButtonState[i])
    //     {
    //         lastButtonState[i] = currentButtonState;

    //         if (!currentButtonState)
    //         {
    //             relaysState[1 + i] = !relaysState[1 + i];
    //             pcf8575.write(RELAY_R2 + i, relaysState[1 + i]);
    //             Blynk.virtualWrite(BLYNK_RELAY_2 + i, relaysState[1 + i]);
    //         }

    //         delay(10);
    //     }
    // }

    // updateCurrentTemperature();
}
Loading
esp32-s2-devkitm-1
Loading
ds18b20
Loading
ds18b20
Loading
ds18b20
pcf8575Breakout