Program na Arduino/Prośba o pomoc/ Przekaźnik

Masz problem z Arduino? Tutaj możesz szukać pomocy.
ODPOWIEDZ
decimus
Młodszy majsterkowicz
Posty: 39
Rejestracja: 27 gru 2014, 09:18

Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: decimus » 7 lut 2015, 19:42

Mam gotowy program do sterowania przekaźnikiem.Po wciśnięciu przycisku przekaźnik włącza się na zadany czas,a następnie się wyłącza.
Jak zrobić ,aby w trakcie pracy przekaźnika po ponownym wciśnięciu czas zaczął liczyć się od nowa i aby przekaźnik nie wstrzymał pracy na tą chwilę ponownego wciśnięcia.
Krótko mówiąc ,jeżeli będziemy wciskać przycisk non stop cyklicznie to urządzenie będzie cały czas pracowało na zadany czas ,aż do ostatniego wciśnięcia kiedy się już wyłączy po zadanym czasie. ;) Czy, może ktoś mi w tym pomóc :)


int pinButton = 8;
int Relay = 2;
int stateRelay = LOW;
int stateButton;
int previous = LOW;
long time = 0;
long debounce = 500;
int stayON = 20000; //stay on for 20000 ms

void setup() {
pinMode(pinButton, INPUT);
pinMode(Relay, OUTPUT);
}

void loop() {
stateButton = digitalRead(pinButton);
if(stateButton == HIGH && previous == LOW && millis() - time > debounce) {
if(stateRelay == HIGH){
digitalWrite(Relay, LOW);
} else {
digitalWrite(Relay, HIGH);
delay(stayON);
digitalWrite(Relay, LOW);
}
time = millis();
}
previous == stateButton;

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


razorxx100
Starszy majsterkowicz
Posty: 329
Rejestracja: 1 sie 2014, 22:57

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: razorxx100 » 7 lut 2015, 20:56

void loop() {
stateButton = digitalRead(pinButton);
if(stateButton == HIGH ) {
time = millis() + 20000;
digitalWrite(Relay, HIGH);
stan = 1;
}
if(stan == 1 && millis() > time) {
digitalWrite(Relay, LOW);
stan = 0;
}
decimus
Młodszy majsterkowicz
Posty: 39
Rejestracja: 27 gru 2014, 09:18

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: decimus » 7 lut 2015, 21:57

Ja poprawiłem program,ale wyskakuje błąd:teraz jest tak:

int pinButton = 8;
int Relay = 13;
int stateRelay = LOW;
int stateButton;
int previous = LOW;
long time = 0;
long debounce = 500;
int stayON = 5000; //stay on for 5000 ms

void setup() {
pinMode(pinButton, INPUT);
pinMode(Relay, OUTPUT);
}

void loop() {
stateButton = digitalRead(pinButton);
if(stateButton == HIGH ) {
time = millis() + 20000;
digitalWrite(Relay, HIGH);
stan = 1;
}
if(stan == 1 && millis() > time) {
digitalWrite(Relay, LOW);
stan = 0;
}


Mam jeszcze coś takiego ,czyli Timery.Chodzi o to, aby go właśnie przystosować jak ten wyżej.
1.Przycisk raz H raz L steruje Input8 ,a ten Output-em13
2.Resetowanie czasu bez wyłączenia przekaźnika przy cyklicznym wciskaniu przycisku.
Ja coś takiego mam ,ale na cyfrówce układ czasowo zmierzchowy.Chciałem zobaczyc jakby to było na mikrokontrolerze.
Zmierzchowy wiem natomiast mam problem z tym resetowanie zadanego czasu i zliczaniem od nowa tak aby nam światło paliło się non stop do czasu wyjścia z zasięgu i po zadanym czasie wyłączy się.
.....................................................................................................................................................
#include "Timer.h"

Timer t;
int pin = 13;

void setup()
{
pinMode(pin, OUTPUT);
t.pulse(pin, 10 * 60 * 1000, HIGH); // 10 minutes
}

void loop()
{
t.update();
}
razorxx100
Starszy majsterkowicz
Posty: 329
Rejestracja: 1 sie 2014, 22:57

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: razorxx100 » 8 lut 2015, 00:30

Sprawdz to.

int pinButton = 8;
int Relay = 13;
int stateRelay = LOW;
int stateButton;
int previous = LOW;
int stan = 0;
long time = 0;
long debounce = 500;
int stayON = 5000; //stay on for 5000 ms

void setup() {
pinMode(pinButton, INPUT);
pinMode(Relay, OUTPUT);
}

void loop() {
stateButton = digitalRead(pinButton);
if(stateButton == HIGH ) {
stan = 0;
time = millis() + 20000;
digitalWrite(Relay, HIGH);
stan = 1;
}
if(stan == 1 && millis() > time) {
digitalWrite(Relay, LOW);
stan = 0;
}
decimus
Młodszy majsterkowicz
Posty: 39
Rejestracja: 27 gru 2014, 09:18

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: decimus » 8 lut 2015, 08:53

Dalej pokazuje jakiś błąd,ale znalazłem program typowo Timery do sterowania oświetleniem przez czujkę i oto mi właśnie chodziło.
Nie wiem tylko,czy jest funkcja,która resetuje zadany czas[gdy poruszamy się w zasięgu czujki] przy tym nie wyłączając światła nawet na chwilę i zlicza czas od nowa dopóki nie wyjdziemy z jej zasięgu, to wtedy dopiero wyłączy światło po zadanym czasie.
Ja myślę,że tu potrzebne są te "przerwania" [nie znam się na tym] ,czyli :

Światło mimo ciągłego resetowania układu dalej świeci tylko zlicza zadany czas od nowa dopóki nas widzi czujka pir.

Znalazłem też inny program,ale tam jest "reset" Arduino i chwilę to trwa,czyli światło zgaśnie na 2-4 sekundy.

Ja mam to zrobione elektronicznie na CD4541 "reset" jest zarazem wyzwoleniem zadanego czasu.Styki NC czujki dają raz H raz L [jak jesteśmy w zasięgu -kuchnia dałem czujkę BOSCH-bardzo czuła-nawet jak siedzimy to wykrywa ruch ręki]- wstawiłem tranzystor, który tymi stanami steruje lub bramka - przerzutnik CD40106 z układu Zmierzchowego - wykorzystałem].

Ten poniżej program weryfikuje mi na IDE Arduino,ale nie montowałem jeszcze i nie wiem jak z tym resetowaniem czasu?
Jest strona o tym co poniżej dużo opisuje,ale tu nie mogę podać.Chyba że wpiszesz: "Wielozadaniowość w Arduino #3"
Czy,mógłbyś sprawdzić?

Program:
#include <Timers.h>

byte sensors[2] = {2, 3};
byte lamps[2] = {4, 5};

Timers<2> timer;

void lampOn(byte element)
{
digitalWrite(lamps[element], HIGH);
timer.setInterval(element, 120000);
}

void lampOff(byte element)
{
digitalWrite(lamps[element], LOW);
timer.setInterval(element, 0);
}

void setup()
{
for (byte i=0; i<2; i++)
{
pinMode(sensors, INPUT_PULLUP);
pinMode(lamps, OUTPUT);
digitalWrite(lamps, LOW);
}

timer.onTime = lampOff;
}

void loop()
{
for (byte i=0; i<2; i++)
{
if (digitalRead(sensors) == HIGH)
{
lampOn(i);
}
}

timer.process();
}
/////////////////////////////////////////
Drugi tego samego autora:
/////////////////////////////////////////
#include <Timers.h>

// Liczba kanałów sensor - światło
#define NUM_CHANNELS 10
// Piny cyfrowe do których podłączone są sensory
#define SENSORS_PINS 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
// Piny Cyfrowe do których podłączone są sterowniki świateł
#define LAMPS_PINS 12, 13, 14, 15, 16, 17, 18, 19, 20, 21

// Stan przy którym sterownik włącza światło
#define LAMP_ON HIGH
// Stan przy którym sterownik wyłącza światło
#define LAMP_OFF LOW
// Stan przy którym czujnik wykrywa osobę
#define SENSOR_ACTIVE HIGH

// Czas włączonej lampy w sekundach
#define LAMP_ON_TIME 120

// Deklaracja obiektu timera
Timers<NUM_CHANNELS> timer;

// Deklaracja pinów czujników i świateł
byte sensors[NUM_CHANNELS] = {SENSORS_PINS};
byte lamps[NUM_CHANNELS] = {LAMPS_PINS};

// Funkcja wywoływana gdy timer odliczy czas któregoś z kanałów
// [slot - numer kanalu]
void onTime(byte slot)
{
// Wyłączeie odpowiedniego światła
digitalWrite(lamps[slot], LAMP_OFF);
// Wyłaczenie timera dla danego światła
timer.setInterval(slot, 0);
}

// Funkcja wywoływana gdy czujnik wykryje osobę
// [slot - numer kanalu]
void lampOn(byte slot)
{
// Włączenie odpowiedniego światła
digitalWrite(lamps[slot], LAMP_ON);
// Włączenie timera odliczającego do wyłaczenia danego światła
timer.setInterval(slot, LAMP_ON_TIME * 1000);
}

void setup()
{
// Pętla ustawiająca piny Arduino dla czujników i świateł
for (byte i=0; i<NUM_CHANNELS; i++)
{
pinMode(sensors, INPUT_PULLUP);
pinMode(lamps, OUTPUT);
digitalWrite(lamps, LAMP_OFF);
}
// Przypisanie funkcji wywoływanej gdy timer odliczy czas dla któregoś światła
timer.onTime = onTime;
}

void loop()
{
// Aktualizacja czasu timera
timer.process();
// Pętla sprawdzająca czy któryś z czujników wykrył osobę
for (byte i=0; i<NUM_CHANNELS; i++)
{
// Jeśli wykrył to wywoływana jest funkcja lampOn
if (digitalRead(sensors) == SENSOR_ACTIVE)
lampOn(i);
}
}
razorxx100
Starszy majsterkowicz
Posty: 329
Rejestracja: 1 sie 2014, 22:57

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: razorxx100 » 8 lut 2015, 13:11

Jejciu... Jak ci jakis error wyskakuje to wez go przeczytaj i sprawdz co jest nie tak.. Petla loop poprostu nie byla zamknieta..
int pinButton = 8;
int Relay = 13;
int stateRelay = LOW;
int stateButton;
int previous = LOW;
int stan = 0;
long time = 0;
long debounce = 500;
int stayON = 5000; //stay on for 5000 ms

void setup() {
pinMode(pinButton, INPUT);
pinMode(Relay, OUTPUT);
}

void loop() {
stateButton = digitalRead(pinButton);
if(stateButton == HIGH ) {
stan = 0;
time = millis() + 20000;
digitalWrite(Relay, HIGH);
stan = 1;
}
if(stan == 1 && millis() > time) {
digitalWrite(Relay, LOW);
stan = 0;
}
}
decimus
Młodszy majsterkowicz
Posty: 39
Rejestracja: 27 gru 2014, 09:18

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: decimus » 8 lut 2015, 15:24

Bardzo Ci dziękuje za poświęcenie mi czasu, bo zagadka rozwiązana bez tych timerów.Jest co chciałem.
Czy, byłaby możliwość opisania z boku co dana linijka ma za zadanie.Oczywiście nie jest to koniecznie jak nie masz zbytnio czasu.
razorxx100
Starszy majsterkowicz
Posty: 329
Rejestracja: 1 sie 2014, 22:57

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: razorxx100 » 8 lut 2015, 15:31

void loop() {
stateButton = digitalRead(pinButton); // odczytanie stanu
if(stateButton == HIGH ) { // jezeli przycisk jest wcisniety to;
stan = 0; // dla zmiennej stan ustala 0
time = millis() + 20000; // do zmiennej time dopisuje ile czasu chodzi juz nasza atmega i dodaje do tego 20 sekund.
digitalWrite(Relay, HIGH); // Daje stan wysoki na pinie zeby wlaczyc lampke
stan = 1; // dla zmiennej stan ustala 1
}// tutaj zamykami jednego ifa zeby kolejny if chodzil ciagle w petli.
if(stan == 1 && millis() > time) { // sprawdzenie czy zmienna stan = 1 i czy aktualny stan jest wiekszy od popszedniego z dodaniem 20s
digitalWrite(Relay, LOW); // Jak if spelni warunek to poprostu wylaczy lampke
stan = 0; // zmiana stanu na 0
// Dalem te stany zeby sprawdzac czy juz jest odliczanie, bo chcialem to zrobic na dwa ify w petli ale z tego co widze to zapomnialem xD
}
}
decimus
Młodszy majsterkowicz
Posty: 39
Rejestracja: 27 gru 2014, 09:18

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: decimus » 8 lut 2015, 18:34

Dzięki za wszystko.Mam jeszcze pytanie, bo tego nie rozumiem:

int stayON = 5000; - to wyrzuciłem i też chodzi, to chyba teraz nie potrzebne?

long time = 0; - to i jakie ma znaczenie
long debounce = 500; - to i dlaczego 500
razorxx100
Starszy majsterkowicz
Posty: 329
Rejestracja: 1 sie 2014, 22:57

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: razorxx100 » 8 lut 2015, 19:23

To juz z twojego kodu zostalo.
decimus
Młodszy majsterkowicz
Posty: 39
Rejestracja: 27 gru 2014, 09:18

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: decimus » 8 lut 2015, 20:47

To nie był mój kod.
Tak jak pisałem nie mam za bardzo pojęcia o programowaniu.Dlatego pytałem.
Zrobiłem kilka projektów podglądając i zmieniając kod,ale to tak na chłopski rozum i nawet pracują.
Na przykład termometr zmieniłem w termostat i inne.
ewmario
Młodszy majsterkowicz
Posty: 7
Rejestracja: 17 maja 2020, 12:10

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: ewmario » 19 maja 2020, 19:33

Witam serdecznie.

Temat bardzo stary, ale może ktoś zauważy mój dopisek.

Skorzystałem z kodu kolegi razorxx100 modyfikując go dla swoich potrzeb.

Mam już swoje lata i raczkuję w kwestii programowania. Mój problem z tym kodem polega na tym, że świetnie spełnia on moje zapotrzebowanie. Z jednym małym mankamentem. Otóż, włożyłem ten kod w Timera i byłoby super, gdyby nie fakt, że wyłączenie czasowe przekaźnika jest uzależnione od stanu przycisku. W moim przypadku przekaźnik jest inicjowany wilgotnością. Przy spadku wilgotności uruchamia zraszacz. Potrzebuję, aby przekaźnik pracował 5 sekund i wyłączał się bez względu na wskazanie wilgotności. Timer pracuje co 15 minut. W trakcie pracy zraszacza czujnik DHT22 może nie zdążyć zgłosić wzrostu wilgotności przed upływem 5 sekund. Dlatego PK musi się wyłączyć bez względu na wilgotność.

Czy ktoś zechciałby pomóc?


Kod nie jest docelowy tylko eksperymentalny do sprawdzenia działania. Czasy również do eksperymentów.
------------------------------------------------------------

#include<Timers.h>


int klik = A3;
int PK1 = A1;

int statePK1 = HIGH;
int previous = HIGH;
int stan = 1;
unsigned long time = 0;

Timer Zraszacz;

void setup()
{
pinMode(klik, INPUT_PULLUP);
pinMode(PK1, OUTPUT);

Zraszacz.begin((SECS(1)); //docelowo 15min

}

void loop()
{
if (Zraszacz.available())
{
if(digitalRead(klik) == LOW )
{
stan = 0;
time = millis() + 1000; //docelowo 5sek
digitalWrite(PK1, LOW);
stan = 1;
}
if(stan == 1 && millis() > time)
{
digitalWrite(PK1, HIGH);
stan = 0;
}


Zraszacz.restart();
}
}

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

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: Marhef » 20 maja 2020, 00:57

Napisz jeszcze raz założenia. Program ma działać tak?
1) spada wilgotność
2) włącza się przekaźnik na 5 sekund
3) po 5 sekundach przekaźnik wyłącza się
4) kolejne włączenie przekaźnika jest realizowane po 15 minutach (nawet, jeśli wilgotność nie wzrośnie?)
A może włączyć zraszacz i zablokować jego ponowne włączenie do momentu kolejnego spadku wilgotności? Bez timera i zliczania czasu?
Rozumiem, że czujnik wilgotności działa cyfrowo? Na pewnym poziomie wilgotności zmienia stan z 0 na 1?

Może z tym pomogę, ale rzadko jestem przed komputerem, więc może to potrwać :)
ewmario
Młodszy majsterkowicz
Posty: 7
Rejestracja: 17 maja 2020, 12:10

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: ewmario » 21 maja 2020, 23:21

Przepraszam, ale miałem sporo ciężkiej pracy i zmęczenie nie pozwoliło odpisać.

Może opiszę to po swojemu. Mam już większość potrzebnego kodu. Mielę jeszcze co nieco ale pomalutku. O dziwo coraz więcej zostaje w głowie.

Jeśli chodzi o timery to mam ich kilka. A właściwie wszystko poza regulacją 2 kanałów PWM oświetlenia (świt/zmierzch wariował mi w timerze) Bez timerów trochę się toto wszystko blokowało. Już mi zaczęły sekundy na LCD przeskakiwać po kilka naraz. Piszę sobie ten kod na "piechotę". Od kiedy popakowałem to wszystko do timerów jest OK. Narazie :)

Skład projektu:

DHT11, DHT22; Dallas 18B20; RTC I2C, LCD I2C, dwa wentylatory (jeden PWM drugi ON/OFF), kontaktron poziomu wody, pompka 5V napowietrzająca awaryjna, kontrola zasilania 230V, tryb awaryjny z czasowym podtrzymaniem UNO R3, pompki awaryjnej i 5 szt diod LED (przy okazji) do oświetlenia strategicznych punktów mieszkania.
Wszystkie zmienne pomiarowe mam w int. Nie potrzebuję dziesiętnych ani setnych. Skończyły mi się wszystkie piny w UNO. Właśnie jestem na etapie rozpracowywania expandera PCF8574. Dziwnie mi się ten projekt rozrasta. A miałem zrobić tylko podgląd temperatury i wilgotności w paludarium, akwarium i mieszkaniu, Ale ta zabawka przebiła nawet kolejkę elektryczną :)

Wiedzę na temat Arduino mam bliską logicznemu zeru ale zawziąłem się i to skończę. Szczególnie, że moim celem jest nie tyle nauka programowania co pochłonięcie tyle, ile pusty łeb będzie w stanie pochłonąć a później spróbuje zarazić tym wnuczka. Ma dziś 5 lat to ja mam jeszcze ze trzy na pochłanianie.

Dobra. Wygląda to tak:

1. na poziomie 75% wilgotności i rozwartym kontaktronie poziomu wody (zwarcie informuje UNO, że zbiornik jest pusty, PK pompki jest unieruchamiany i miga czerwona LED) uruchamiana jest pompka zraszacza

2. jako czujnik pracuje DHT22. Eksperymentując z nim zauważyłem, że nie zawsze reaguje w ciągu 5 sek. Rzecz w tym, że nie chcę wszystkiego zatopić i 5 sek to optymalny czas zraszania. Dlatego też chciałbym, żeby po uruchomieniu pracował 5 sek i ignorował stan kontaktronu aż do kolejnego pomiaru wilgotności. Z tym 15 min może być różnie. Narazie DHT22 pracuje w warunkach improwizowanych. W akwarium, w którym go testuję, zmieniając wilgotność zamgławiaczem, zmiany następują dość szybko. W paludarium, w którym będzie "mieszkał" docelowo, warunki są stabilniejsze. Możliwe, że nawet rozważę pomiar np. co godzinę.

3. Myślałem o tym, żeby jak pisałeś, wyjąć to z timera i uzależnić od wilgotności. Ale wilgotność ma drugorzędne znaczenie. Zraszanie nie służy podniesieniu wilgotności, tylko zmoczeniu powierzchni liści roślin. Paludarium jest zbiornikiem zamkniętym o kubaturze 330L. Ma niewielkie otwory wentylacyjne. Będzie pracował w nim wentylator (PWM o którym pisałem) Całą dobę około 30% RPM (walka z pleśnią). Kiedy wilgotność wzrośnie (lato) do 90% wentylator wejdzie na 50% RPM. Kiedy skoczy powyżej 95% (już tak miałem) niewielki elektromagnes otworzy klapkę w pokrywie nad wentylatorem a wentylator z prędkością 100% RPM zrobi przeciąg. DHT22 będzie wtedy wariował. Dlatego wolę cykliczne pomiary (częstotliwość dopasuję już na gotowo po zamontowaniu wszystkiego (obecnie jest w trakcie tworzenia i stopniowego testowania)

4. Oczywiście przekaźnik pompy będzie uruchamiany tylko w przypadku spadku wilgotności poniżej 85%.

To wszystko co opisałem jest już napisane (a raczej adoptowane z rożnych rozwiązań z internetu i częściowo napisane osobiście) i najważniejsze nie mam żadnego delaya :) Nie mogę jedynie zmusić tego przekaźnika do ignorowania sygnału z DHT po pierwszym uruchomieniu.
Awatar użytkownika
Marhef
Złota rączka
Posty: 1261
Rejestracja: 18 lis 2011, 02:18

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: Marhef » 21 maja 2020, 23:48

Niezły projekt :-)
Jeśli chcesz, żeby zraszacz był blokowany przez czas do kolejnego pomiaru, to utwórz dodatkową zmienną blokującą, ustawiaj jej wartość jak włączysz przekaźnik, zeruj wartość przy pomiarze wilgotności. A zanim włączysz przekaźnik sprawdzaj tą zmienną. Coś w tym stylu:

Kod: Zaznacz cały

if (wilgotnosc<85% && blokada=0) {
  Wlacz_przekaznik();
  blokada =1;
}
A przy pomiarze wilgotności dodaj linijkę:

Kod: Zaznacz cały

blokada =0;
stiven
Złota rączka
Posty: 1643
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: stiven » 22 maja 2020, 10:47

Kod: Zaznacz cały

#include<Timers.h>


int klik = A3;
int PK1 = A1;

int statePK1 = HIGH;
int previous = HIGH;
int stan = 1;
unsigned long time = 0;

Timer Zraszacz;

void setup()
{
  pinMode(klik, INPUT_PULLUP);
  pinMode(PK1, OUTPUT);

  Zraszacz.begin((SECS(1)); //docelowo 15min

}

void loop()
{
  if (Zraszacz.available())		//if "główny"
  {
    if(digitalRead(klik) == LOW )
    {
      stan = 0;
      time = millis() + 1000; //docelowo 5sek
      digitalWrite(PK1, LOW);
      stan = 1;
    }
	
    if(stan == 1 && millis() > time)	/////////////ten if///////////////
    {
      digitalWrite(PK1, HIGH);
      stan = 0;
    }


  Zraszacz.restart();
  }
}
Problem w tym kodzie jest taki, że "ten if", który zaznaczyłem komentarzem, jeśli nie wykona się od razu (a ma się wykonać dopiero po 1 sekundzie/5 sekundach), to już się nie wykona w danym cyklu timera, bo program wyjdzie z "głównego" ifa timera (każda linijka kodu w ifie obsługi timera jest "brana pod uwagę" tylko raz i program potem wychodzi z obsługi timera, no chyba że byś zrobił jakąś pętlę "oczekującą" na wykonanie po określonym czasie, ale przy obsłudze timerów chyba nie jest to wskazane). Jeśli chcesz pozostawić timer, to by trzeba było "wyrzucić" część kodu poza główny if timera, ale ogólnie też ten timer jest niepotrzebny i można to by było prosto wykonać za pomocą samego millis(). No ale może być z timerem i bym zrobił to wtedy tak:

Kod: Zaznacz cały

#include<Timers.h>


int klik = A3;
int PK1 = A1;

int statePK1 = HIGH;
int previous = HIGH;
int stan = 0;
unsigned long time = 0;

Timer Zraszacz;

void setup()
{
  pinMode(klik, INPUT_PULLUP);
  pinMode(PK1, OUTPUT);

  Zraszacz.begin((SECS(5)); //docelowo 15min

}
void loop()
{
  if (Zraszacz.available())	//jeśli timer zliczył ustawiony czas
  {
    if (digitalRead(klik) == LOW)	//jeśli nastąpił spadek wilgotności
    {
      time = millis() + 1000; //docelowo 5sek
      digitalWrite(PK1, LOW);
      stan = 1;
    }
	
    Zraszacz.restart();
  }
	
  if(stan == 1 && millis() > time)	//jeśli włączony został przekaźnik zraszania i minął określony czas
  {
    digitalWrite(PK1, HIGH);
    stan = 0;
  }
}
No i jak chcesz testować ten kod, to czas timera musi być większy niż 1 sekunda, tak żeby był dłuższy niż czas po jakim zadziała if wyłączający, bo tak to to nie ma sensu, bo teoretycznie jeśli ten czas będzie taki sam, to zraszanie będzie trwało ciągle, bez żadnej przerwy i nie będziesz wiedział, czy kod działa prawidłowo. Tutaj zraszanie powinno działać przez 1 sekundę na 5 sekund jeśli będzie potrzebne.
ewmario
Młodszy majsterkowicz
Posty: 7
Rejestracja: 17 maja 2020, 12:10

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: ewmario » 22 maja 2020, 17:49

Dziękuję za zainteresowanie i odpowiedzi. Dziś już nie sprawdzę propozycji w praktyce. Ogarnę to jutro.

Stiven. Czy mi się wydaje, czy przed if (digitalRead(klik) == LOW) brakuje złapania aktualnej wartości millis()?
stiven
Złota rączka
Posty: 1643
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: stiven » 22 maja 2020, 21:14

ewmario pisze:
22 maja 2020, 17:49
Stiven. Czy mi się wydaje, czy przed if (digitalRead(klik) == LOW) brakuje złapania aktualnej wartości millis()?
Nie, nie brakuje. Zapis wartości z millis() do zmiennej time i dodanie odpowiedniej wartości do opóźnienia jest wewnątrz tego ifa, który podałeś. I tylko wtedy, kiedy ten if się wykona jest to potrzebne. Ostatni if wyłączający w innym przypadku nie będzie potrzebował tej wartości, bo ma się nie wykonywać, wartość zmiennej stan na to nie pozwoli i nie potrzeba wtedy też wartości z millis() w zmiennej time.
Ale właśnie jeszcze jedna rzecz. Żeby mieć pewność, że program uruchomi się z wyłączonym zraszaniem, trzeba dodać odpowiednią linijkę do setup()(stan na pinach ustawionych jako wyjście jest przypadkowy jeśli w programie go nie ustawimy, dlatego warto/trzeba odpowiedni stan początkowy ustawić w setup()). Tak jak tutaj w kodzie, który napisałem z wykorzystaniem samego millis(), bez timera:

Kod: Zaznacz cały

int klik = A3;
int PK1 = A1;

int statePK1 = HIGH;
int previous = HIGH;
int stan = 0;
int start = 0;
unsigned long time_start = 0;
unsigned long time_stop = 0;

void setup()
{
  pinMode(klik, INPUT_PULLUP);
  pinMode(PK1, OUTPUT);

  digitalWrite(PK1, HIGH);	//wyłączenie zraszania
}
void loop()
{
  if(start == 0) 
  {
    time_start = millis() + 5000;	//dla 15 minut będzie 900000
    start = 1;
  }

  if (millis() > time_start)	//jeśli minął określony czas do sprawdzenia, czy spadła wilgotność
  {
    if (digitalRead(klik) == LOW)	//jeśli nastąpił spadek wilgotności
    {
      time_stop = millis() + 1000; //docelowo 5sek
      digitalWrite(PK1, LOW);
      stan = 1;
      start = 0;
    }
  }
	
  if(stan == 1 && millis() > time_stop)	//jeśli włączony został przekaźnik zraszania i minął określony czas
  {
    digitalWrite(PK1, HIGH);
    stan = 0;
  }
}
Tutaj trochę skrócona wersja:

Kod: Zaznacz cały

int klik = A3;
int PK1 = A1;

int statePK1 = HIGH;
int previous = HIGH;
int stan = 0;
unsigned long time_start = 0;
unsigned long time_stop = 0;

void setup()
{
  pinMode(klik, INPUT_PULLUP);
  pinMode(PK1, OUTPUT);

  digitalWrite(PK1, HIGH);	//wyłączenie zraszania
}
void loop()
{
  if (millis() > time_start)	//jeśli minął określony czas do sprawdzenia (+ zaraz po uruchomieniu programu), czy spadła wilgotność
  {
    time_start = millis() + 5000;	//dla 15 minut będzie 900000
    if (digitalRead(klik) == LOW)	//jeśli nastąpił spadek wilgotności
    {
      time_stop = millis() + 1000; //docelowo 5sek
      digitalWrite(PK1, LOW);
      stan = 1;
    }
  }
	
  if(stan == 1 && millis() > time)	//jeśli włączony został przekaźnik zraszania i minął określony czas
  {
    digitalWrite(PK1, HIGH);
    stan = 0;
  }
}
Różnica będzie taka, że w tym drugim programie już w momencie uruchomienia programu będzie sprawdzenie czy potrzebne jest zraszanie. W tym pierwszym i w tym z timerem pierwsze sprawdzenie będzie dopiero po ustalonym czasie sprawdzania.
ewmario
Młodszy majsterkowicz
Posty: 7
Rejestracja: 17 maja 2020, 12:10

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: ewmario » 23 maja 2020, 11:09

Jeszcze tego nie testowałem w praktyce. Dziękuję.
Narazie próbuję zrozumieć ten kod. Jako, że wiedzę mam znikomą to zwoje mózgowe się prostują. Jak ogarnę zrozumienie to przetestuję.
stiven
Złota rączka
Posty: 1643
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: stiven » 23 maja 2020, 12:56

Dopisałem trochę komentarzy do kodu, może łatwiej będzie zrozumieć. Zauważyłem, że w tym pierwszym kodzie trzeba przenieść jedną linijkę, bo tak jak tam wcześniej było, to kiedy minie określony czas do sprawdzenia czy spadła wilgotność, a by nie spadła, to kolejne sprawdzenie nie byłoby po określonym czasie, tylko cały czas dopóki nie byłoby spadku wilgotności, bo nie byłoby pobrania aktualnego czasu do opóźnienia sprawdzania.

Kod: Zaznacz cały

int klik = A3;
int PK1 = A1;

int statePK1 = HIGH;
int previous = HIGH;
int stan = 0;
int start = 0;
unsigned long time_start = 0;
unsigned long time_stop = 0;

void setup()
{
  pinMode(klik, INPUT_PULLUP);
  pinMode(PK1, OUTPUT);

  digitalWrite(PK1, HIGH);	//wyłączenie zraszania
}
void loop()
{
  if(start == 0)	//if do zapisywania opóźnienia do zmiennej time_start
  {
    time_start = millis() + 5000; //zapisanie opóźnienia po jakim ma zadziałać if do sprawdzania czy spadła wilgotność
    start = 1;	//zablokowanie ponownego wykonania ifa
  }

  if (millis() > time_start)	//jeśli minął określony czas do sprawdzenia, czy spadła wilgotność
  {
    if (digitalRead(klik) == LOW)	//jeśli nastąpił spadek wilgotności
    {
      time_stop = millis() + 1000; //zapisanie opóźnienia po jakim ma zadziałać if wyłączający
      digitalWrite(PK1, LOW);
      stan = 1;		//odblokowanie ifa wyłączającego zraszanie
    }
    start = 0;	//odblokowanie ifa zapisującego opóźnienie do zmiennej time_start
  }
	
  if(stan == 1 && millis() > time_stop)	//jeśli odblokowana została możliwość wykonania ifa (zmienna stan) i minął określony czas
  {
    digitalWrite(PK1, HIGH);
    stan = 0;	//zablokowanie ponownego wykonania ifa
  }
}

Kod: Zaznacz cały

int klik = A3;
int PK1 = A1;

int statePK1 = HIGH;
int previous = HIGH;
int stan = 0;
unsigned long time_start = 0;	//można ustawić inną wartość, to pierwszy if wykona się po określonym czasie od uruchomienia programu, a nie od razu
unsigned long time_stop = 0;

void setup()
{
  pinMode(klik, INPUT_PULLUP);
  pinMode(PK1, OUTPUT);

  digitalWrite(PK1, HIGH);	//wyłączenie zraszania
}
void loop()
{
  if (millis() > time_start)	//od razu po uruchomieniu programu millis() będzie większe od time_start (przy ustawionej wartości 0), później po upływie określonego czasu według linijki poniżej 
  {
    time_start = millis() + 5000;	//zapisanie opóźnienia po jakim ma zadziałać if do sprawdzania czy spadła wilgotność
    if (digitalRead(klik) == LOW)	//jeśli nastąpił spadek wilgotności
    {
      time_stop = millis() + 1000; //zapisanie opóźnienia po jakim ma zadziałać if wyłączający
      digitalWrite(PK1, LOW);
      stan = 1;		//odblokowanie ifa wyłączającego zraszanie
    }
  }
	
  if(stan == 1 && millis() > time_stop)	//jeśli odblokowana została możliwość wykonania ifa (zmienna stan) i minął określony czas
  {
    digitalWrite(PK1, HIGH);
    stan = 0;	//zablokowanie ponownego wykonania ifa
  }
}
A jeszcze w drugim programie nie poprawiłem nazwy zmiennej time na nową time_stop w ostatnim ifie.
ewmario
Młodszy majsterkowicz
Posty: 7
Rejestracja: 17 maja 2020, 12:10

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: ewmario » 24 maja 2020, 23:26

Witam ponownie.

W telegraficznym skrócie. Za duży głąb jeszcze jestem, aby to wszystko ogarnąć. Albo za stary :) na naukę.
Kombinowałem i nic mi z tego nie wychodziło. Kody gotowce podane przez Was nie chciały mi działać (testowane w osobnym sketchu) tak jak chciałem. A nawet, gdyby zadziałay, to i tak Aż nagle wpadłem na pomysł aby co timer włączył inny timer wyłączył. I tak oto powstał kolejny timer w kolekcji, który w połączeniu z millis() wyłącza mi przekaźnik. Tzn tam nie będzie przekaźnika tylko jakiś tranzystor albo optotriak.
Tak oto ustawiając czas działania timera sprawdzającego wilgotność reguluję częstotliwość (ewentualnego) zraszania.

Dzięki koledze stiven i jego komentarzom, załapałem wreszcie o co biega ze zmienną stan. Jakoś nie mogłem tego załapać.
Wreszcie zacząłem chwytać jak działa millis. Dodam, że kod wyłączenia z uzyciem millis napisałem całkiem sam po długim czytaniu i jeszcze dłuzszym tentegowaniu w glowie. Nie podglądałem przy pisaniu...

Narazie dziękuję za pomoc. Nie będę truł. Pewnie macie lepsze zajęcia. A i tak za mało jeszcze rozumiem. Ale jak skończę wypociny i przetestuję to je tutaj wrzucę. Może jakiemuś laikowi się przydadzą.

Pozdrawiam.
ewmario
Młodszy majsterkowicz
Posty: 7
Rejestracja: 17 maja 2020, 12:10

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: ewmario » 27 maja 2020, 13:19

Witam ponownie. Miałem nie truć, ale jedna rzecz nie daje mi spokoju. I nigdzie nie mogę znaleźć odpowiedzi.

Dlaczego dosłownie wszędzie widzę same finkcje int?
Np. sterowanie jasnością led. Wiadomo, że wartość analogWrite nie przekroczy 255. Lub funcje digitalWrite operują 0 i 1. Podobnie odczyt czasu. Czemu int Godz a nie byte Godz? Nie będzie wartości wyższej jak 24 lub dla minut 56 ewentualnie sekund 60. Czemu wszyscy używają int zamiast byte? Przecież int zajmuje więcej pamięci niż byte. Chyba, że czegoś nie łapię.
stiven
Złota rączka
Posty: 1643
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: stiven » 27 maja 2020, 14:02

Dokładnie mówiąc, int to typ danych, nie funkcja. Funkcja to coś innego. Ja na własne potrzeby daje typy odpowiednie, ale ze względu na to, że właśnie najczęściej int jest wszędzie używany w przypadku arduino, to ja na forum też już staram się używać int, żeby nie wprowadzać niepotrzebnego zamieszania czymś, czego ktoś może nie rozumieć. Ale możesz spokojnie używać inne typy w zależności od potrzeb.

Int w arduino zajmuje 2 bajty, typ byte i char zajmują 1 bajt, a zmienna typu boolean lub bool, chociaż może przyjmować tylko dwie wartości, czyli ma zakres jednego bita, to i tak zajmuje 1 bajt w pamięci, bo tak to jest zorganizowane, że zmienne są alokowane na pełny bajt/bajty. W danym jednym bajcie pamięci nie zostanie zaalokowanych więcej zmiennych niż jedna.
ewmario
Młodszy majsterkowicz
Posty: 7
Rejestracja: 17 maja 2020, 12:10

Re: Program na Arduino/Prośba o pomoc/ Przekaźnik

Post autor: ewmario » 27 maja 2020, 18:12

Dzięki.
Pisałem to w pracy i się przejęzyczyłem. Faktycznie int to nie funkcja. Ale dopiero się uczę.
Gryzło mnie to i musiałem spytać.
ODPOWIEDZ

Strony partnerskie: