Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
-
johnyhol
- Příspěvky: 33
- Registrován: 07 pro 2017, 21:17
- Reputation: 0
Příspěvek
od johnyhol » 16 srp 2021, 22:53
Ahoj, potřeboval bych poradit s projektem na automatické zavírání branky po setmění. Mám funkční program, ale funguje pouze pokud ho ovládám jedním spínačem (fotobuňkou). Potřeboval bych ale ještě přidat jeden spínač (koncák pro kontrolu stavu zavřeno/otevřeno), aby po setmění a při otevřené brance po určitém čase sepnulo relé a branka se zavřela. Myslel jsem si, že jenom upravím podmínku, aby se relé sepnulo jen pokud bude sepnutá fotobuňka a zároveň sepnutý spínač koncáku, ale takto to nefunguje. Spíná to i pokud zapnu jenom jeden ze spínačů. Poradí mi prosím někdo co s tím?
Díky
Tady můj kód:
Kód: Vybrat vše
//Automaticke zavirani branky po setmeni.
#define KONCAK 2 // koncak vrat
#define FOTOBUNKA 3 // fotobunka
#define CHODEC 4 // rele ovladani branky - zelena LED
unsigned long FotobunkaMillis; // cas sepnuti fotobunky
unsigned long ChodecSepnuto; // CHODEC sepnuto
unsigned long ZpozdeneSepnuti = 5000; // zpozdeni sepnuti
unsigned long ZpozdeneVypnuti = 500; // zpozdeni vypnuti
bool ChodecReady = false; // vypnuti po zpozdeni
bool ChodecStav = false; // stav sepnuti
void setup() {
pinMode(FOTOBUNKA, INPUT);
pinMode(KONCAK, INPUT);
pinMode(CHODEC, OUTPUT);
digitalWrite(CHODEC, LOW);
}
void loop() {
unsigned long currentMillis = millis();
//if (digitalRead(FOTOBUNKA) == LOW) { //funkcni, ale pouze s jednim spinacem (fotobunkou)
if ((digitalRead(FOTOBUNKA) == LOW) && (digitalRead(KONCAK) == LOW)) { //takto to nefunguje 2x spinac (fotobunka+koncak)
FotobunkaMillis = currentMillis;
ChodecReady = true;
}
if (ChodecReady) {
if ((unsigned long)(currentMillis - FotobunkaMillis) >= ZpozdeneSepnuti) {
digitalWrite(CHODEC, HIGH);
ChodecStav = true;
ChodecSepnuto = currentMillis;
ChodecReady = false; // odkomentovat pro zmenu reakce na tlacitko - zakom. porad sviti pri drzeni
}
}
if (ChodecStav) {
if ((unsigned long)(currentMillis - ChodecSepnuto) >= ZpozdeneVypnuti) {
ChodecStav = false;
digitalWrite(CHODEC, LOW);
}
}
}
-
gilhad
- Příspěvky: 779
- Registrován: 07 bře 2018, 11:22
- Reputation: 0
Příspěvek
od gilhad » 17 srp 2021, 05:12
Nevím, jaké máš schéma, ale předpokládám z kódu, že jak fotobuňka, tak koncák spínají na nulu (zem,LOW), ale máš tam zajištěno, že při rozepnutí se na nich objeví HIGH? Tedy nejspíš nějaký pullup přiměřené velikosti?
Přetrvá problém, i když změníš
Kód: Vybrat vše
pinMode(FOTOBUNKA, INPUT);
pinMode(KONCAK, INPUT);
na
Kód: Vybrat vše
pinMode(FOTOBUNKA, INPUT_PULLUP);
pinMode(KONCAK, INPUT_PULLUP);
?
-
johnyhol
- Příspěvky: 33
- Registrován: 07 pro 2017, 21:17
- Reputation: 0
Příspěvek
od johnyhol » 17 srp 2021, 09:23
Mám to zapojené jako testovací obvod vždy s pomocným rezistorem proti zemi:
Zkoušel jsem to i jak píšeš s interním odporem (INPUT_PULLUP), ale pořád to nefunguje. Jenom když nechám jedno tlačítko tak to funguje jak má. Pokud to zkouším jako jednoduchý program s delay:
Kód: Vybrat vše
void loop() {
if ((digitalRead(FOTOBUNKA) == LOW) && (digitalRead(KONCAK) == LOW)){
delay (5000);
digitalWrite(LED, HIGH);
delay (2000);
digitalWrite(LED, LOW);
}else{
digitalWrite(LED, LOW);
}
}
tak to taky funguje.
-
Přílohy
-
-
ondraN
- Příspěvky: 932
- Registrován: 08 srp 2019, 20:01
- Reputation: 0
Příspěvek
od ondraN » 17 srp 2021, 10:09
Tak, jak to máš zapojené, je při sepnutí přečtená úroveň HIGH a při rozepnutí úroveň LOW. Pokud chceš udělat nějakou akci, když jsou oba spínače sepnuté tak bude podmínka
Kód: Vybrat vše
if ((digitalRead(FOTOBUNKA) == HIGH) && (digitalRead(KONCAK) == HIGH)) {
//akce pri sepnuti obou
}
Při tomto zapojení nepoužívej INPUT_PULLUP, to by se tlouklo.
-
johnyhol
- Příspěvky: 33
- Registrován: 07 pro 2017, 21:17
- Reputation: 0
Příspěvek
od johnyhol » 17 srp 2021, 16:51
To už jsem zkoušel taky, jen se invertuje styl ovládání, ale pořád to nedělá co má tzn. nespíná to pouze když jsou sepnuty (nebo při obrácené logice vypnuty) oba spínače. Prostě když jeden uvolním/sepnu tak to po nastaveném čase sepne relé i když je podmínka složená. S časováním pomocí millis nemám zkušenosti tak nevím co je v kódu špatně, když to s časováním pomocí delay funguje při stejné podmínce správně.
-
Pacok
- Příspěvky: 33
- Registrován: 08 bře 2020, 10:14
- Reputation: 0
Příspěvek
od Pacok » 17 srp 2021, 18:20
Zbytocne si podla mna komplikujes zivit.V zapojeni pphonov bran original z obchodu mas tiez na koncakoch len odpojenie motora.Ziadne serepeticky.Tym vies ze ak prejde koncakom nic ti brana neznici.
-
johnyhol
- Příspěvky: 33
- Registrován: 07 pro 2017, 21:17
- Reputation: 0
Příspěvek
od johnyhol » 17 srp 2021, 22:00
Já vím že si komplikuju život, ale nedá mi to spát a tak to chci vyřešit a pak to případně použít i jinde kde aktuálně používám delay.
-
kiRRow
- Příspěvky: 1152
- Registrován: 07 kvě 2019, 07:03
- Reputation: 0
- Bydliště: Opava
Příspěvek
od kiRRow » 18 srp 2021, 10:25
Ze sériové linky si vyčti skutečné stavy (neocenitelný pomocník při debugování a trasování programu), co když jedna věc je aktivní HIGH a druhá je aktivní LOW ?
-
johnyhol
- Příspěvky: 33
- Registrován: 07 pro 2017, 21:17
- Reputation: 0
Příspěvek
od johnyhol » 26 srp 2021, 06:57
Ahoj, stavy znám(přesto jsem to ještě prověřil přes sériovou linku), problém je jinde. Po přidání druhé podmínky (když vznikne složená) to reaguje až po znovu sepnutí jednoho ze spínačů a to je špatně. Já potřebuju takovou reakci, že když se rozepnou oba spínače, tak hned začne odpočet (např. 5s) a pak sepne relé na 1s.
Jako je to tady:
Kód: Vybrat vše
//Automaticke zavirani branky po setmeni.
#define KONCAK 2 // koncak vrat
#define FOTOBUNKA 3 // fotobunka
#define CHODEC 4 // rele ovladani branky - zelena LED
unsigned long FotobunkaMillis; // cas sepnuti fotobunky
unsigned long ChodecSepnuto; // CHODEC sepnuto
unsigned long ZpozdeneSepnuti = 5000; // zpozdeni sepnuti
unsigned long ZpozdeneVypnuti = 1000; // zpozdeni vypnuti
bool ChodecReady = false; // vypnuti po zpozdeni
bool ChodecStav = false; // stav sepnuti
void setup() {
pinMode(FOTOBUNKA, INPUT);
pinMode(KONCAK, INPUT);
pinMode(CHODEC, OUTPUT);
digitalWrite(CHODEC, LOW);
Serial.begin(600);
}
void loop() {
if ((digitalRead(FOTOBUNKA) == LOW) && (digitalRead(KONCAK) == LOW)) {
Serial.println("otevreno+tma");
delay(5000);
digitalWrite(CHODEC, HIGH);
delay(1000);
digitalWrite(CHODEC, LOW);
}
if (digitalRead(FOTOBUNKA) == HIGH){
Serial.println("svetlo");
}else{
Serial.println("tma");
}
if (digitalRead(KONCAK) == HIGH){
Serial.println("zavreno");
}else{
Serial.println("otevreno");
}
}
-
ondraN
- Příspěvky: 932
- Registrován: 08 srp 2019, 20:01
- Reputation: 0
Příspěvek
od ondraN » 26 srp 2021, 10:20
Mohl bys nějak rozumně napsat, jak to má vlastně fungovat? Možná jsem nějak přibržděný, ale stále v tom nemám jasno.
Označ spínače třeba Tma, Open, Rele a vypiš do tabulky co se má stát s označením stavů. To ti pak i velmi pomůže s tvorbou programu.
Např.
Zap-->stav0
stav0 Tma=r, Open=r, -->stav0
Tma=r, Open=s,-->stav0
Tma=s, Open=s, -->Rele=on na 1s, stav1
stav1 Tma=s, Open=r, -->stav1
Tma=s, Open=s,-->stav0
atd.
A pak v programu uděláš nekonečnou smyčku a stavovou proměnou a v příkazu switch budeš řešit jednotlivé akce a přechod mezi stavy. Je to maximálně přehledné a jednoduché na programování. V technické terminologii se tomu říká stavový automat. Je to taky ideální řešení pro zpracování více souběžných činností na jednojádrovém procesoru.
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 21 hostů