Skocz do zawartości

Mój termostat do oceny.


Pomocna odpowiedź

Napisano

Witam proszę odnieść się do kodu czy brnąc dalej.. xD

Próbuje napisać termostat dedykowany do mojej kotłowni w której mam zainstalowane 3 źródła ciepła dotychczas żadne nawet tech-I3 nie spełniało moich wymagań.

Proszę się odnieść do samej składni i przejrzystości kodu. 

#include <OneWire.h>
#include <DallasTemperature.h>

const int oneWireBus = 4;   
const int pompaKOPCIUCH = 2;
const int pompaCO = 3;
const int pompaCWU = 5;
const int COzCWU= 6;
const int COcwuKG = 7;
const int COzKG= 8;
const int pompaCIEPLA = 9;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

DeviceAddress czKOPCIUCH = { 0x28, 0xE8, 0x33, 0x96, 0xF0, 0x1, 0x3C, 0xE0};
DeviceAddress czBUFOR = { 0x28, 0xE8, 0x33, 0x96, 0xF0, 0x1, 0x3C, 0xE0};
DeviceAddress czcwuGORA = { 0x28, 0xE8, 0x33, 0x96, 0xF0, 0x1, 0x3C, 0xE0};
DeviceAddress czcwuDOL = { 0x28, 0xE8, 0x33, 0x96, 0xF0, 0x1, 0x3C, 0xE0};

void setup() {
  Serial.begin(115200);
  sensors.begin();
}

void loop()
{
  sensors.requestTemperatures(); 
  float KOPCIUCH = sensors.getTempC(czKOPCIUCH);
  float BUFOR = sensors.getTempC(czBUFOR);
  float cwuGORA = sensors.getTempC(czcwuGORA);
  float cwuDOL = sensors.getTempC(czcwuDOL);
  
  while (BUFOR <= 79)
  {
    while (cwuDOL >= 40)
    {
      digitalWrite(1, LOW); // Wyłącz Pompę CWU
      digitalWrite(2, LOW); // Zawór przełączajacy CWU/CO bez zmian przepływ AB-B
      digitalWrite(3, LOW); // Zawór przełączajacy CWU/KG bez zmian przepływ AB-B 
      delay(9000);
      while (KOPCIUCH > 40)
        {
          digitalWrite(2, LOW); // Zawór przełączajacy CWU/CO przepływ AB-B
          digitalWrite(2, LOW); // Zawór przełączajacy CO/KG przepływ AB-B
          digitalWrite(2, LOW); // Zawór przełączajacy Powroty przepływ AB-B
          digitalWrite(6, HIGH); // Włącz pompę od kopciucha
          digitalWrite(6, HIGH); // Włącz pompę główną CO
          digitalWrite(4, LOW); // Wyłącz pompę ciepła
          digitalWrite(5, LOW); // Wyłącz kocioł gazowy
          while (KOPCIUCH > 40)
          {
            delay(5000);
            if(cwuDOL < 40)
              {return;}
          }
         }
      }  
    
      while(digitalRead(TECH)==LOW && KOPCIUCH < 35 && cwuDOL > 40 )
      {
         if(cwuDOL < 40)
         {return;}
      
         else if(BUFOR >= 40) //DZIAŁA TYLKO POMPA CIEPŁA
        {
          digitalWrite(2, LOW); // Zawór przełączajacy CWU/CO przepływ AB-B
          digitalWrite(2, LOW); // Zawór przełączajacy CO/KG przepływ AB-B
          digitalWrite(2, LOW); // Zawór przełączajacy Powrotu przepływ AB-B
          digitalWrite(6, LOW); // Wyłącz pompę od kopciucha
          digitalWrite(4, HIGH); // Włącz pompę ciepła
           digitalWrite(6, HIGH); // Włącz pompę główną CO
          digitalWrite(5, LOW); // Wyłącz kocioł gazowy 
        }
        else if(BUFOR < 35) //DZIAŁA POMPA CIEPŁA Z KOTŁEM GAZOWYM
        {
          digitalWrite(2, LOW); // Zawór przełączajacy CWU/CO przepływ AB-B
          digitalWrite(2, HIGH); // Zawór przełączajacy CO/KG przepływ AB-A
         // digitalWrite(2, LOW); // Zawór przełączajacy Powrotu przepływ AB-B
          digitalWrite(6, LOW); // Wyłącz pompę od kopciucha
          digitalWrite(4, HIGH); // Włącz pompę ciepła
          digitalWrite(6, HIGH); // Włącz pompę główną CO
          digitalWrite(5, HIGH); // Włącz kocioł gazowy 
        }
        delay(5000);
      }
    
    while (cwuDOL < 40)
    {
      digitalWrite(CWUzKG, HIGH); // Zawór CWU/KG  włącz przpye przez wymiennik CWU
      digitalWrite(COzCWU, HIGH); // Przełącz Zawór CWU/CO przepływ AB-A
      delay(8000);
      digitalWrite(pompaCWU, HIGH); // Włącz Pompę CWU
      digitalWrite(pompaCO, HIGH); // Włącz Pompę główną CO
      
      while (KOPCIUCH < 55)
      {
        if(pompaCIEPLA == LOW) //jeśli pompa ciepla jest wyłączona
        {
           digitalWrite(pompaCIEPLA, HIGH);  // włącz pompę ciepła
           delay(2000);
        }
        else (pompaCIEPLA == HIGH && cwuGORA < 40); //jeśli PC jest włączona oraz cwu góra <40
        {
        //  digitalWrite(pompaCWU, HIGH); // Włącz Pompę CWU
          digitalWrite(pompaCO, LOW); // Wyłącz Pompę główną CO
         // digitalWrite(CWUzCO, LOW); // Zawór CWU/CO  przeyw AB-B na instalacje CO
          digitalWrite(CWUzKG, LOW); // Zawór CWU/KG  włącz kocioł gazowy
          delay(8000);
          break;

      while (cwuDOL < 40)&&(CWUzKG == LOW) //działa kocioł gazowy
      {
         if (KOPCIUCH >= 55 && cwuGORA > 40) 
         {
            digitalWrite(pompaCIEPLA, LOW); // Wyłącz pompę ciepła
            digitalWrite(CWUzCO, HIGH); // Zawór CWU/CO  przepływ AB-A na wymiennik
            digitalWrite(CWUzKG, HIGH); // Zawór CWU/KG  przepływ AB-A na na wymiennik
            digitalWrite(pompaKOPCIUCH, HIGH); // Włącz pompę obiegową kopciucha
            digitalWrite(pompaCO, HIGH); // Włącz Pompę główną CO
            delay(8000);
            break;
         }
         else if(BUFOR >= 55)
         {
            digitalWrite(CWUzKG, HIGH); // Zawór CWU/KG  przepływ AB-A na na wymiennik
          //digitalWrite(CWUzCO, HIGH); // Zawór CWU/CO  przepływ AB-A na wymiennik
            digitalWrite(pompaCO, HIGH); // Włącz Pompę główną CO
            delay(8000);
         }
          
       while (KOPCIUCH >= 55 && cwuDOL < 40) 
       { 
        if (cwuGORA > 40 && pompaKOPCIUCH == LOW) 
         {
           digitalWrite(pompaCIEPLA, LOW);  // wyłącz pompę ciepła
           digitalWrite(pompaKOPCIUCH, HIGH); // Włącz pompę obiegową kopciucha
           digitalWrite(CWUzCO, HIGH); // Przełącz Zawór CWU/CO przepływ AB-A
           digitalWrite(CWUzKG, HIGH); // Zawór przełączajacy CWU/KG ustal na wymiennik
           delay(8000);
           digitalWrite(pompaCO, HIGH); // Włącz Pompę główną CO
           digitalWrite(pompaCWU, HIGH); // Włącz Pompę CWU

         }
         else (cwuGORA < 40)
        {      
          digitalWrite(CWUzCO, LOW); // Przełącz Zawór CWU/CO przepływ AB-B
          digitalWrite(CWUzKG, LOW); // Zawór przełączajacy CWU/KG włącza kocioł gazowy
          delay(8000);  
          break;
        } 
       }
      }
     }    
  }
    } 

 

To nie ma prawa działać.

Załóżmy, że KOPCIUCH wynosi 50. Kiedy skończy się pętla

while (KOPCIUCH > 40) {
  // rób coś z zaworami
  delay(cośtam);
  }

Załóż, że nie istnieje instrukcja while ani funkcja delay, i poczytaj co to maszyna stanów.

23 minuty temu, ampers napisał:

Jeżeli dobrze rozumiem zagnieżdżenie pętli nie pomoże ?

 

Przede wszystkim: uzależniasz zakończenie pętli od wartości zmiennej KOPCIUCH, a ona się przecież sama magicznie nie zmieni dopóki nie odczytasz termometru. Zmienna cwuDOL będzie też miała tę samą wartość którą odczytałeś na początku loop. Teoretycznie można wepchac odczyty w pętlę, w drugą pętlę, w trzecią pętlę ale to totalnie bez sensu, odczyt robisz raz a potem zależnie od tego co dostałeś wykonujesz jakieś czynności

O maszynie stanów pisano tu już milion razy...

Przeczytaj sobie to: https://forbot.pl/blog/kurs-arduino-ii-wielozadaniowosc-opoznienia-z-millis-id18418

A potem zobacz, jak nasz kolega sobie z tym poradził (w pierwszej wersji programu była zupa z różnych dziwnych instrukcji, w ostatniej uczciwa maszyna stanów): 

 

A przede wszystkim zanim zaczniesz pisać programy które podłączysz do czegoś poważniejszego niż migająca dioda - skończ forbotowe kursy Arduino przynajmniej bo albo sfajczysz chałupę, albo zimą zamarzniesz 😞 Niestety - wygląda na to że nie rozumiesz jak ta maszyneria działa...

No to co, kiedy następna wersja kodu?

Okej. rozumiem że błądzę i gdzie leży problem. Brak wiedzy :D 

Co do następnej wersji kodu to już niebawem coś postaram się napisać.  Ale najpier nauka by się nie ośmieszać na forum ....:D

 

  • Lubię! 1
1 godzinę temu, ampers napisał:

Ale najpier nauka by się nie ośmieszać na forum

Spokojnie - nikt tu się nie ośmiesza. Po prostu - jeśli czegoś nie rozumiesz i nie bardzo wiesz jak znaleźć rozwiązanie - piszesz tutaj o pytasz.

A nauka przyda się niezależnie od ośmieszania 🙂

 

14 godzin temu, ampers napisał:

Witam proszę odnieść się do kodu czy brnąc dalej.. xD

Zdecydowanie na początek w takim przypadku poleciłbym szybki ale systematyczny kurs zupełnych podstaw języka C. Jeden z najlepszych tutoriali (nie tylko dla języka C) - biorąc pod uwagę zwięzłość i ścisłość przekazu - to ten z portalu w3schools:

https://www.w3schools.com/c/index.php

  • Lubię! 1

Witam ponownie. Wydaje się mi że ugryzłem temat. Od innej strony teraz jest bardziej czytelne i prostsze w obsłudze dzięki podrzuconym powyżej linkom.

A oto kawałek kodu do zobrazowania jak to ma w moim mniemaniu funkcjonować i czy to dobra droga.

void loop() {
  sensors.requestTemperatures();
  float czKOPCIUCH = sensors.getTempC(czujnikKopciuch);
  //....
  //....
  //C.O.
  bool stanPompyKOPCIUCH = czKOPCIUCH >= tempKOPCIUCH_ON; 
  //....
  //.... Tutaj dalsza logika progrmu czyli kolejne bool
  
  if (stanPompyKOPCIUCH != poprzednistanPompyKOPCIUCH) {
    digitalWrite(PIN_KOPCIUCH, stanPompyKOPCIUCH);
    poprzednistanPompyKOPCIUCH = stanPompyKOPCIUCH;
  }
	//.... Ten if sprawdza czy jest zmiana logiki stanu od ostatniego przebiegu petli i jeżeli jest ten sam omija go
    //.... dzięki temu unikam ciągłego podawania na pin stanu wysokiego bądz niskiego.

  delay(1000); 
}

 

 

Dnia 26.08.2023 o 07:17, ethanak napisał:

Teoretycznie można wepchac odczyty w pętlę, w drugą pętlę, w trzecią pętlę ale to totalnie bez sensu, odczyt robisz raz a potem zależnie od tego co dostałeś wykonujesz jakieś czynności

Wydaje się mi że dobrze pojąłem te słowa. :D

Pytanie co z delay teoretycznie nie przeszkadza np.ustawić na 2-5 sek. bo oznaczało bo to tylko że co 5 sek. będzie odczyt z czujników. Choć każdy wie że blokuje to program. Widzę dwie możliwości zrobić to poprzez funkcje milis(), lub też nie ustalać czasu przerwy ale uzależnić od zmiany np co 1oC. jakieś pomysły i czy ogólnie tym razem kod jest okej ?

Tym razem jest ok... Co do delay() to nie jest on zły dopóki nie zechcesz wykonywać akcji innych nagle...np. dorobisz guziki do ustawiania ustawień i już ten delay będzie brudził...z millis() było by dużo lepiej...

7 godzin temu, farmaceuta napisał:

Co do delay() to nie jest on zły dopóki nie zechcesz wykonywać akcji innych nagle...np. dorobisz guziki do ustawiania ustawień i już ten delay będzie brudził...z millis() było by dużo lepiej...

Szczerze nie przewidywałem przycisków nawet w przyszłości a jedynie podpięcie wyświetlacza choć to jest też zbędne myślałem tylko o sygnalizacji stanu działania instalacji poprzez Diody i ich opis proste i czytelne. Poza tym nie potrzebuje wodotrysków w kotłowni wyświetlaczy i innych dodatkowych elementów. Choć nie powiem że ładny wyświetlacz nie robił by roboty i graficzne przestawienie instalacji, ale to może zostawmy na przyszłość :D

Na tą chwilę chcę dokończyć pisani programu uruchomić, przetestować na sucho i podłączyć.

  • Lubię! 2

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...