• 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
Przekaźnik czasowy na attiny13
#1
Witam, potrzebuje zaprogramować przekaźnik pompy na attiny13 w następujący sposób:
1. Wyłączona 20min
2. Włączona 90s
3. Wyłączona 60min
Punkt 2 i 3 w pętli

Próbowałem funkcją delay ale maksymalny czas mi wychodził około 1min, a millis coś mi nie wychodzi.

Czy ktoś był by mi w stanie pomóc ?
 
Odpowiedź
#2
(17-04-2024, 08:58)Spinus napisał(a): Witam, potrzebuje zaprogramować przekaźnik pompy na attiny13 w następujący sposób:
1. Wyłączona 20min
2. Włączona 90s
3. Wyłączona 60min
Punkt 2 i 3 w pętli

Próbowałem funkcją delay ale maksymalny czas mi wychodził około 1min, a millis coś mi nie wychodzi.

Czy ktoś był by mi w stanie pomóc ?

Jasne, tylko pokaż jak to masz napisane.

Ja na podobnej zasadzie będę robił system do wentylacji wyłazu na strychu aby robić przewiew świeżego powietrza gdyż aktualnie skrapla mi się wilgoć.
 
Odpowiedź
#3
60 sec czyli argument delay to ok 60000. To blisko granicy 16 bitów. Pokaż może dokładnie kod jaki napisałeś, być może wystarczy 'wypromować' typ do longa i delay zadziała. Argument delaya jest typu unsigned long.
Może sprawdź delay(100000UL);
 
Odpowiedź
#4
delay przyjmuje unsigned int, czyli 65535 to ponad 1 minutę ale nie więcej czyli tylko 65 sek MAX
 
Odpowiedź
#5
(17-04-2024, 11:30)oscarX napisał(a): 60 sec czyli argument delay to ok 60000. To blisko granicy 16 bitów. Pokaż może dokładnie kod jaki napisałeś, być może wystarczy 'wypromować' typ do longa i delay zadziała. Argument delaya jest typu unsigned long.
Może sprawdź delay(100000UL);
Dopisek UL nie działał, próbowałem. Nie ma mnie teraz przy komputerze, żebym wysłał kod.
Ale teraz to już nie wiem nawet co mam ci wysłać, bo pisałem chyba 10 razy na nowo i każdy przerabiałem kilka razy?
 
Odpowiedź
#6
(17-04-2024, 11:40)Łowiczak napisał(a): delay przyjmuje unsigned int, czyli 65535 to ponad 1 minutę ale nie więcej czyli tylko 65 sek MAX
Tutaj podają że unsigned long.
 
Odpowiedź
#7
może zamiast delay użyj cykle zegara systemowego,  coś w tym stylu

Kod:
#define CZAS_WYLACZONA 20 * 60 * 1000  // 20 minut w milisekundach
#define CZAS_WLACZONA 90 * 1000         // 90 sekund w milisekundach
#define CZAS_POMIEDZY 60 * 60 * 1000   // 60 minut w milisekundach

enum Stan { WYLACZONA, WLACZONA, POMIEDZY };
Stan obecny_stan = WYLACZONA;

unsigned long czas_startu = 0;

void setup() {
  // Konfiguracja pinów i przekaźnika
}

void loop() {
  switch (obecny_stan) {
    case WYLACZONA:
      if (millis() - czas_startu >= CZAS_WYLACZONA) {
        czas_startu = millis();
        obecny_stan = WLACZONA;
      }
      break;
    case WLACZONA:
      if (millis() - czas_startu >= CZAS_WLACZONA) {
        czas_startu = millis();
        obecny_stan = POMIEDZY;
      }
      break;
    case POMIEDZY:
      if (millis() - czas_startu >= CZAS_POMIEDZY) {
        czas_startu = millis();
        obecny_stan = WYLACZONA;
      }
      break;
  }
}
 
Odpowiedź
#8
Jutro rano spróbuję wgrać zobaczę co z tego wyjdzie i dam znać.
Próbowałem z millis, ale mi coś nie wyszło ?
 
Odpowiedź
#9
(17-04-2024, 14:10)Łowiczak napisał(a): może zamiast delay użyj cykle zegara systemowego,  coś w tym stylu

Kod:
#define CZAS_WYLACZONA 20 * 60 * 1000  // 20 minut w milisekundach
#define CZAS_WLACZONA 90 * 1000         // 90 sekund w milisekundach
#define CZAS_POMIEDZY 60 * 60 * 1000   // 60 minut w milisekundach

enum Stan { WYLACZONA, WLACZONA, POMIEDZY };
Stan obecny_stan = WYLACZONA;

unsigned long czas_startu = 0;

void setup() {
  // Konfiguracja pinów i przekaźnika
}

void loop() {
  switch (obecny_stan) {
    case WYLACZONA:
      if (millis() - czas_startu >= CZAS_WYLACZONA) {
        czas_startu = millis();
        obecny_stan = WLACZONA;
      }
      break;
    case WLACZONA:
      if (millis() - czas_startu >= CZAS_WLACZONA) {
        czas_startu = millis();
        obecny_stan = POMIEDZY;
      }
      break;
    case POMIEDZY:
      if (millis() - czas_startu >= CZAS_POMIEDZY) {
        czas_startu = millis();
        obecny_stan = WYLACZONA;
      }
      break;
  }
}

Tylko trzeba pamiętać, że millis też się zeruje co jakiś czas - kilkadziesiąt dni, co generuje taki problem, że podczas pisania, uruchamiania i testowania kodu wszystko będzie działać, a jak się zostrawi uruchomione urządzenie już włączone to może się zdarzyć, że zmienna czas_startu zostanie przypisana wartością bliską maksymalnej, chwilę potem millis się wyzeruje i będzie problem.
I te wartości w #define też chyba powinny być oznaczone UL.
 
Odpowiedź
#10
(18-04-2024, 07:32)oscarX napisał(a): Tylko trzeba pamiętać, że millis też się zeruje co jakiś czas - kilkadziesiąt dni, co generuje taki problem, ...

to że się zeruje nie ma żadnego znaczenie bo jest w pętli pobierane za każdym razem pdczas zmiany stanu, czyli tak jakby program zaczął działanie od nowa, podobnie jak podczas zaniku zasilania

PS. Funkcja millis() w mikrokontrolerach Arduino (w tym ESP8266 używanym w NodeMCU) zwraca liczbę milisekund od czasu uruchomienia urządzenia. Oznacza to, że wartość zwracana przez millis() zwiększa się w miarę upływu czasu od momentu uruchomienia urządzenia i nie jest zerowana automatycznie.

Jednakże, wartość zwracana przez millis() jest liczbą typu unsigned long, która ma ograniczenie górne. Po przekroczeniu maksymalnej wartości (4294967295 milisekund, czyli około 50 dni), wartość ta przepełnia się i zaczyna od zera. To oznacza, że z powodu przepełnienia millis() zacznie zwracać wartości od zera i liczyć czas od nowa.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości