Skocz do zawartości

Mój termostat do oceny.


ampers

Pomocna odpowiedź

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;
        } 
       }
      }
     }    
  }
    } 

 

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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?

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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 🙂

 

Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

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 ?

Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.