Arduino akwarium dolewanie wody i światło

Masz problem z Arduino? Tutaj możesz szukać pomocy.
ODPOWIEDZ
Valdi
Młodszy majsterkowicz
Posty: 8
Rejestracja: 22 cze 2016, 15:18

Arduino akwarium dolewanie wody i światło

Post autor: Valdi » 22 cze 2016, 15:38

Witam,
ponieważ zbliża się urlop a nie chciał bym zostawić krewetek bez opieki postanowiłem zrobić projekt oświetlenia i dolewania wody.
Otóż tak:
Dolewanie wody - projekt opiera się na pompce z zaworkiem (12V), jednego włącznika pływakowego (docelowo 2 szt.), przekaźnika i arduino nano.
Światło - poprostu przekaźnik z arduino.
Generalnie dolewka działa ale ostatnio włączyła mi się w nocy i zapragnąłem założyć moduł czasu rzeczywistego.
Założenie jest takie że o określonej porze włącza się światło i oraz od tego czasu jeżeli czujnik pływakowy wykryje za mało wody pompa zacznie pompować w czasie +X sekund tak aby nie było kilkusekundowych załączeń.
I natrafiłem na mały problem jak w kodzie ustawię czas załączenia obejmuje tą samą godzinę czyli np. włączenie 12.00 i wyłączenie 12.40 to wszystko ładnie działa.
Ale jak ustawię start 12.00 stop 13.05 to nie działa.
Czy ktoś może popatrzeć na kod i podpowiedzieć co spierdzieliłem.
Zdaję sobie sprawę że jest nieelegancki ale to mój własny :).

#include <DS3231.h>
#include <Wire.h>
#include <Time.h>

DS3231 clock;
RTCDateTime dt;
const int dioda1 = 9;
const int przy2 = 10;
const int dioda2 = 11;
int buttonState = 0;


void setup()
{
pinMode(dioda1, OUTPUT);
pinMode(dioda2, OUTPUT);
pinMode(przy2, INPUT);

Serial.begin(9600);
// Inicjalizacja DS3231
Serial.println("Initialize DS3231");;
clock.begin();

// Ustawiany date i godzine kompilacji szkicu
//clock.setDateTime(__DATE__, __TIME__);
//clock.setDateTime(2016, 06, 20, 22, 45, 00);
}

void loop()
{
// Odczytujemy i wyswietlamy czas / załączamy swiatło
dt = clock.getDateTime();
if (dt.hour >= 15 && dt.minute >= 35 && dt.hour <= 16 && dt.minute <= 2){
digitalWrite(dioda1, HIGH);
Serial.print("Wlaczony: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");
}
// wyłączamy swiatlo
else {
digitalWrite(dioda1, LOW);
Serial.print("Wylaczony: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");
}
zalaczamy dolewanie
if (dt.hour >= 15 && dt.minute >= 40 && dt.hour <= 16 && dt.minute <= 2 && digitalRead(przy2) == HIGH) {
//digitalWrite(dioda2, HIGH);
Serial.print("P_Wlaczony: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");
digitalWrite(dioda2, HIGH);
delay(10000);
}
else //nie zalaczamy dolewania
{
digitalWrite(dioda2, LOW);
Serial.print("Wylaczony_a: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");
}
delay(1000);
}

pozdrawiam
Valdi

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


thetox
Młodszy majsterkowicz
Posty: 14
Rejestracja: 16 mar 2016, 09:33

Re: Arduino akwarium dolewanie wody i światło

Post autor: thetox » 22 cze 2016, 16:02

if (dt.hour >= 15 && dt.minute >= 35 && dt.hour <= 16 && dt.minute <= 2)

Minuty po 16 nie są ani większe ani równe 35 dalej if już nie jest sprawdzany.
Valdi
Młodszy majsterkowicz
Posty: 8
Rejestracja: 22 cze 2016, 15:18

Re: Arduino akwarium dolewanie wody i światło

Post autor: Valdi » 22 cze 2016, 16:44

thetox pisze:if (dt.hour >= 15 && dt.minute >= 35 && dt.hour <= 16 && dt.minute <= 2)

Minuty po 16 nie są ani większe ani równe 35 dalej if już nie jest sprawdzany.
Dzieki za odpowiedz ale jakby mam zacme myslowa :(
Czy w takim razie ten zapis byl by prawidlowy jako zakres.

if (dt.hour > 15 && dt.minute >35 && dt.hour < 16 && dt.minute < 2)
Czy przy takim zapisie ze czas ma byc wiekszy niz 15:35 do 16:02 to zadziala prawidlowo
I if bedzie dalej sprawdzany?

Pozdrawiam
Valdi
Awatar użytkownika
Marhef
Złota rączka
Posty: 1188
Rejestracja: 18 lis 2011, 02:18

Re: Arduino akwarium dolewanie wody i światło

Post autor: Marhef » 22 cze 2016, 19:20

Nie chodzi o to, że warunek jest niekompletny. Po pierwsze godzina nie mogą być jednocześnie większa od 15 i mniejsza od 16. Po drugie minuty nie mogą być jednocześnie większe od 35 i mniejsze od 2. Procesor nie sprawdza tak, jak człowiek.
Warunek powinien być: (godz == 15 && min >35) lub (godz == 16 && min <2)
thetox
Młodszy majsterkowicz
Posty: 14
Rejestracja: 16 mar 2016, 09:33

Re: Arduino akwarium dolewanie wody i światło

Post autor: thetox » 22 cze 2016, 19:54

Zmodyfikuj kod troche.

Kod: Zaznacz cały

if (dt.hour >= 15 && dt.minute >= 35){
digitalWrite(dioda1, HIGH);
Serial.print("Wlaczony: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");
}
// wyłączamy swiatlo
else if (dt.hour <= 16 && dt.minute <= 2) {
digitalWrite(dioda1, LOW);
Serial.print("Wylaczony: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");}
Valdi
Młodszy majsterkowicz
Posty: 8
Rejestracja: 22 cze 2016, 15:18

Re: Arduino akwarium dolewanie wody i światło

Post autor: Valdi » 22 cze 2016, 21:44

Wielkie dzięki :)
jutro w pracy zmodyfikuję kod i przedstawię do obejrzenia :)
Super extra za wytłumaczenie, bo oczywiście patrzyłem na to po ludzku.
Oczywiście w finalnej wersji nie będzie Serial.print tylko wyświetlanie na wyświetlaczu dwa wiersze.

jeszcze raz dziękuję bardzo.

Valdi
Awatar użytkownika
Marhef
Złota rączka
Posty: 1188
Rejestracja: 18 lis 2011, 02:18

Re: Arduino akwarium dolewanie wody i światło

Post autor: Marhef » 23 cze 2016, 08:32

thetox, nie zadziała. Popatrz na warunki. O 16:35 też się włączy. I o 17:35, i o 18:35... i tak aż do 23:35. A wyłączy się o 16:02, a później o 00:02, 01:02... 16:02. W tym przypadku MUSISZ dać sprawdzanie ==, a nie >=, <=
Valdi
Młodszy majsterkowicz
Posty: 8
Rejestracja: 22 cze 2016, 15:18

Re: Arduino akwarium dolewanie wody i światło

Post autor: Valdi » 23 cze 2016, 09:06

No to pytanie jak ma w końcu wyglądać warunek włączenia?
jeżeli dam if (dt.hour == 15 && dt.minute == 35){
To czy ten warunek nie zadziała tylko o godzinie 15:35?

A może prościej by było dać taki warunek włączenia?
if (dt.hour >= 15){

i dla wyłączenia
if (dt.hour <= 16){

ps. a może dało by się połączyć dt.hour i dt.minute w całość czyli (15:35) i w takiej formie to sprawdzać ?


Valdi
Awatar użytkownika
ethanak
Złota rączka
Posty: 764
Rejestracja: 21 lis 2015, 14:41
Kontakt:

Re: Arduino akwarium dolewanie wody i światło

Post autor: ethanak » 23 cze 2016, 10:40

Ech... coś na ten temat:

Kod: Zaznacz cały

przekaznik = 
 (dt.hour > startHour || (dt.hour == startHour && dt.minute >= startMinute)) &&
 (dt.hour < stopHour || (dt.hour == stopHour && dt.minute < stopMinute));
Awatar użytkownika
Marhef
Złota rączka
Posty: 1188
Rejestracja: 18 lis 2011, 02:18

Re: Arduino akwarium dolewanie wody i światło

Post autor: Marhef » 23 cze 2016, 11:22

Valdi pisze:No to pytanie jak ma w końcu wyglądać warunek włączenia?
jeżeli dam if (dt.hour == 15 && dt.minute == 35){
To czy ten warunek nie zadziała tylko o godzinie 15:35?
Tak, ten warunek zadziała TYLKO o 15:35.
Valdi pisze:A może prościej by było dać taki warunek włączenia?
if (dt.hour >= 15){
i dla wyłączenia
if (dt.hour <= 16){
Zauważ, że wtedy załączy się o KAŻDEJ godzinie po godzinie 15.
Warunek, który podał kolega @ethanak jest pełnym warunkiem do włączenia wyjścia. Chociaż lekko bym go zmodyfikował (tylko żeby ułatwić analizę kodu):

Kod: Zaznacz cały

((dt.hour > startHour && dt.hour < stopHour) || (dt.hour == startHour && dt.minute >= startMinute)  || (dt.hour == stopHour && dt.minute < stopMinute);
Dla podanych przez Ciebie danych (od 15:35 do 16:02), poszczególne wartości w warunku będą:

Kod: Zaznacz cały

(dt.hour > startHour && dt.hour < stopHour)
to ZAWSZE będzie miało wartość FALSE, ponieważ godzina nie może być jednocześnie większa od 15 i mniejsza od 16.

Kod: Zaznacz cały

(dt.hour == startHour && dt.minute >= startMinute)
to będzie miało wartość TRUE wtedy, kiedy na zegarze będzie godzina od 15:35 do 15:59

Kod: Zaznacz cały

(dt.hour == stopHour && dt.minute < stopMinute)
a to będzie miało wartość TRUE jeżeli na zegarze będzie godzina od 16:00 do 16:01.
Mam nadzieję, że to trochę rozjaśniło ;)
Aha, troszkę się komplikuje, jeżeli godzina zakończenia jest mniejsza od godziny rozpoczęcia (np. od 23:40 do 2:15)
Awatar użytkownika
ethanak
Złota rączka
Posty: 764
Rejestracja: 21 lis 2015, 14:41
Kontakt:

Re: Arduino akwarium dolewanie wody i światło

Post autor: ethanak » 23 cze 2016, 12:33

Na to też jest prosty sposób - w takiej sytuacji traktujemy okres między stop i start jako wyłączenie światła.
Coś takiego (zakładając że start* i stop* są globalne) mniej więcej:

Kod: Zaznacz cały

byte light(byte sh, byte sm, byte eh, byte em)
{
   if (sh > eh || (sh == eh && sm > em))
      return ! light(eh, em, sh, sm);
   return (dt.hour > sh || (dt.hour == sh && dt.minute >= sm)) &&
      (dt.hour < eh || (dt.hour == eh && dt.minute < em));
}

byte light()
{
    return light(startHour, startMinute, stopHour, stopMinute);
}
Valdi
Młodszy majsterkowicz
Posty: 8
Rejestracja: 22 cze 2016, 15:18

Re: Arduino akwarium dolewanie wody i światło

Post autor: Valdi » 23 cze 2016, 14:02

Zadziałał ten kod:
(dt.hour > startHour || (dt.hour == startHour && dt.minute >= startMinute)) &&
(dt.hour < stopHour || (dt.hour == stopHour && dt.minute < stopMinute));

wielkie dzięki ethanak

natomiast rzeczywiście w nocy może być problem :(
A nie można by zastosować coś takiego że czas będzie od powiedzmy 20:00 do 24:00 i 0d 00:00 do 7:00 czyli coś takiego:
(dt.hour > startHour || (dt.hour == startHour && dt.minute >= startMinute)) &&
(dt.hour < stopHour || (dt.hour == stopHour && dt.minute < stopMinute)) || (dt.hour > startHour1 || (dt.hour == startHour1 && dt.minute >= startMinute1)) &&
(dt.hour < stopHour1 || (dt.hour == stopHour1 && dt.minute < stopMinute1));;



natomiast tego kodu nie rozumiem nic a nic :(
byte light(byte sh, byte sm, byte eh, byte em)
{
if (sh > eh || (sh == eh && sm > em))
return ! light(eh, em, sh, sm);
return (dt.hour > sh || (dt.hour == sh && dt.minute >= sm)) &&
(dt.hour < eh || (dt.hour == eh && dt.minute < em));
}

byte light()
{
return light(startHour, startMinute, stopHour, stopMinute);
}
ODPOWIEDZ

Strony partnerskie: