Termostat reagujący na najniższą temperaturę z 4 czujników

studzin
Posts: 1
Joined: Thu Dec 26, 2024 2:29 pm

Post

Chcę zrobić zabezpieczenie przeciwzamrożeniowe w oparciu o termostat. Mam rozmieszczone 4 czujniki DS18b20 w różnych miejscach i chcę aby moduł załączył zasilanie jeśli najniższa wartość na dowolnym z nich spadnie poniżej temperatury zadanej. Za bardzo nie wiem jak podstawić zamiast odczytu z jednego DSa zmienną lowestTemp. Kombinowałem z VirtualThermometer, ale bezskutecznie. Mam serdeczną prośbę o pomoc.

Code: Select all

#include <SuplaDevice.h>
#include <supla/storage/eeprom.h>
#include <supla/device/status_led.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/control/hvac_base.h>
#include <supla/clock/clock.h>
#include <supla/network/html/time_parameters.h>
#include <supla/network/html/hvac_parameters.h>
#include <supla/control/internal_pin_output.h>
#include <supla/events.h>
#include <supla/actions.h>
#include <supla/control/button.h>
#include <supla/sensor/virtual_thermometer.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>



#define Przekaznik1_GPIO 2
#define DS18B20_GPIO 4

Supla::ESPWifi wifi("x", "x");
Supla::Eeprom eeprom;

// Tworzenie obiektów do komunikacji z czujnikami
OneWire oneWire(DS18B20_GPIO);
DallasTemperature sensors(&oneWire);

// Definicje adresów
  DeviceAddress ds1addr = {0x28, 0x56, 0x72, 0x64, 0x10, 0x00, 0x00, 0xB8};
  DeviceAddress ds2addr = {0x28, 0xE3, 0x71, 0x65, 0x10, 0x00, 0x00, 0x95};
  DeviceAddress ds3addr = {0x28, 0x0B, 0x73, 0x64, 0x10, 0x00, 0x00, 0x11};
  DeviceAddress ds4addr = {0x28, 0xFF, 0x4F, 0xAB, 0x6E, 0x18, 0x01, 0x66};

float lowestTemp;


void setup() {
 Serial.begin(115200);
  char GUID[SUPLA_GUID_SIZE] = {0x28,0xCC,0xFE,0x32,0x5F,0x88,0xD8,0x13,0xA7,0xBF,0x70,0x51,0xDE,0x60,0x3B,0x64};

new Supla::Clock;

eeprom.setStateSavePeriod(180000);

auto output = new Supla::Control::InternalPinOutput(Przekaznik1_GPIO);
auto hvac = new Supla::Control::HvacBase(output);

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//  DeviceAddress ds1addr = {0x28, 0x56, 0x72, 0x64, 0x10, 0x00, 0x00, 0xB8};
//  DeviceAddress ds2addr = {0x28, 0xE3, 0x71, 0x65, 0x10, 0x00, 0x00, 0x95};

//  new Supla::Sensor::DS18B20(DS18B20_GPIO, ds1addr);
//  new Supla::Sensor::DS18B20(DS18B20_GPIO, ds2addr);

// If you don't have thermometers, but still want to try how it works,
// comment above lines and uncomment below lines, to configure dummy
// thermometers (they wil report temperature which is configured below)

  auto t1 = new Supla::Sensor::VirtualThermometer;
  auto t2 = new Supla::Sensor::VirtualThermometer;
  t1->setValue(21.3);
  t2->setValue(22.4);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


// Konfiguracja parametrów termostatu
  hvac->setMainThermometerChannelNo(1);     // Main Thermometer DS1
  hvac->setTemperatureHisteresisMin(20);  // 0.2 degree
  hvac->setTemperatureHisteresisMax(1000);  // 10 degree
  hvac->setTemperatureHisteresis(40);

  SuplaDevice.setName("Termostat");
  SuplaDevice.begin(21); // Thermostat requires proto version >= 21

    SuplaDevice.begin(GUID,              // Global Unique Identifier 
                  "x",  // SUPLA server address
                  "x",   // Email address used to login to Supla Cloud
                  "x");          // Authorization key
}

void loop() {

  // Odczyt temperatur z każdego czujnika
  float temp1 = sensors.getTempC(ds1addr);  // Czujnik 1
  float temp2 = sensors.getTempC(ds2addr);  // Czujnik 2
  float temp3 = sensors.getTempC(ds3addr);  // Czujnik 3
  float temp4 = sensors.getTempC(ds4addr);  // Czujnik 4



  // Znalezienie najniższej temperatury
  lowestTemp = temp1;
  if (temp2 < lowestTemp) lowestTemp = temp2;
  if (temp3 < lowestTemp) lowestTemp = temp3;
  if (temp4 < lowestTemp) lowestTemp = temp4;

SuplaDevice.iterate();

}


[email protected]
Posts: 1585
Joined: Mon Feb 06, 2023 8:56 am
Has thanked: 18 times
Been thanked: 26 times

Post

studzin wrote: Thu Dec 26, 2024 8:43 pm Chcę zrobić zabezpieczenie przeciwzamrożeniowe w oparciu o termostat. Mam rozmieszczone 4 czujniki DS18b20 w różnych miejscach i chcę aby moduł załączył zasilanie jeśli najniższa wartość na dowolnym z nich spadnie poniżej temperatury zadanej. Za bardzo nie wiem jak podstawić zamiast odczytu z jednego DSa zmienną lowestTemp. Kombinowałem z VirtualThermometer, ale bezskutecznie. Mam serdeczną prośbę o pomoc.

Code: Select all

#include <SuplaDevice.h>
#include <supla/storage/eeprom.h>
#include <supla/device/status_led.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/control/hvac_base.h>
#include <supla/clock/clock.h>
#include <supla/network/html/time_parameters.h>
#include <supla/network/html/hvac_parameters.h>
#include <supla/control/internal_pin_output.h>
#include <supla/events.h>
#include <supla/actions.h>
#include <supla/control/button.h>
#include <supla/sensor/virtual_thermometer.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>



#define Przekaznik1_GPIO 2
#define DS18B20_GPIO 4

Supla::ESPWifi wifi("x", "x");
Supla::Eeprom eeprom;

// Tworzenie obiektów do komunikacji z czujnikami
OneWire oneWire(DS18B20_GPIO);
DallasTemperature sensors(&oneWire);

// Definicje adresów
  DeviceAddress ds1addr = {0x28, 0x56, 0x72, 0x64, 0x10, 0x00, 0x00, 0xB8};
  DeviceAddress ds2addr = {0x28, 0xE3, 0x71, 0x65, 0x10, 0x00, 0x00, 0x95};
  DeviceAddress ds3addr = {0x28, 0x0B, 0x73, 0x64, 0x10, 0x00, 0x00, 0x11};
  DeviceAddress ds4addr = {0x28, 0xFF, 0x4F, 0xAB, 0x6E, 0x18, 0x01, 0x66};

float lowestTemp;


void setup() {
 Serial.begin(115200);
  char GUID[SUPLA_GUID_SIZE] = {0x28,0xCC,0xFE,0x32,0x5F,0x88,0xD8,0x13,0xA7,0xBF,0x70,0x51,0xDE,0x60,0x3B,0x64};

new Supla::Clock;

eeprom.setStateSavePeriod(180000);

auto output = new Supla::Control::InternalPinOutput(Przekaznik1_GPIO);
auto hvac = new Supla::Control::HvacBase(output);

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//  DeviceAddress ds1addr = {0x28, 0x56, 0x72, 0x64, 0x10, 0x00, 0x00, 0xB8};
//  DeviceAddress ds2addr = {0x28, 0xE3, 0x71, 0x65, 0x10, 0x00, 0x00, 0x95};

//  new Supla::Sensor::DS18B20(DS18B20_GPIO, ds1addr);
//  new Supla::Sensor::DS18B20(DS18B20_GPIO, ds2addr);

// If you don't have thermometers, but still want to try how it works,
// comment above lines and uncomment below lines, to configure dummy
// thermometers (they wil report temperature which is configured below)

  auto t1 = new Supla::Sensor::VirtualThermometer;
  auto t2 = new Supla::Sensor::VirtualThermometer;
  t1->setValue(21.3);
  t2->setValue(22.4);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


// Konfiguracja parametrów termostatu
  hvac->setMainThermometerChannelNo(1);     // Main Thermometer DS1
  hvac->setTemperatureHisteresisMin(20);  // 0.2 degree
  hvac->setTemperatureHisteresisMax(1000);  // 10 degree
  hvac->setTemperatureHisteresis(40);

  SuplaDevice.setName("Termostat");
  SuplaDevice.begin(21); // Thermostat requires proto version >= 21

    SuplaDevice.begin(GUID,              // Global Unique Identifier 
                  "x",  // SUPLA server address
                  "x",   // Email address used to login to Supla Cloud
                  "x");          // Authorization key
}

void loop() {

  // Odczyt temperatur z każdego czujnika
  float temp1 = sensors.getTempC(ds1addr);  // Czujnik 1
  float temp2 = sensors.getTempC(ds2addr);  // Czujnik 2
  float temp3 = sensors.getTempC(ds3addr);  // Czujnik 3
  float temp4 = sensors.getTempC(ds4addr);  // Czujnik 4



  // Znalezienie najniższej temperatury
  lowestTemp = temp1;
  if (temp2 < lowestTemp) lowestTemp = temp2;
  if (temp3 < lowestTemp) lowestTemp = temp3;
  if (temp4 < lowestTemp) lowestTemp = temp4;

SuplaDevice.iterate();

}


A próbowałeś

t1->setValue(lowestTemp);

Postawić w loop przed SuplaDevice .Iterate ()?
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

Taki odczyt DS'ów w loop to nie jest dobry pomysł.
Odczyt temperatury w DS'ach skłąda się z trzech kroków:
1. Wysłanie rozkazu wykonania pomiaru
2. Poczekanie odpowiednią ilość czasu (zależnie od ustawionej precyzji)
3. Odczyt pomiaru

Czas oczekiwania może wynosić nawet do niecałej 1 s (zależnie od precyzji) i może to zamulić pętlę loop. Najlepiej jeśli tam nie ma operacji blokujących.
Odczyt z DS'ów można zrealizować w taki sposób, że nie blokujesz programu, tylko wysyłasz rozkaz, zapisujesz czas wysłania, kręcisz normlanie pętlą i sprwadzasz ile minęło czasu, w odpowiednim momencie realizujesz odczyt.

Poza tym w większości przypadków wystarczy odczyt raz na kilkanaście/kilkadziesiąt sekund (o ile nie więcej).
Najlepsze suple dla Twojego domu :mrgreen:

Return to “Pomoc”