Vítejte na Elektro Bastlírn?
Nuke - Elektro Bastlirna
  Vytvořit účet Hlavní · Fórum · DDump · Profil · Zprávy · Hledat na fóru · Příspěvky na provoz EB

Vlákno na téma KORONAVIRUS - nutná registrace


Nuke - Elektro Bastlirna: Diskuzní fórum

 FAQFAQ   HledatHledat   Uživatelské skupinyUživatelské skupiny   ProfilProfil   Soukromé zprávySoukromé zprávy   PřihlášeníPřihlášení 

Začátečník arduino - pomoct s tlačítky - bazén (přesunuto)
Jdi na stránku 1, 2, 3, 4  Další
 
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Miniaturní počítače (Arduino, Raspberry a další)
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Rellik



Založen: Feb 17, 2017
Příspěvky: 636
Bydliště: Staré Město (UH)

PříspěvekZaslal: st prosinec 06 2017, 16:40    Předmět: Začátečník arduino - pomoct s tlačítky - bazén (přesunuto) Citovat

Zdravím vespolek. Mám v ruce své první arduino a chtěl bych si naprogramovat jednoduché hlídání bazénu viz můj dotaz v poradně ( http://www.ebastlirna.cz/modules.php?name=Forums&file=viewtopic&t=82896 ).
No i když běžně občas programuju v PHP, a myslel jsem že to nebude o moc jiné opak je pravdou.
V tom případě začínám víceméně od začátku.
Má představa programu je následující:

Stále pojede program, který dle času 2x za 24 hodin zapne postupně 2 relé. (RTC obvod je na cestě). Mezitím dle dvou teplotních čidel sepne podle nastavení další relé (nemusí spustit).
Přitom v podstatě kdykoliv mimo ty časové úseky bych chtěl v jednom případě sepnout opět ty "časové" relé ručně - jedno tlačítko(stejná doba sepnutí obou - nastavené ve funkci).
Sepnout jen jedno z těch dvou relé - druhé tlačítko.

No zatím zápasím s "blikající diodou" (hlavní program) a dvěma tlačítky (podprogramy). Hlavní program "blikání" funguje. Po stisku tlačítka ovšem další dvě diody zůstanou svítit i po puštění. To by bylo dobré, ale po dalším zmáčknutí bych chtěl aby zhasnuly. Poradí někdo jak upravit následující kód, případně řekne jestli na to jdu špatně a jak na to jít jinak?
Díky.
kód:
int G = A0; // 3x LED
int Y = A1;
int B = A2;
int zelena;
int modra;
int Tl1 = 0; // tlačítka
int Tl2 = 1;

void setup() {
    pinMode(G,OUTPUT);
    pinMode(Y,OUTPUT);
    pinMode(B,OUTPUT);
    pinMode(Tl1,INPUT_PULLUP);
    pinMode(Tl2,INPUT_PULLUP);
}

void loop() {
  zelena = digitalRead(Tl1);
  modra = digitalRead(Tl2);
  // pokud se zmáčkne Tl bude svítit modrá, pokud se pustí zhasne
  if(modra == LOW) {
          digitalWrite(B, HIGH);
          }
  // to samé jako předchozí ale jiné Tl a LED
  if(zelena == LOW) {
          digitalWrite(G, HIGH);
          }

 // hlavní program, který pojede stále
HlavniProg();


}

void HlavniProg() {
    digitalWrite(Y, HIGH);
    delay(200);
    digitalWrite(Y, LOW);
    delay(200);
}


Naposledy upravil Rellik dne so prosinec 16 2017, 8:33, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
dreamer



Založen: Oct 22, 2014
Příspěvky: 383

PříspěvekZaslal: st prosinec 06 2017, 17:15    Předmět: Citovat

Stačí použít "else". Hezky je to popsané tady třeba:

https://programmingelectronics.com/tutorial-11-if-else-statement-comparison-operators-and-conditions/
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
FHonza



Založen: Nov 20, 2012
Příspěvky: 1453
Bydliště: Praha

PříspěvekZaslal: st prosinec 06 2017, 17:27    Předmět: Citovat

kód:

if(modra == LOW) {
          digitalWrite(B, HIGH);
          }
else
 {
    digitalWrite(B, LOW);
  }


Každopádně bude chtít ošetřit debouncing tlačítek.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Rellik



Založen: Feb 17, 2017
Příspěvky: 636
Bydliště: Staré Město (UH)

PříspěvekZaslal: st prosinec 06 2017, 17:35    Předmět: Citovat

Díky vyzkouším... Zákmity tlačítek jsem včera měřil na osciloskopu (jsou celkem šílené... Smile ). Mělo by stačit přidat delay po prvním kontaktu (než se Tl pustí)...

EDIT:
tak po přidání else se projeví že ty další diody svítí jen po dobu držení tlačítka. Asi by to nějak chtělo uložit stav tlačítka po zmáčknutí a ten pak dalším stlačením negovat.


Naposledy upravil Rellik dne st prosinec 06 2017, 18:03, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
FHonza



Založen: Nov 20, 2012
Příspěvky: 1453
Bydliště: Praha

PříspěvekZaslal: st prosinec 06 2017, 17:50    Předmět: Citovat

Sem to asi špatně pochopil. Na první zmáčknutí rozsvítit, na druhý zhasnout ?

Edit: doporučuju se vyhnout delay(), to je tak nějak cesta směrem k peklu. Lepší je použít millis()
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Rellik



Založen: Feb 17, 2017
Příspěvky: 636
Bydliště: Staré Město (UH)

PříspěvekZaslal: st prosinec 06 2017, 17:55    Předmět: Citovat

Jo první klik rozsvítí, druhý zhasne...
Jo ten millis() jsem už někde našel...
Nicméně je zajímavé, že pokud přidám jen to "else" a nechám udělat výpis na monitor, tak každé tlačítko má jiný stav i když se nic nemačkalo (po resetu)...
EDIT: chyba byla si ve zvolených pinech pro tlačítka. (0, 1) když jsem je posunul na pin2 a 3, tak to jde. Myslím na jedno zmáčknutí - pokud se drží - svítí...



Screenshot_20171206_175304.png
 Komentář:

Stáhnout
 Soubor:  Screenshot_20171206_175304.png
 Velikost:  117.29 kB
 Staženo:  266 krát

Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
dreamer



Založen: Oct 22, 2014
Příspěvky: 383

PříspěvekZaslal: st prosinec 06 2017, 18:30    Předmět: Citovat

Pro testování je funkce mills() použitelná, jenom je třeba mít na paměti že po 49,7 dnů dojde k přetečení a začne počítat od 0. V celku elegantně to řeší knihovna "interval" která je vysvětlena a ke stažení na:
http://www.xpablo.cz/?p=421
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Rellik



Založen: Feb 17, 2017
Příspěvky: 636
Bydliště: Staré Město (UH)

PříspěvekZaslal: st prosinec 06 2017, 18:51    Předmět: Citovat

Dreamer:
Ty relé pak budou řízeny RTC časem, takže v podstatě ani delay ani millis nebude třeba. Max pro to hlídání prokliků na tlačítku. A jestli bude po cca 50 dnech počítat znovu od nuly je úplně jedno...

Nastíním celý program ( květen až září - jinak PWR-OFF).:
Hlavní program:
časování dvou relé brzo ráno a pozdě večer. Jedno relé sepne na cca 1 hodinu. druhé cca 20s po prvním na cca 40sekund. (filtrace a dávka chloru).Přes den hlídání dvou teplot - if(temp1 >=45 && temp2 <=24) sepne další relé (teplota soláru a teplota bazénu).

podprogramy na Tl:
Při tomto běhu programu chci dvě ovládací tlačítka, přičemž jedno bude simulovat funkci těch dvou relé (stejná funkce jen manuální - víceméně mimo ty dva automatické časy) - tady stačí jednočinné zmáčknutí - po uplynutí nastavené doby přejde opět do automatu (dávka chloru navíc).
Druhé tlačítko sepne jen jedno z těch dvou relé (s tím delším časem opět mimo nastavené časy automatu). U tohoto tlačítka je potřeba i ručního vypnutí buď stejným nebo klidně i jiným tlačítkem (vysávání).

No vlastně bude potřeba asi 3 ty tlačítka. Jedno by mělo vypnout tu "teplotní funkci pokud bude v činnosti ( pro případ vysávání pokud pojede ohřev vody).
Snad to do jara nějak splácám... Smile

EDIT: zatím mi ty Tl fungují asi tak: odkaz.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
dreamer



Založen: Oct 22, 2014
Příspěvky: 383

PříspěvekZaslal: st prosinec 06 2017, 19:59    Předmět: Citovat

To znám, taky to tak dělám Smile jenom je potřeba mít na paměti že konstrukce na nepájivém poli nejsou moc spolehlivé. Takže až něco přestane najednou fungovat nebo bude fungovat jinak než bylo zamýšleno, může být problém někde tam. U takhle jednoduchých programů řeším zákmity tlačítek pomocí "delay" 200ms. Prostě když je detekováno stisknutí tlačítka, dám 200ms pauzu pak teprve program pokračuje. Vím že to není nejčistější ale pokud to nevadí jinde tak je to nejjednoduší řešení.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
FHonza



Založen: Nov 20, 2012
Příspěvky: 1453
Bydliště: Praha

PříspěvekZaslal: st prosinec 06 2017, 20:16    Předmět: Citovat

200ms už je hodně, neznalá obsluha si bude myslet že se nic neděje a tlačítko zmáčkne znovu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
fero_b



Založen: May 17, 2004
Příspěvky: 582
Bydliště: Kosice

PříspěvekZaslal: st prosinec 06 2017, 23:20    Předmět: Citovat

Zabudni na snimanie v hlavnej slucke a delay, to je uplne zle. Spravne to ma byt spravene takto: pustis si prerusenie od casovaca, cca 50ms, v nom sa vzdy pozries na stav tlacidiel, ak nastane stav 0-1 tlacidlo bolo stlacene, 0-1 pustene, to ze sa na to pozeras kazdych 50ms ti osetri zakmity, stlacenie klavesy zapises do bufra FIFO (velost 6bytov staci) a hlavna slucka pozera ci je nieco v tomto bufri je, a vybavi danu klavesu..
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
fero_b



Založen: May 17, 2004
Příspěvky: 582
Bydliště: Kosice

PříspěvekZaslal: čt prosinec 07 2017, 9:04    Předmět: Citovat

skusim vyseknut narychlo kus kodu:

1) nadeklarujes dve premenne (2 byty, kde nacitas piny kde je navesena klavesnica, predchadzajuci stav, a sucasny stav):

uint8_t keyboard_byte_prev;
uint8_t keyboard_byte_current;

//dalej buffer a index donho:

uint8_t keyboard_buffer[KEYBOARD_BUFFER_SIZE];
uint8_t keyboard_write;

2) inicializacia - v arduine metoda "setup" (mam 4 klavesy navesene na porte H):

uint8_t key_hport = PINH & 0x78;
key_hport = key_hport<<1;
keyboard_byte_current = key_hport;
keyboard_byte_prev = keyboard_byte_current;
keyboard_write = 0x00;

3) prerusenie chodiace kazdych 60ms:

ISR (TIMER1_COMPA_vect)
{
keyboard_byte_prev = keyboard_byte_current;
uint8_t key_hport = PINH & 0x78;
key_hport = key_hport<<1;
keyboard_byte_current = key_hport;

if (((keyboard_byte_prev & 0x10) == 0x10) && ((keyboard_byte_current & 0x10) == 0)){ //button one, rising edge
//catch interrupt counter at rising edge
keyboard_byte_prev = keyboard_byte_current; //key handled
keyboard_buffer[keyboard_write] = 1; //toto je kod klavesy 1 pre stlacenie
if (keyboard_write < (KEYBOARD_BUFFER_SIZE-1)){
keyboard_write++;
}

goto label_interrupt1;
}else if (((keyboard_byte_prev & 0x10) == 0x0) && ((keyboard_byte_current & 0x10) == 0x10) ){//button one falling edge
keyboard_byte_prev = keyboard_byte_current; //short press key handled
keyboard_buffer[keyboard_write] = 2; //kod klavesy 1 pre pustenie
if (keyboard_write < (KEYBOARD_BUFFER_SIZE-1)){
keyboard_write++;
}
goto label_interrupt1;

}
...//tuna bude nasledovat dalsia klavesa (ten isty kod, len ine masky a kody klaves)



label_interrupt1: //tu pokracuje prerusenie... ak uz nic nerobi tak koniec



}

4) hlavna slucka //pre kritikov "goto" - mal som tam pekne funkcie, ale ako vidno su zakomentene, dosiel som na koniec so zasobnikom, tak som jeden-krat pouzite napastoval rovno namiesto Sad - nie az tak pekne, ale ucelne a rychlejsie Smile



for( ; ; ) {

uint8_t keyb_eval; //getKey();
if (keyboard_write == 0){ //keyboard_read){
keyb_eval = 0;
goto lab_01;
}
keyb_eval = keyboard_buffer[(keyboard_write -1)];
keyboard_write--;

lab_01:


if (keyb_eval == 1){ //push button1 response

}else if (keyb_eval == 2){ //release button1 response

}

//tu pride obsluha akcie pre dalsi buton... atd

... //dalsi tvoj kod hlavnej slucky


} //koniec hlavnej slucky
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Rellik



Založen: Feb 17, 2017
Příspěvky: 636
Bydliště: Staré Město (UH)

PříspěvekZaslal: čt prosinec 07 2017, 16:32    Předmět: Citovat

fero_b: Moc díky za radu. Nicméně moc moudrý jsem z toho nebyl. Začal jsem googlit ty funkce a narazil na jiné řešení těch tlačítek a to i s omezením těch zákmitů.
Dal jsem to dohromady, funguje - ale.
Dal jsem tu funkci blikání diody pod jedno tlačítko s tím, že se i rozsvítí dioda (jedna bliká druhá svítí). Pokud tlačítko opět zmáčknu, tak se neblikací dioda zhasne. Dotud je to OK. Problém je s tou blikací. Pokud to totiž vypnu když zrovna blikne, tak zůstane svítit. Jak to upravit aby to ten zavolaný podprogram ukončilo?
kód:
const int G = A0; // 3x LED
const int Y = A1;
const int B = A2;
int zelena;
int modra;
const int Tl1 = 2; // tlačítka
const int Tl2 = 3;
int ledState = LOW;
int gState = LOW;
int bState = LOW;
unsigned long previousMillis = 0;
const long interval = 800;

// nové
int Tl1State;
int Tl2State;
int lastTl1State = LOW;
int lastTl2State = LOW;

long lastDebounceTime = 0; 
long debounceDelay = 50;


void setup() {
    Serial.begin(9600);
    pinMode(G,OUTPUT);
    pinMode(Y,OUTPUT);
    pinMode(B,OUTPUT);
    pinMode(Tl1,INPUT_PULLUP);
    pinMode(Tl2,INPUT_PULLUP);
}

void loop() {
  zelena = digitalRead(Tl1);
  modra = digitalRead(Tl2);

// zelená dioda
   if(zelena != HIGH) {
              zelena = LOW;
   }
                       
   if(zelena != lastTl1State) {
              lastDebounceTime = millis();
              if (Tl1State == HIGH) {
                            gState = !gState;
                                     }
   }
                               
   if ((millis() - lastDebounceTime) > debounceDelay) {
                 Tl1State = zelena;
 }

 //
digitalWrite(G, gState);
lastTl1State = zelena;

// modrá dioda
   if(modra != HIGH) {
              modra = LOW;
   }
                       
   if(modra != lastTl2State) {
              lastDebounceTime = millis();
              if (Tl2State == HIGH) {
                            bState = !bState;
                                     }
   }
                               
   if ((millis() - lastDebounceTime) > debounceDelay) {
                 Tl2State = modra;
 }

 //
digitalWrite(B, bState);
lastTl2State = modra;

if(bState == HIGH) {
  HlavniProg();
}


 // hlavní program, který pojede stále
//HlavniProg();


}

void HlavniProg() {
 unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    digitalWrite(Y, ledState);
  }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
fero_b



Založen: May 17, 2004
Příspěvky: 582
Bydliště: Kosice

PříspěvekZaslal: čt prosinec 07 2017, 16:43    Předmět: Citovat

tie funkcie su z nejakeho mojho kodu, na googli to asi nenajdes, mozno ako pises nieco ine, ja riesim aj "long press" ale to som z toho co som ti napastoval dal prec aby som to velmi nezakomplikoval. Na ten kod co si poslal sa pozriem neskor:) Teoreticky by som ti cely ten handlink klavesnice mohol vyseknut z mojho projektu tak aby si to len skompiloval, ale postuduj ako sa spusti a nastavi na arduine prerusenie (ja arduino nepouzivam, pisem rovno pre procak, kde je prazdna flaska) ale urcite aj arduino nejak umoznuje nastavit vektor prerusenia, a povolit prerusenie, je to len otazka toho IDE a kompilatora co tam pouzivaju..
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Rellik



Založen: Feb 17, 2017
Příspěvky: 636
Bydliště: Staré Město (UH)

PříspěvekZaslal: čt prosinec 07 2017, 16:49    Předmět: Citovat

Kdybys na to mrkl, byl bych rád. Jinak "longpress" bych řekl, že je ok protože to můžu držet jak dlouho chci a vždy to jen buď zapne nebo vypne... Začnu zatím studovat další funkce co budu potřebovat... Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Miniaturní počítače (Arduino, Raspberry a další) Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2, 3, 4  Další
Strana 1 z 4

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra.
Nemůžete odpovídat na témata v tomto fóru.
Nemůžete upravovat své příspěvky v tomto fóru.
Nemůžete mazat své příspěvky v tomto fóru.
Nemůžete hlasovat v tomto fóru.
Nemůžete připojovat soubory k příspěvkům
Můžete stahovat a prohlížet přiložené soubory

Powered by phpBB © 2001, 2005 phpBB Group
Forums ©
Nuke - Elektro Bastlirna

Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.


PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Čas potřebný ke zpracování stránky 0.19 sekund