Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Eltrox Hurton
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

jak wykonać kilka razy pętlę IF i zakończyć ją

pinelesss 24 Jul 2017 15:14 2001 7
  • #1
    pinelesss
    Level 10  
    Na wstępie witam szanownych forumowiczów.

    Jestem na etapie budowy zintegrowanego czujnika opadów deszczu, światła i temperatury zewnętrznej pod system alarmowy. Kwestia pomiarów światła i temperatury oraz wysyłka danych do centrali alarmowej w postaci danych dzień/noc oraz temperatura dodatnia/ujemna nie stanowi większego problemu.

    Do budowy czujnika opadów deszczu wykorzystałem LC7555, który pod wpływem zmiany rezystancji wejściowej generuje częstotliwość na wyjściu. Temat związany z poprawnym odczytem tej częstotliwości przez Arduino oraz wysyłki danych deszcz/sucho do centrali alarmowej, również nie stanowił większego problemu. Problemem jest jednak kwestia sterowania grzałką w zależności od 3-4 różnych scenariuszy, zależnych od częstotliwości zmierzonej na wejściu Arduino:

    1. Jeśli 200 < frequency < 2000
    - włączyć przekaźnik out na pierwszy czas (np. 10 sek), po czym go wyłączyć na drugi czas (np. 20 sek)
    - wykonać pętlę 5 razy i wyjść
    2. Jeśli 2000 < frequency < 4000
    - włączyć przekaźnik out na pierwszy czas (np. 10 sek), po czym go wyłączyć na drugi czas (np. 20 sek)
    - wykonać pętlę 10 razy i wyjść
    3. Jeśli frequency > 4000
    - zostaw wyłączony przekaźnik out

    Częściowo udało mnie się zrealizować pierwszy scenariusz, jak w przykładzie poniżej
    tzn. jeśli częstotliwość jest większa niż 200 a mniejsza niż 2000 Hz przekaźnik jest włączany na czas1 i wyłączany na czas2 i tak w kółko, do momentu gdy częstotliwość nie spadnie poniżej 200Hz lub przekroczy 2kHz, gdzie:
    - frequency - obliczona częstotliwość sygnału wchodzącego na wejście;
    - Out - wyjście przekaźnika

    Code: c
    Log in, to see the code

    ... jednak nie potrafię skutecznie dodać warunku, który tylko np. 5 razy by wykonał główną pętlę "if". Dodawałem przed pierwszą "if" pętlę "for (k1=0; k1<6; k1++){pętla if}", jednak cały czas działała funkcja "if", jakby "for" w ogóle nie działało. Cały czas przekaźnik został włączany na okres czas1 i wyłączany na czas2 dopóki (frequency>200)&&(frequency<2000)

    Nie mam pojęcia gdzie robię błąd lub jak inaczej można poradzić sobie z tym problemem.

    Potrzebuję wykonać przedstawione wyżej scenariusze aby uniknąć zbędnego grzania podczas intensywnych opadów deszczu/śniegu.

    Pozdrawiam serdecznie, Rafał
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • Eltrox Hurton
  • #2
    Kaliber PC - Service

    Level 22  
    Witam.

    Jeśli chcesz zrealizować jakiś warunek, w którym warunek if ma wykonywać jakąś operację w określonym cyklu (czyli np. 5 razy coś działa a potem STOP aż do spełnienia kolejnego warunku itp.), to podpowiem tylko, że bardzo łatwo można uzyskać takie rezultaty wprowadzając dodatkowe zmienne i wprowadzać je do warunków.

    Zastanów się nad tym. Jeśli nadal będziesz miał wątpliwości to podziałamy coś więcej.
  • Eltrox Hurton
  • #3
    neo_dc
    Level 32  
    Dodaj zmienną do warunku i za każdym wykonaniem inkrementuj ją. Przy ostatnim wykonaniu wyzeruj i przechodź do następnej funkcji. To tylko jedna z metod :)
  • #4
    krzysiek_krm
    Level 40  
    Witam,
    wydaje się, że najbardziej zręcznie będzie zrealizować funkcję "Grzałka" w formie odpowiednio zaprojektowanej maszyny stanów.
    Algorytmowi chyba jednak czegoś jeszcze brakuje. Jeżeli na przykład warunek numer jeden (200 - 2000) będzie się utrzymywał bardzo długo, czy wystarczy jednorazowe wykonanie pętli pięciu powtórzeń, czy może pętla powinna być powtarzana co jakiś czas, na przykład co godzinę ?

    Pozdrawiam
  • #5
    pinelesss
    Level 10  
    krzysiek_krm wrote:
    Witam,
    wydaje się, że najbardziej zręcznie będzie zrealizować funkcję "Grzałka" w formie odpowiednio zaprojektowanej maszyny stanów.
    Algorytmowi chyba jednak czegoś jeszcze brakuje. Jeżeli na przykład warunek numer jeden (200 - 2000) będzie się utrzymywał bardzo długo, czy wystarczy jednorazowe wykonanie pętli pięciu powtórzeń, czy może pętla powinna być powtarzana co jakiś czas, na przykład co godzinę ?

    Pozdrawiam


    Witam, bardzo dziękuję za odpowiedź. Faktycznie, byłoby idealne powtórzyć wykonanie pętli po jakimś dłuższym czasie (np. w scenariuszu 2-3). Jeśli deszcz przestanie padać z automatu z najwyższego progu spadnie częstotliwość do progu 3-2-1. Dawno jednak nie używałem C++ i sporo rzeczy umknęło.

    Dodano po 4 [minuty]:

    neo_dc wrote:
    Dodaj zmienną do warunku i za każdym wykonaniem inkrementuj ją. Przy ostatnim wykonaniu wyzeruj i przechodź do następnej funkcji. To tylko jedna z metod :)


    Bardzo dziękuję za sugestię. Dodawałem do głównej pętli if warunek (np. &&(k1<5) i na końcu pętli dawałem k++, jednak nie przynosiło to żadnych rezultatów, program działał w kółko włączając i wyłączając przekaźnik. Analizowałem co i gdzie mam nie tak, zmieniałem również umiejscowienie inkrementacji k++ jednak wciąż to samo.
    Dodano po 2 [godziny] 2 [minuty]:
    pinelesss wrote:
    krzysiek_krm wrote:
    Witam,
    wydaje się, że najbardziej zręcznie będzie zrealizować funkcję "Grzałka" w formie odpowiednio zaprojektowanej maszyny stanów.
    Algorytmowi chyba jednak czegoś jeszcze brakuje. Jeżeli na przykład warunek numer jeden (200 - 2000) będzie się utrzymywał bardzo długo, czy wystarczy jednorazowe wykonanie pętli pięciu powtórzeń, czy może pętla powinna być powtarzana co jakiś czas, na przykład co godzinę ?

    Pozdrawiam


    Witam, bardzo dziękuję za odpowiedź. Faktycznie, byłoby idealne powtórzyć wykonanie pętli po jakimś dłuższym czasie (np. w scenariuszu 2-3). Jeśli deszcz przestanie padać z automatu z najwyższego progu spadnie częstotliwość do progu 3-2-1. Dawno jednak nie używałem C++ i sporo rzeczy umknęło.

    Dodano po 4 [minuty]:

    neo_dc wrote:
    Dodaj zmienną do warunku i za każdym wykonaniem inkrementuj ją. Przy ostatnim wykonaniu wyzeruj i przechodź do następnej funkcji. To tylko jedna z metod :)


    Bardzo dziękuję za sugestię. Dodawałem do głównej pętli if warunek (np. &&(k1<5) i na końcu pętli dawałem k++, jednak nie przynosiło to żadnych rezultatów, program działał w kółko włączając i wyłączając przekaźnik. Analizowałem co i gdzie mam nie tak, zmieniałem również umiejscowienie inkrementacji k++ jednak wciąż to samo.


    - poprawka, znalazłem błąd - inkrementację k1 dodawałem zawsze po wszystkich "if" a przed zakończeniem głównej pętli a to błąd. Każda podpętla dodawała do wartości k1 wartość 1 czyli po przejściu całej pętli wartość k1 była już równa 3.
    teraz wygląda to tak:

    Code: c
    Log in, to see the code

    Jednak zdaję sobie sprawę, że nie jest to do końca dobre rozwiązanie i tylko częściowo spełniające moje założenia.

    Po ponownym przeanalizowaniu potrzeb oraz uwzględnieniem cennych sugestii kolegi "krzysiek_krm" chciałbym zrealizować docelowo coś takiego: program sprawdzał by częstotliwość na wejściu i na jej podstawie sterował grzałką, i tak:
    - jeśli częstotliwość jest mniejsza niż 200 Hz, program nie włącza grzałki
    - jeśli częstotliwość jest w granicach 200 -15000 Hz wtedy program włącza grzałkę według scenariuszy 1-3. W każdym ze scenariuszy można przyjąć na stałe, iż grzałka jest 5-krotnie włączana na okres czas1 (docelowo na 5 min) po czym wyłączana na okres czas2 (docelowo 10 min) i jeśli w tym czasie nie zmniejszy się częstotliwość o próg niżej (np. z 3->2) czeka godzinę i ponownie uruchamia 5-krotne powtórzenie włącz/wyłącz. Natomiast jeśli w międzyczasie spadnie do progu niżej, program wchodzi do założeń niższego progu i dalej 5-krotnie wykonuje włączenie i wyłączenie grzałki... itd.

    Mam nadzieję, że nie namieszałem za bardzo.
    Miałbym zatem prośbę o sugestie, w jaki sposób najlepiej byłoby się zabrać do tematu, bo po swoich wypocinach widzę, że jest to za bardzo zamieszane z mojej strony.
  • #6
    User removed account
    User removed account  
  • #7
    pinelesss
    Level 10  
    szpoak wrote:
    Mi się wydaje że większa (+logiczna) ilość warunków rozwiązała by problem. Scenariusz musi zawierać wszystkie opcje dot. częstotliwości (temp. zewn.) oraz aktualnej temperatury grzałki. Do tego "czas" i po wszystkim. Trzy scenariusze (takie same) to lekki obłęd :-) że tak powiem.

    Etap1 programu:
    - sprawdza temp. zewnętrzną
    - przypisuje zmiennej A
    - sprawdza temp. wewnętrzną (grzałki, wody itp.)
    - przypisuje zmiennej B
    i teraz warunki i scenariusze które będą zależne od wyników zmiennych A i B
    warunek1:
    - jeśli na zewnątrz zmino, w środku zimno to... > scenariusz 1
    czyli pętla podgrzewania czasowego + po zakończeniu wyjście z pętli ale powrót do
    początku etapu1, czyli ponownie:
    - sprawdza temp. zewnętrzną
    - zmienia zmienną A
    - sprawdza temp. wewnętrzną (grzałki, wody itp.)
    - zmienia zmienną B
    i przechodzi do warunków i zależności które teraz po podgrzaniu wody będą miały już inny scenariusz typu:
    * jeśli na zewnątrz zimno
    * jeśli woda zimna
    * jeśli woda ciepła
    to pętli koniec i przechodzi dalej do opcji związanych z tym co robić gdy woda ciepła...

    ------------

    Musisz opracować kilkanaście możliwych scenariuszy np:
    1. na zewnątrz zimno, woda zimna...
    2. na zewnątrz zimno, woda w zakresie takim i takim (grzanie)
    3. na zewnątrz zimno, woda zagrzana (max temp)

    Wyrazy zimno, ciepło zastąp oczywiście w/g własnego uznania odpowiednim wyrazem dot. właściwego sygnału z czujników.

    Cały program powinien byc jedną wielką pętlą uzależnioną od warunków z czujników + czas. Czas jest potrzebny na wstrzymanie pracy programu jeśli pętla miała by się w końcu spełnić (zagrzać wodę) bo wiemy że po czasie woda ostygnie lub zmieni sie temp. zewnętrzna więc pętla nie skończy się bo po co ja kończyć?
    Program ma działać cały czas w kółeczko będąc zapętlonym a wykonywać zadania na podstawie zmiennych które zczyta z czujników dlatego muszą być wszystkie mozliwe scenariusze a jak ich zabraknie (woda ciepła!) to wtedy przerwa czasowa i ponowne uruchomienie programu. Gdy woda ostygnie całośc zacznie się od początku...


    Wielkie dzięki kolego "szpoak"za pomysł.
    Faktycznie, powiązanie z temperaturą zewnętrzną jest dobrym pomysłem. W przypadku, kiedy latem temperatura powietrza jest wysoka woda szybko sama odparuje i włączanie grzałki nie będzie uzasadnione. Jednak to w ciągu dnia. W nocy pomimo wyższych temperatur osiada rosa i tu już mi się komplikuje żywot :) Nie widzę u mnie za bardzo możliwości powiązania całości z temperaturą grzałki. Czujnik opadów deszczu/śniegu/wilgotności jest wykonany na bazie płytki:
    jak wykonać kilka razy pętlę IF i zakończyć ją
    Grzałka jest zrobiona na zasadzie rezystancji na odwrotnej stronie PCB. Całość hermetyczna.
    Nawet, jeśli miałbym możliwość doklejenia np DS18B20 od spodu, to i tak nie będzie to miarodajne do temperatury płytki na górze (od strony czujnika opadów)
    Dlatego uważałem do tej pory za jedyną zależność - zmianę częstotliwości na podstawie ilości kropli, które wylądują na górnej stronie czujnika. Czujnik będzie umieszczony pod kątem 45' względem poziomu po to, aby woda mogła swobodnie z niego spływać. Natomiast pozostanie na pewno wilgoć między ścieżkami, która pomimo zakończenia opadów będzie występować. Po to grzałka od dolnej strony, aby woda czy wilgoć szybciej odparowały. Początkowo myślałem aby grzałka była włączona non stop jak jest opad ale szkoda jej ze względu na jej żywotność - stąd 5-krotne włączenie i wyłączenie na określony czas. Jeśli będą intensywne opady to po 5 próbach "wysuszenia" czujnika program wyłączy grzałkę na godzinę, po czym znowu ponowi próbę i tak aż do momentu aż nie spadnie częstotliwość do niższego poziomu. Jeśli natomiast poziom częstotliwości wzrośnie o poziom wyżej, raczej bez sensu byłaby próba włączania grzałki.
    Potrzebuję wykombinować jakiś "mądry" algorytm, który z jednej strony nie przepali za szybko grzałki a z drugiej pozwoli wyeliminować fałszywe alarmy o opadach, które się skończyły jakiś czas temu.
  • #8
    User removed account
    User removed account