Sepnutí relé pomocí kapacitního tlačítka

rex001
Příspěvky: 5
Registrován: 06 bře 2020, 12:39
Reputation: 0

Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od rex001 » 06 bře 2020, 12:45

Zdraví, potřebuji poradit, mám naprogramované relé ve smyčce, ale potřebuji ho občas sepnout kapacitním tlačítkem, zkoušel jsem různé varianty ale nemůžu to pořád správně sestavit. Jsem v tom trochu začátečník a určitě mi chybí nějaký základní / banální příkaz.

zatím to mám sestaveno takto:
#define RELE1_PIN 6
#define RELE2_PIN 5
#define pinTlacitko 2

int stavTlacitka = 0;


void setup() {
pinMode(RELE1_PIN, OUTPUT);
pinMode(RELE2_PIN, OUTPUT);
pinMode(pinTlacitko, INPUT);
attachInterrupt(digitalPinToInterrupt(pinTlacitko), prerus, RISING);

}

void loop() {

{ digitalWrite(RELE1_PIN, HIGH);
digitalWrite(RELE2_PIN, HIGH);
delay(10000);
digitalWrite(RELE1_PIN, LOW);
digitalWrite(RELE2_PIN, LOW);
delay(5000); }

{ if (stavTlacitka == HIGH)
digitalWrite(RELE1_PIN, HIGH);
delay (500);
digitalWrite(RELE1_PIN, LOW);
stavTlacitka = LOW;
}
}
void prerus(){
stavTlacitka = HIGH;
}

Předem děkuji.

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od pavel1tu » 06 bře 2020, 12:49

Kod se vklada pomoci tlacitka </>

Mas tam nejak divne pouzivane zavorky { } u podminek IF
Pokud se nikdo neozve, vecer ti to opravim
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

rex001
Příspěvky: 5
Registrován: 06 bře 2020, 12:39
Reputation: 0

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od rex001 » 06 bře 2020, 13:19

Dobře, děkuji. :)

rex001
Příspěvky: 5
Registrován: 06 bře 2020, 12:39
Reputation: 0

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od rex001 » 06 bře 2020, 13:54

pavel1tu píše:
06 bře 2020, 12:49
Kod se vklada pomoci tlacitka </>

Mas tam nejak divne pouzivane zavorky { } u podminek IF
Pokud se nikdo neozve, vecer ti to opravim
Ještě jsem zkoušel tuhle metodu, ale taky to nefunguje. :D

Kód: Vybrat vše

#define RELE1_PIN 6
#define RELE2_PIN 5 
#define pinTlacitko 2
bool stav1, rezim1;
int stavTlacitka = 0;


void setup() {
 pinMode(RELE1_PIN, OUTPUT);
 pinMode(RELE2_PIN, OUTPUT);
 pinMode(pinTlacitko, INPUT);
}

void loop() {
 
 digitalWrite(RELE1_PIN, HIGH);   //relé1 rozepnuto (záleží také na typu)
 digitalWrite(RELE2_PIN, HIGH);   //relé2 rozepnuto (záleží také na typu)
 delay(10000);                     //1 s čekání
 digitalWrite(RELE1_PIN, LOW);    //relé1 sepnuto (záleží také na typu relé)                 //1 s čekání
 digitalWrite(RELE2_PIN, LOW);    //relé2 sepnuto (záleží také na typu relé)
 delay(5000);{
 stav1 = false;
}
 if (stavTlacitka == HIGH){
 digitalWrite(RELE1_PIN, HIGH);
 delay (500);
 digitalWrite(RELE1_PIN, LOW);
 stavTlacitka = LOW;
 rezim1 = true;
  
}
}
void NastaveniVystupu() {
 digitalWrite(RELE1_PIN, stav1 || rezim1); 
}

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od ondraN » 06 bře 2020, 15:40

Ta proměnná ošetřovaná v interruptu by měla být definována takto

Kód: Vybrat vše

volatile int stavTlacitka = 0;

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od pavel1tu » 06 bře 2020, 16:28

Ty delay() jsou v programu kde chceš dělat ještě něco jiného dost naprd
pokud program stojí na delay(), nic jiného nedělá, tak musíš v tom přerušení zpracovat vše co chceš uělat od tlačítka

Takto budou neustále dělat rele
ON - 10s
OFF - 5s
a dokola

když stiskneš tlačítko, tak když bude rele1 OFF se sepne a po 500ms vypne
pokud bude zapnuté, tak se jen po 500ms vypne
(chtělo by to přesný popis co chceš aby to dělalo)

Stisknuti tlacitka musi privest na pin 2 log HIGH

Kód: Vybrat vše

#define RELE1_PIN 6
#define RELE2_PIN 5
#define pinTlacitko 2

volatile int stavTlacitka = 0;


void setup() 
{
  pinMode(RELE1_PIN, OUTPUT);
  pinMode(RELE2_PIN, OUTPUT);
  pinMode(pinTlacitko, INPUT);
  attachInterrupt(digitalPinToInterrupt(pinTlacitko), prerus, RISING);

}

void loop() 
{ // tady se bude pora dokola spinat a vypinat obe rele 
  digitalWrite(RELE1_PIN, HIGH);
  digitalWrite(RELE2_PIN, HIGH);
  delay(10000);
  digitalWrite(RELE1_PIN, LOW);
  digitalWrite(RELE2_PIN, LOW);
  delay(5000); 
}
void prerus()
{  
  detachInterrupt(digitalPinToInterrupt(pinTlacitko));  //pozastavi interup kvuli zakmitum tlacitka
  stavTlacitka = HIGH;            //kdyby bylo potreba jinde
  digitalWrite(RELE1_PIN, HIGH);
  delay (500);
  digitalWrite(RELE1_PIN, LOW);
  stavTlacitka = LOW;            //kdyby bylo potreba jinde
  attachInterrupt(digitalPinToInterrupt(pinTlacitko), prerus, RISING);
}
Naposledy upravil(a) pavel1tu dne 06 bře 2020, 16:51, celkem upraveno 1 x.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od pavel1tu » 06 bře 2020, 16:46

Tohle je cistsi - nemam jak vyzkouset a jsou tammozna preklepy
prvni smycka zkouma zda ubehlo 5s a pokud jsou rele vypnuty, sepne je
druha smycka zkouma zda ubehlo 10s a pokud jsou rele zapnuty, vypne je
treti smycka provede to co jsi mel predtim, pokud probehlo preruseni od tlacitka
v preruseni se dělá cojsi chtěl + par věci pro jistotu

pokud to nebude fungovat napis, ja si to postavím doma a testnu

Kód: Vybrat vše

#define RELE1_PIN 6
#define RELE2_PIN 5
#define pinTlacitko 2

volatile int stavTlacitka = 0;
unsigned long currentMillis, previousMillis;
int stavRele = 0;

void setup() 
{
  pinMode(RELE1_PIN, OUTPUT);
  pinMode(RELE2_PIN, OUTPUT);
  pinMode(pinTlacitko, INPUT);
  attachInterrupt(digitalPinToInterrupt(pinTlacitko), prerus, RISING);
  previousMillis = millis();   //nacteni casu od spusteni

}

void loop() 
{ // tady se bude zapinat rele po 5s pokud je VYP
   currentMillis = millis();      
   if(currentMillis - previousMillis > 5000 && stavRele == 0) {   
        previousMillis = currentMillis;  
        digitalWrite(RELE1_PIN, HIGH);
        digitalWrite(RELE2_PIN, HIGH);
        stavRele = 1;
   }
   // tady se bude vypinat rele po 10s pokud je ZAP
   if(currentMillis - previousMillis > 10000 && stavRele == 1) {   
        previousMillis = currentMillis;  
        digitalWrite(RELE1_PIN, LOW);
        digitalWrite(RELE2_PIN, LOW);
        stavRele = 0;
   }

  if (stavTlacitka == HIGH) {
      digitalWrite(RELE1_PIN, HIGH);
      delay (500);
      digitalWrite(RELE1_PIN, LOW);
      stavTlacitka = LOW;           
  }


}
void prerus()
{  
  detachInterrupt(digitalPinToInterrupt(pinTlacitko));  //pozastavi interup kvuli zakmitum tlacitka
  stavTlacitka = HIGH; 

  // proti zakmitum tlacitka muze se zrusit pokud nejsou nebo zvetsit pokud jsou velke             
  delay (50);             
  
  attachInterrupt(digitalPinToInterrupt(pinTlacitko), prerus, RISING);  //obnovi interup kvuli zakmitum tlacitka 
}




UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od gilhad » 06 bře 2020, 17:19

obavam se, ze dettachInterrupt sice vymaze danou funkci ze seznamu interruptu (tedy dalsi stisk tlacitka tam nezkusi skocit), ale interrupty sam o sobe nepovoli, takze nasledujici delay() rozhodne nebude fungovat spravne (porad je v kontextu probihajiciho inerruptu) a nejspis Arduino zablokuje zcela (protoze v kontextu interruptu se mu neupdatuje cas)

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od pavel1tu » 06 bře 2020, 17:38

Takže detachInterrupt zrušit a proti zákmitu dát jen delay() ?
Já ošetřuji tlačítka HW, tak toto neřeším,
tady se to jednou probíralo, že je ideální hned dát "detachInterrupt",
pak zpracovat co se chce při přerušení a opět přerušení zapnout.

Ach, nemám místo kde to vyzkoušet a ani čas ....
Pája pájí - mám jich teprve 6 hotových a ještě 14 mne čeká

Obrázek
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Sepnutí relé pomocí kapacitního tlačítka

Příspěvek od gilhad » 06 bře 2020, 19:31

Nedavat delay vubec, v interruptu nema co delat.

Nebo pred nim aspon povolit interrupty (v interruptu jsou zakazane).

(ten detach s tim problemem delay vubec nesouvisi)

----

Interruptum je v datasheetu venovano spousta stranek a neni to zcela trivialni. Ale se znacnym zjednodusenim to probiha nejak takto:

Pokud nastane nejaka sance na interrupt (treba je pin stazen dolu), tak se overi, zda je interrupt tohoto typu povolen a kdyz ne, tak se nic nestane.

Pokud jsou interrupty povolene, tak se dokonci rozdelana (ASM) instrukce, zakazou se interrupty, ulozi adresa na zasobnik a skoci na adresu interruptu (do tabulky/vektoru), kde s trochou stesti je skok na osetrujici funkci ci navrat z interruptu (IRET).

Kdyz se zavola IRET (napr. na konci te funkce), tak se povoli interrupty a ze zasobniku se nacte adresa, kam se to vrati a provede aspon jednu instrukci.

Pokud jsou interrupty zakazany, tak se poznaci zdroj interruptu do registru cekajicich interruptu. Az se interrupty povoli (a provede ta jedna instrukce), tak pokud je neco v registru cekajicich interruptu, tak se vycisti+provede interrupt s nejnizsim cislem (tedy zakazi interrupty atd ...). Pokud jsou interrupty zakazane a dojde k nekolikanasobne aktivaci zdroje, tak se tam vzdy zapise priznak (ale nikoli pocet), takze na konci se ten dotycny provede max jednou.

Pokud je i pote neco v registru, tak se postup opakuje.

(Ve skutecnosti je to samozrejme vyrazne slozitejsi)

Attach/detach vlastne jen prepisuji vektor interruptu a povoluji/zakazuji prislusny zdroj - pokud to udelas pri provadeni interruptu, tak se to provadeni stejne dokonci a az pak se povoli dalsi interrupty.

millis ctou neco, co casovy interrupt inkrementuje, tedy pri provadeni interruptu (kdy jsou interrupty zakazany) se jim to neinkrementuje a vraci furt stejnou hodnotu. Pokud interrupt trva dlouho, tak klidne muzou "ztratit" nekolik volani sveho casovace a hodnota se jim zvedne jen jednou o jeden krok. ("ztrati" se udaj o tom, kolikrat to melo inkrementovat = hodiny "stoji/ tiknou jen jednou na konci")

delay mam v .../Arduino/hardware/arduino/avr/cores/arduino/wiring.c okolo radky 106 a zavisi na micros ktere (stejne jako millis) zavisi na TIMER0_OVF_vect coz je interrupt pro timer 0 a ten se pri zakazanych interruptech nespusti, takze delay proste nekonecne ceka, az se zvetsi hodnota, ktera se nemeni (= cti proste to zatuhne).


attach/detach Interrupt jen zmanipuluje vektor interruptu a povoli/zakaze konktertni zdroj, ale celkove interrupty pochopitelne nemeni (nepovoluje/nezakazuje). Na Arduinu od zacatku jsou interrupty povoleny (kvuli milli napr.) takze neni potreba je pri pridani dalsiho povolovat (a naopak by se tim rozbila obsluha stavajicich), detach do vektoru da prazdnou funkci a zakaze zdroj, ale nikoli interrupty celkove (protoze by prestaly jit treba prave ty millis)

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 10 hostů