• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zmiana stanów logicznych oświetlenia
#1
Cześc Wam Smile
Tworzę projekt w którym można za pomocą aplikacji ustawić godzinę włączenia i wyłączenia oświetlenia. Ta część programu działa mi bardzo dobrze. Do tego chciałbym aby za pomocą dwóch przycisków w aplikacji (P1 - Świt, P2 - zmierzch) można było włączać i wyłączać oświetlenie manualnie. Na początku programu użyłem dwóch zmiennych: boolean swit = false; boolean zmierzch = false;. Następnie wstawiłem w kodzie w miejscu odbioru danych z bluetooth że w momencie odebrania wiadomości  ,,swit"  stan zmiennej swit zmieni się na true a zmiennej zmierzch na false. Tak samo z wiadomością do zmiennej zmierzch tylko z odwrotnym wynikiem.  Arduino fajnie odbiera wszystko z aplikacji przez bluetooth tylko problem jest ze stanami lampki. Kiedy lampka pracuje w przedziale czasowym ustawionym w aplikacji i nagle wyłączę ją za pomocą przycisków i włączę to następnie jeżeli minie zadany czas świecenia to ona dalej świeci. Tak samo jest kiedy  chciałbym ją włączyć w momencie kiedy jest wyłączona i czeka na czas włączenia, jeżeli ją włączę a potem wyłączę to w momencie kiedy jest czas żeby się automatycznie zaświeciła to tego nie zrobi. 

Próbowałem wielu metod, kilka było nawet prawie trafnych(coś zawsze nie do końca działało), próbowałem tablic prawdy, ale to na nic. Chciałbym zmieniać stany lampki tak żeby w trakcie jej pracy lub w momencie kiedy nie pracuje, manualnie włączać i wyłączać lampkę.

Czy jest ktoś, kto mógłby mi trochę podpowiedzieć, naprowadzić?
Kod funkcji timera odpowiadającego za załączenie i wyłączenie lampki o odpowiedniej godzinie wygląda tak:

//poczatkowa deklaracja zmiennych typu boolean (początek programu)

     boolean swit = false;
     booleand zmierzch = false;

//część programu w której arduino odbiera informacje z aplikacji

if (wiadomosc.length() > 0) {
     if(wiadomosc == "swit"){             //odwraca stany swit i zmierzch
          swit = true;           
          zmierzch = false;
     }
     if(wiadomosc == "zmierzch"){       //odwraca stany swit i zmierzch
          swit = false;
          zmierzch = true;
     }


// Własna FUNKCJA TIMER 1  (już poza pętlą loop)


boolean timer( int timerPin, byte hOn, byte mOn, byte sOn, byte hOff, byte mOff, byte sOff, byte timerStatus) {

  if  (timerStatus == 0) {
    digitalWrite(timerPin, OFF);
    return false;
  };

  boolean state = false;
  long tOn = (long(hOn) * 3600) + (long(mOn) * 60) + long(sOn);
  long tOff = (long(hOff) * 3600) + (long(mOff) * 60) + long(sOff);

  if (tOn < tOff) {
    if (currentTimeSec >= tOn && currentTimeSec < tOff) { 

//czyli jak czas jest wiekszy od momentu wlaczenia lampki i momentu wylaczenia lampki, przedzial w ktorym jest         wlaczona lampka
      state = true;
    }
  }

  if (tOn > tOff) {
    if (currentTimeSec >= tOn && currentTimeSec <= 86399) {
      state = true;
    }
    if (currentTimeSec >= 0 && currentTimeSec < tOff) {
      state = true;
    }
  }

   if(swit == true){       //jezeli swit jest true to zmienia sie stan state lampki na true czyli ma swiecic. 
     state = true; 
 }

  if(zmierzch == true){    //jezeli zmierzch jest true to zmienia sie stan state lampki na false i powiina nie swiecic
     state == false;
 }


  if (state) {
    analogWrite(led, jasnosc); // wejscie pwm jest deklarowane na pin leda o okreslonej jasnosci rownej 0
    jasnosc += wypelnienie;
    if (jasnosc > 255) //jesli jest powyzej 255, to ustalamy spowrotem 255
      jasnosc = 255;
    return true;   //zwraca wartosc state na true
  }
  else {
    analogWrite(led, jasnosc); // wejscie pwm deklarowane na pin led o jasnosci rownej 0
    jasnosc -= wypelnienie;
    if (jasnosc < 0) //jesli spadlo nam ponizej zera, to wracamy na wartosc 0.
      jasnosc = 0;
    return false;   //zwraca wartosc state na false
  }
}
 
Odpowiedź
#2
A nie jest problemem :
if(zmierzch == true){ //jezeli zmierzch jest true to zmienia sie stan state lampki na false i powiina nie swiecic
state == false;
}
Podwójny znak =, do state nie wpisuje się false.

Przyznam, że jak dla mnie to trochę namieszane jak w cygańskim tobołku, no ale ja początkujący i wolę operować na 1 lub 0 , albo HIGH i LOW.
Po co dwie zmienne jak wystarczy jedna. "Naduszam" przycisk "zapal" to stan zmiennej = 1 a jak "naduszam" przycisk "zgaś" to stan zmiennej = 0.
 
Odpowiedź
#3
Każda linijka kodu powinna być soczyście skomentowana, żeby czytający nie musiał się domyślać, co robi dany fragment kodu. Zresztą autor, jeśli zostawi projekt na kilka dni, to też nie będzie wiedział do czego ten kod służy.
A swoją drogą, wystarczy jeden przycisk do obsługi tej lampki.

P.S. Nie mam pojęcia co ma robić owa lampka, z opisów wynika, że ma świecić w dzień i nie świecić w nocy.
P.S.2 Agregacik prawdę prawi.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#4
Z tymi komentarzami to lepiej nie przesadzać. Właściwie najlepiej żeby komentarzy nie było.
 
Odpowiedź
#5
Na wstępie dziękuje za odpowiedzi. Lampka jest częścią sterownika akwarystycznego. Ten drugi znak równości wpisał mi się przez przypadek, oficjalnie jest tam tylko jeden. Za chwilę dodam bardziej opisany kod Smile
 
Odpowiedź
#6
// Własna FUNKCJA TIMER 1  (już poza pętlą loop)


boolean timer( int timerPin, byte hOn, byte mOn, byte sOn, byte hOff, byte mOff, byte sOff, byte timerStatus) {

  if  (timerStatus == 0) {      // jeżeli status timera jest równy zero
    digitalWrite(timerPin, OFF);  //wyjście pod ktorym jest lampka jest wyłączona
    return false;                              //zwraca wartosc false do stanu STATE odpowiadającego za włączenie lub wyłączenie lampki
  };

  boolean state = false;      //początkowy stan false
  long tOn = (long(hOn) * 3600) + (long(mOn) * 60) + long(sOn);    //godzina wlaczenia  timera
  long tOff = (long(hOff) * 3600) + (long(mOff) * 60) + long(sOff);    //godzina wylaczenia timera



//warunki  czasowe włączenia i wyłączenia lampki

  if (tOn < tOff) {        //jeżeli czas włączenia jest < od czasu wyłączenia
    if (currentTimeSec >= tOn && currentTimeSec < tOff) {    //jeżeli aktualny czas >= od czasu włączenia i aktualny czas < od czasu wyłączenia

//czyli jak czas jest wiekszy od momentu wlaczenia lampki i momentu wylaczenia lampki, przedzial w ktorym jest        wlaczona lampka
      state = true;      //zwraca stan STATE równy true czyli lampka się świeci
    }
  }

  if (tOn > tOff) {      //jeżeli czas włączenia jest większy od czasu wyłączenia
    if (currentTimeSec >= tOn && currentTimeSec <= 86399) {    //jeżeli aktualny czas >= czasowi włączenia i aktualny czas <= od północy
      state = true;    //zwraca wartość STATE true
    }
    if (currentTimeSec >= 0 && currentTimeSec < tOff) {      //jeżeli obecny czas >= od zera i obecny czas < od czasu wyłączenia
      state = true;    //zwraca stan STATE true
    }
  }

  if(swit == true){      //jezeli swit jest true to zmienia sie stan state lampki na true czyli powinna świecić
    state = true;
}

  if(zmierzch == true){    //jezeli zmierzch jest true to zmienia sie stan state lampki na false i nie powinna się swiecic
    state = false;
}


  if (state) {
    analogWrite(led, jasnosc); // wejscie pwm jest deklarowane na pin leda o okreslonej jasnosci rownej 0
    jasnosc += wypelnienie;
    if (jasnosc > 255) //jesli jest powyzej 255, to ustalamy spowrotem 255
      jasnosc = 255;
    return true;  //zwraca wartosc state na true
  }
  else {
    analogWrite(led, jasnosc); // wejscie pwm deklarowane na pin led o jasnosci rownej 0
    jasnosc -= wypelnienie;
    if (jasnosc < 0) //jesli spadlo nam ponizej zera, to wracamy na wartosc 0.
      jasnosc = 0;
    return false;  //zwraca wartosc state na false
  }
}
 
Odpowiedź
#7
Próbowałem ze wstawieniem warunków świtu i zmierzchu w warunek przy porównywaniu czasów włączenia i wyłączenia. Podwoiłem ilość warunków. Efekt był taki że jeżeli lampka świeciła się przykłądowo od godziny 10:00 do godziny 12:00 to w tym czasie mogłem za pomocą przycisków zmieniać stan lampki. Jeżeli czas przekroczył godzinę 12:00 to po tym czasie stan wysoki był cały czas i nie mogłem jej wyłączyć przyciskiem ani nie odbywało się to programowo o 12:00 jak powinno.
Wyglądało to tak:


//warunki  czasowe włączenia i wyłączenia lampki

  if (tOn < tOff) {   
    if (currentTimeSec >= tOn && currentTimeSec < tOff && swit == true) { 

      state = true;
    }
  }

  if (tOn > tOff) {   
    if (currentTimeSec >= tOn && currentTimeSec <= 86399 && swit == true) { 
      state = true; 
    }
    if (currentTimeSec >= 0 && currentTimeSec < tOff &&  swit == true) {  
      state = true; 
    }
  }
  if (tOn < tOff) {  
    if (currentTimeSec >= tOn && currentTimeSec < tOff && zmierzch == true) { 

      state = false;
    }
  }

  if (tOn > tOff) { 
    if (currentTimeSec >= tOn && currentTimeSec <= 86399 && zmierzch == true) { 
      state = false; 
    }
    if (currentTimeSec >= 0 && currentTimeSec < tOff  && zmierzch== true) { 
      state = false;
    }
  }
 
Odpowiedź
#8
Przykładowo:

1 Przypadek:

Czas włączenia lampki to godzina 10:00, czas wyłączenia to godzina 20:00.
Kiedy lampka działa automatycznie chciałbym ją wyłączyć przyciskiem (ZMIERZCH) bo np. chcę wpuścić nowe ryby, które są płochliwe przy świetle.
Jeżeli już je wpuściłem to chciałbym włączyć lampkę przyciskiem (ŚWIT), to jakby powrót do automatycznej pracy, do stanu przed wyłączeniem lampki.

2 przypadek:
Minęła już godzina wyłączenia czyli 20:00, lampka nie świeci, ale ja chciałbym ją włączyć bo muszę coś zrobić w akwarium. Naciskam przycisk (ŚWIT) i lampka zaczyna świecić. Po obsłudze zbiornika naciskam przycisk (ZMIERZCH) aby ją wyłączyć i  aby następnie program działał w automacie i czekał na godzinę 10:00 na włączenie.

Pierwszy kod który Wam napisałem powodował to że po uruchomieniu Arduino lampka świeciła się o ustalonej godzinie włączenia, a także gasiła się o ustalonej godzinie wyłączenia.

Za pomocą tych przycisków mogłem manualnie sterować lampką, ale jeżeli chociaż raz to zrobiłem to program już nie był w stanie wyłączyć ani włączyć lampki o ustalonej godzinie.

Wynikałoby z tego że po naciśnięciu przycisków kod timera był w pewien sposób dezaktywowany i tylko ręcznie za pomocą przycisków mogłem zmieniać stan lampki.
 
Odpowiedź
#9
Czy masz zegar do sterowania tym programem. Jak ustawiasz warunki załączania i wyłączania lampy.
Ponadto nie wiem jak coś może być większe lub mniejsze od prawdy czy fałszu.
Czy w ciągu doby automatycznie tylko raz załączasz i wyłączasz lampę.
 
Odpowiedź
#10
Zegar do sterowania tym programem to DS3231.

Wciągu doby lampka raz się zaświeca i gaśnie. Z reguły to godziny  10:00 (Czas automatycznego włączenia możliwy do zmiany w aplikacji) i 20:00 (Czas wyłączenia również możliwy do zmiany). Jeżeli chodzi o aplikację to wszystko działa dobrze. Problem mam tylko z tym manualnym włączeniem i wyłączeniem.

Program do obsługi samego zegara bez tych przycisków (fragmenty):

boolean ON = true, OFF = false;

long unsigned currentTimeSec;

int led = 3; // do ktorego pinu pwm podlaczona jest dioda
int jasnosc = 0; // wartosc poczatkowa jasnosci
int wypelnienie = 1; // co ile punktow zwieksza sie wypelnienie

#define t1Pin 3

// Godzina, minuta, sekunda włączenia obwodu 1 (Godzina/Minuta/Sekunda)
int t1HOn, t1MOn, t1SOn;

// Godzina, minuta, sekunda wyłączenia obwodu 1 (Godzina/Minuta/Sekunda)
int t1HOff, t1MOff, t1SOff;

DS3231 clock;
RTCDateTime dt;

  // stan poczatkowy pinu timera
  digitalWrite(t1Pin, OFF);


//kolejny fragment to juz petla loop

void loop() {

  currentTimeSec =  (long(dt.hour) * 3600) + (long(dt.minute) * 60) + long(dt.second);

  //zmienna currentTimeSec pobiera z RTC aktualny czas i przelicza go na sekundy, bedzie to potrzebne do warunków funkcji timera

dt = clock.getDateTime();

  //odczytywanie zapisanej w pamieci eeprom godzinie switu i zmierzchu
  t1HOn = EEPROM.read(0);
  t1MOn = EEPROM.read(1);
  t1HOff = EEPROM.read(2);
  t1MOff = EEPROM.read(3);

  timer(t1Pin, t1HOn, t1MOn, t1SOn, t1HOff, t1MOff, t1SOff, 1);    //TIMER NR 1

//tutaj juz poza petla loop

//FUNKCJA TIMER 1 - ten timer odpowiada za porównywanie aktualnego czasu z RTC do czasu ustawionego


boolean timer( int tPin, byte hOn, byte mOn, byte sOn, byte hOff, byte mOff, byte sOff, byte tStatus) //, long currentTimeSec)
{
  if  (tStatus == 0) {
    digitalWrite(tPin, OFF);
    return false;
  };

  boolean state = false;
  long tOn = (long(hOn) * 3600) + (long(mOn) * 60) + long(sOn);
  long tOff = (long(hOff) * 3600) + (long(mOff) * 60) + long(sOff);


//1 warunek porównujący aktualny czas z czasem ustawionym

  if (tOn < tOff) {
    if (currentTimeSec >= tOn && currentTimeSec < tOff) { 
      state = true;
    }
  }

//2 warunek porównujący aktualny czas z czasem ustawionym

  if (tOn > tOff) {
    if (currentTimeSec >= tOn && currentTimeSec <= 86399) {
      state = true;
    }
    if (currentTimeSec >= 0 && currentTimeSec < tOff) {
      state = true;
    }
  }

//jeżeli state == true to lampka się rozjaśnia

  if (state) {
    analogWrite(led, jasnosc); // wejscie pwm jest deklarowane na pin leda o okreslonej jasnosci rownej 0
    jasnosc += wypelnienie;
    if (jasnosc > 255) //jesli jest powyzej 255, to ustalamy spowrotem 255
      jasnosc = 255;
    return true;
  }

//jeżeli state == false to lampka się ściemnia

  else {
    analogWrite(led, jasnosc); // wejscie pwm deklarowane na pin led o jasnosci rownej 0
    jasnosc -= wypelnienie;
    if (jasnosc < 0) //jesli spadlo nam ponizej zera, to wracamy na wartosc 0.
      jasnosc = 0;
    return false;
  }
}
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości