Close

Časovane spinaní pinu

Úvodní stránka Fórum Vaše projekty Arduino Časovane spinaní pinu

  • Toto téma obsahuje celkem 31 odpovědí. Do diskuze (5 diskutujících) se naposledy zapojil uživatel posjirka a poslední změna proběhla před 7 roky a 8 měsíci.
Aktuálně je na stránce zobrazeno 30 příspěvků - 1. až 30. (celkem z 32)
  • Autor
    Příspěvky
  • #6116
    Le_Ze
    Účastník

    Zdravim.
    Mam uno,433Mhz RF receiver, modul 4 rele a 4 kanal dalkač.
    Zmačknutím tlačitek spinam relatka.
    1 zmačknutí sepnu, 2 zmačknutí rozepnu.

    Znameho však zajima jak na to, kdyby je chtěl spinat časově.
    Zmačkne tlačitko a sepne se rele třeba na 5 minut.
    a pokud ho zmačkne znovu třeba po minutě, aby čas šel odznova.
    Poradí někdo?

    #6121
    posjirka
    Účastník

    Samozřejmě že to jde a jak na to?
    No doplnit do kodu funkci cyklovače.
    Co ti jiného mám napsat bez kodu ….

    #6124
    Le_Ze
    Účastník

    No dalkač mi vrací kod jako číslo
    Podmínkou IF hlídám ten správný.
    Pokud je pominka splněna tedy spustit třeba thead.

    Nějak však nemohu pochopit princip toho vlakna.
    Proč je u vlakna setInterval()
    Ve škole jsme měli delphi a bud bylo vlakno co vykonalo svou funkcí a ukončilo se, nebo vlakno ktere běželo furt dokola.
    Interval byl u timeru.

    A i kdybych to dal s tym theadem, nevím jak vyřešit to druhe zmačknutí po minutě

    #6126
    posjirka
    Účastník

    dej sem jednoduchý kod s funkcionalitou co potřebuješ a já ti řeknu jak to upravit.
    Chápeš, že se ptáš ze svého pohledu na věc …..? Nevidím ti do hlavy, tak ti nemůžu odpovědět. Navíc arduino nemá thead. Je jednoprocesorový 1 vláknový. Tudíž nemůže řešit 2 paralelní procesy. umí pouze mezi procesy přepínat a to ještě na základě interních časovaču resp. na principu přerušení. Jsme tu v „c++“ deplhi je trochu jinde.

    #6127
    Le_Ze
    Účastník

    Nejjednodušší řešení by bylo tady.
    https://playground.arduino.cc/Code/Timer
    Do kažede podminky dat t.pulse.

    
    #include "Timer.h"
         
         
        Timer t;
        int pin = 3;
            
        void setup()
        {
          pinMode(pin, OUTPUT);
          t.pulse(pin, 10 * 60 * 1000, HIGH); // 10 minutes  
        }
         
         
        void loop()
        {
          t.update();
        }
    

    Proč toto nefunguje jak má?
    Zapnu arduino.
    Po najetí mam na pinu 3 10 vteřin HIGH
    Pak 10 vteřin LOW
    A pak až se začne odpočitavat těch 10 minut HIGH

    #6129
    posjirka
    Účastník

    Požíváš knihovny, které nevíš jak fungují a proto se pak divíš.
    Navíc je to jak jít s bazukou na komára. Jde to mnohem elegantnějí:

    
    // zpozdeni tlacitka
    // v1
    // by JP 2016
    // program po stisku tlačítka rozsvítí LED diodu a nechá jí 5s rozsvícenou, pak ji zhasne a opět čeká na stisk tlačítka
    
    const int LED = 13; // led dioda
    const int TLACITKO = 10; // tlacitko proti zemi
    
    boolean CEKAM = false; // kdyz je true tak ceka na zhasnuti.
    unsigned long OLDTIME = 0; // strojní čas posledního stitku tlačítka
    unsigned long ZPOZDENI = 5000; // čas zpoždění zahsnutí LED diody v ms.
    unsigned long MYTIME = 0; // aktuální čas -zpoždění
    
    void setup()
    {
    	pinMode(LED, OUTPUT); // nastaveni jako vystup
    	pinMode(TLACITKO, INPUT_PULLUP); // nastaveni jako vystup
    	OLDTIME = millis();// zapamatuj si aktuální strojní čas
    }
    
    void loop()
    {
    	digitalWrite(LED, CEKAM); // zapis stav na LED
    	if (digitalRead(TLACITKO) == 0) {	// při stisku tlačitka
    		if (CEKAM == false) {	// a zhasnuté LED diodě
    			CEKAM = true; // změn stav
    			OLDTIME = millis(); // zapamatuj aktuální strojový čas
    		}
    	}
    	if (CEKAM == true) {
    		MYTIME = millis()-ZPOZDENI; // výpočet času zpoždění
    		if (MYTIME >  OLDTIME){	// porovnání aktuálního čas a OLDTIME se zpožděním
    			CEKAM = false; // když  překročím zpoždění zhasni LED diodu
    		}
    	}
    }
    
    #6130
    posjirka
    Účastník

    jo to uvodní 10s přepnutí může mít 2 příčiny:
    1, start Arduina kdy bootloader čeká na rest pro nahrání programu nebo pokračuje dál v aktuálním programu
    2, knihovna timer má na začátku reset proměnných a registru. To chvilku trvá …

    #6131
    Le_Ze
    Účastník

    Ty činske relay moduly sepinají při LOW
    Při spuštění arduina je na pinu HIGH

    Pošlu přes serial 1
    pin se přepne na Low na 10 vteřin a rele sepne.
    Pak je na pinu HIGH 10 vteřin.
    Po 10 vteřinach zase LOW a už se to nepřekopí a rele zustava furt seple.

    
    #include "Timer.h"
    
        Timer t;
        int pin = 4;
    
        void setup()
        {
          Serial.begin(9600);
          pinMode(pin,INPUT_PULLUP);
          pinMode(pin, OUTPUT);       
        }
    
        void loop()
        {
          int val = Serial.parseInt(); 
          if(val == 1){ t.pulse(pin, 10 * 60 * 1000, LOW); }
          t.update();
        }
    
    #6133
    Le_Ze
    Účastník

    Tak vyřešene a odzkoušené přes tu knihovnu timer :).
    Přimo v if zapnu pin.
    digitalWrite(pin, HIGH);
    t.after(10 * 60 * 10000, vypnirele);
    a pak se po určité době spusti funkce, která ho vypne.
    Pokud si při volaní funkce pošlu i čislo pinu, postači mi 1 funkce pro všechny rele.

    #6145
    posjirka
    Účastník

    ještě si vyzkoušej jestli ti dovolí pracovat dál s jiným pinem.
    myslím tím, když aktivuješ 1 pin na zpoždění, můžeš aktivovat hned i druhý?
    Myslím, že minimálně budeš muset udělat druhou instanci timer aby se ti nemíchali proměnné z knihovny….
    originální řešení je uděláno jako aktivace časovače a ve smyčce loop si aktualizuje strojní čas do rozhodovacího procesu.

    #6147
    Le_Ze
    Účastník

    Ano mam 4 rele a 4 timery a jednu splečnou funkcí pro vypinaní

    #6151
    posjirka
    Účastník

    ok hlavní je spokojenost .)

    #6161
    Le_Ze
    Účastník

    Tak zbyla chvilka času a ja chtěl vzykoušet i to s millis.
    Dočet jsem se, že u funkce millis dochazí co 50 dní k přetečení.
    Da se to nějak pořešít?

    #6164
    Zbyšek Voda
    Účastník

    Funkci „nepřetíkat“ nedonutíte, ale můžete s tím v kódu počítat.
    Když najednou funkce millis nevrací něco přes čtyři miliardy (kdy přetéká),
    ale jede od nuly, musíte s tím v programu počítat a například si vynulovat nějaký čítač, nebo podobně.

    #6165
    Le_Ze
    Účastník

    A nedá se časovač programově vynulovat?

    #6166
    posjirka
    Účastník

    nemusíš to nulovat, stačí když budeš dál odpočítávát millis od old-millis. Stejně to nepustí v rámci proměnné více než je její rozsah a bude ti počítat od nuly. když dáš byte a jeho max hodnotu 255 a příčteš 1 tak máš zase 1 a né 256.

    #10899
    hogen
    Účastník

    Dobrý den,jsem začátečník v programování Arduina a mám problém.
    Váše časové spínání pinu se mi moc zamlouvá ,ale potřeboval bych aby to spínalo tří nastavené časy v programu.Tudíž třemi tlačítky ovládat jeden výstup.Zkoušel jsem modifikovat Váš program,ale bez úspěchu.Myslíte,če by jste mne moh nějak poradit.

    Děkuji za jakou koliv odpověď.
    Hog.

    #10901
    posjirka
    Účastník

    hod sem ten program co jsi napsal a mrkenem na to …

    #10903
    hogen
    Účastník

    No já jsem nic nenapsal,jen jsem se pokoušel upravit ten program z tvého příspěvku ze dne 22.2.2016 (20:53),ale bez úspěchu.Asi je to prozatím pro mně nadlidský úkol.Hog.

    #10906
    posjirka
    Účastník

    není to tak složité. Nadefinuješ si 3 sady proměnných:
    OLD_TIMEx
    CEKAMx
    MYTIMEx
    kde „x“ je číslo sady.
    Pak rozkopíruješ a poupraviš celý obsah ve smyčce LOOP()
    to je vše …
    Případně to vyřešíš pomocí funkcí
    Jestlit o nedáš, nezoufej a dej tomu čas, nikdo neví všechno hned.
    Chce to čas s zkušenosti. Já se taky pořád učím a zřejmě tomu nebude konec 🙂

    #10910
    hogen
    Účastník

    Tak jsem to zkoušel,ale moc jsem to nepochopil.Můžeš prosím na to mrknout,jestli to má alespoň trochu hlavu a patu,nebo je tu úplnej nesmysl.Díky

    // zpozdeni tlacitka
    // v1
    // by JP 2016
    // program po stisku tlačítka rozsvítí LED diodu a nechá jí 5s rozsvícenou, pak ji zhasne a opět čeká na stisk tlačítka

    const int LED = 13; // led dioda
    const int TLACITKO = 10; // tlacitko proti zemi
    const int TLACITKO1 = 11; // tlacitko proti zemi
    const int TLACITKO2 = 12; // tlacitko proti zemi

    boolean CEKAM = false; // kdyz je true tak ceka na zhasnuti.
    unsigned long OLDTIME = 0; // strojní čas posledního stitku tlačítka
    unsigned long ZPOZDENI = 5000; // čas zpoždění zahsnutí LED diody v ms.
    unsigned long MYTIME = 0; // aktuální čas -zpoždění

    unsigned long OLDTIME1= 0; // strojní čas posledního stitku tlačítka
    unsigned long ZPOZDENI1 = 10000; // čas zpoždění zahsnutí LED diody v ms.
    unsigned long MYTIME1 = 0; // aktuální čas -zpoždění

    unsigned long OLDTIME2= 0; // strojní čas posledního stitku tlačítka
    unsigned long ZPOZDENI2 = 15000; // čas zpoždění zahsnutí LED diody v ms.
    unsigned long MYTIME2 = 0; // aktuální čas -zpoždění
    void setup()
    {
    pinMode(LED, OUTPUT); // nastaveni jako vystup
    pinMode(TLACITKO, INPUT_PULLUP); // nastaveni jako vystup
    OLDTIME = millis();// zapamatuj si aktuální strojní čas
    pinMode(TLACITKO1, INPUT_PULLUP); // nastaveni jako vystup
    OLDTIME1 = millis();// zapamatuj si aktuální strojní čas
    pinMode(TLACITKO2, INPUT_PULLUP); // nastaveni jako vystup
    OLDTIME2 = millis();// zapamatuj si aktuální strojní čas
    }

    void loop()
    {
    digitalWrite(LED, CEKAM); // zapis stav na LED
    if (digitalRead(TLACITKO) == 0) { // při stisku tlačitka
    if (CEKAM == false) { // a zhasnuté LED diodě
    CEKAM = true; // změn stav
    OLDTIME = millis(); // zapamatuj aktuální strojový čas

    if (digitalRead(TLACITKO1) == 0) { // při stisku tlačitka
    if (CEKAM == false) { // a zhasnuté LED diodě
    CEKAM = true; // změn stav
    OLDTIME = millis(); // zapamatuj aktuální strojový čas

    if (digitalRead(TLACITKO2) == 0) { // při stisku tlačitka
    if (CEKAM == false) { // a zhasnuté LED diodě
    CEKAM = true; // změn stav
    OLDTIME = millis(); // zapamatuj aktuální strojový čas
    }
    }
    }}}}}

    #10912
    posjirka
    Účastník

    1. máš tam chybu, že jsou všechny podmínky vnořené do sebe a vlastně se na ně nikdy nedostane. Musíš si navyknout, že se páry složených závorek dávají do stejné úrovně aby si získla přehled co je co
    když uděláš např.:

    loop(){
    {{
    }
    }
    

    tak nezjistíš, které z nich tvoří pár. udělej to takto:

    loop(){
    {
      {
      }
    }
    

    a hned vidíš, co je s čím.
    2. používej tady párvoou značku CODE pro vkládání kodu, jinak se ti rozhodí jak stylizace, tak je tu problém s některými znaky (přepisují se ne jiné a pak je kod nečitelný).
    3. neměl jsi v kodu vyhodnocení tohot času, jen podmínky
    4. nesprávně jsem si přečetl tvůj požadavek. Takto to nepůjde. musíš si říct co to má dělat ve chvíli když je navolen nějáký čas, evětlo svítí a ty zmáčkenš předvolbu jiného času. Má přestat, prodloužit čas o převolbu, nebo nereagovat?
    Je to důležite k rozhodnutí stavby programu ..

    #10917
    hogen
    Účastník

    Uplně z toho nejsem chytrej hlavně bod 3.
    Můj požadavek je ,aby po stisknutí některého tlačítka času např 5,10,nebo15sec seplo výstup na zadaný čas a pří opětovném sepnutí nějakého tlačítka to nereagovalo,nebo v lepším případě ukončilo odpočítávání a vypnulo výstup(rozepne relé).
    Ještě kdyby to umnělo po skončení odpočtu zvukový signál ,tak by to bylu super,ale to již není podstatné.Díky za tvůj čas. Hog

    #10921
    posjirka
    Účastník

    rozmysli si, jestli má v pruběhu časování po stisku tlačítka skončit, nebo ignorovat.
    Každé má jiné řešení …

    #10922
    hogen
    Účastník

    Po stisku tlačítka skončit.

    #10937
    BlindP
    Účastník

    Napsal jsem jednu třídu, sice určenou pro časování čerpadel, ale pořád je to jen zpožděné vypnutí – pak by to mohlo být

    
    Pump p(vystupni_pin);
    
    if(!digitalRead(pin_tlacitka)) {
       p.Start(20);
    }
    zbyva = p.State();
    
    atd..

    BP

    #10945
    posjirka
    Účastník

    měl jsem trochu honku, ale viděl bych to takto:

    // casovac s 3 predvolbou casu
    // by JP. 2017
    // v01
    
    #define LED 13 // led dioda
    #define TLACITKO1 10 // tlacitko proti zemi
    #define TLACITKO2 11 // tlacitko proti zemi
    #define TLACITKO3 12 // tlacitko proti zemi
    
    void setup()
    {
    	pinMode(LED, OUTPUT);
    	pinMode(TLACITKO1, INPUT);
    	pinMode(TLACITKO2, INPUT);
    	pinMode(TLACITKO3, INPUT);
    }
    
    void loop()
    {
    	if(digitalRead(TLACITKO1) == 0){
    		// po stistku tlacitka 1 volej funkci caosvace se zpozdenim 5s
    		casovac(TLACITKO1, 5000);
    	} 
    	if(digitalRead(TLACITKO2) == 0){
    		// po stistku talcitka 2 volej funkci caosvace se zpozdenim 10s
    		casovac(TLACITKO2, 10000);
    	} 
    	if(digitalRead(TLACITKO3) == 0){
    		// po stistku tlacitka 3 volej funkci caosvace se zpozdenim 15s
    		casovac(TLACITKO3, 15000);
    	} 	
    }
    
    void casovac(int TLACITKO, unsigned long ZPOZDENI)
    {
    	// rozsvit LED a zapis si cas startu 
    	unsigned long OLDTIME = millis();
    	digitalWrite(LED, HIGH);
    	// cekej dokud neni uvolnene tlacitko
    	while(digitalRead(TLACITKO) == 0)
    	{	
    		delay(100); // odstraneni zakmitu tlacitka
    	}
    	// cekej dokud nepretece nastaveny cas
    	while(millis() < (OLDTIME + ZPOZDENI))
    	{
    		// pokud stisknu nejake tlacitko ukonci casovac tim ze vynulujes nastavenou dobu zpozdeni
    		if(digitalRead(TLACITKO1) == 0 || digitalRead(TLACITKO2) == 0 || digitalRead(TLACITKO3) == 0)
    		{
    			ZPOZDENI = 0;
    		}
    	}
    	// zhasni LED
    	digitalWrite(LED, LOW);
    	delay(1000); // zabraneni nechtenemu startu noveho cesovani
    }
    #10946
    posjirka
    Účastník

    je to trochu primitivní řešení, ale aspoň se na něm můžeš něco naučit. Popisy jsou snad jasné a je tam odstraněno hned několik zvláštoností ze základů programování (zákmity tlačítek, nechtěné nastarotvání nového časování atd. spíš jde o věci, které by tě možná v začátku nenapadly, ale pak by ti způsobovali problémy …snad jsem pomohl

    #10947
    hogen
    Účastník

    Jirko děkuji moc,pravě jsem to zkusil nakrmit,ale na vystupu ,to je loterie,myslim,že to je absencí pullUp v programu,mrknu na to,pokusím se to dopsát,pokud to nedám tak to dám hardwarově.(jen doufám ,že neplácám hlouposti).Dnes už to nedám,byl jsem na maltě a nějak mně to zmohlo :-).Dobrou

    #10954
    posjirka
    Účastník

    máš pravdu. v poslední době používám simulator arduina místo HW řešení a nedocvaklo mě, že používá pro vstupy tlačítek přímo log.1/0, nikoliv spínače na zem.
    Patří tam do setup() při nastavení modu pinu použít „INPUT_PULLUP“ místo „INPUT“ u všech tlačítek.

    // casovac s 3 predvolbou casu
    // by JP. 2017
    // v02 - doplnení pull up interních odporu
    
    #define LED 13 // led dioda
    #define TLACITKO1 10 // tlacitko proti zemi
    #define TLACITKO2 11 // tlacitko proti zemi
    #define TLACITKO3 12 // tlacitko proti zemi
    
    void setup()
    {
    	pinMode(LED, OUTPUT);
    	pinMode(TLACITKO1, INPUT_PULLUP);// v02
    	pinMode(TLACITKO2, INPUT_PULLUP);// v02
    	pinMode(TLACITKO3, INPUT_PULLUP);// v02
    }
    
    void loop()
    {
    	if(digitalRead(TLACITKO1) == 0){
    		// po stistku tlacitka 1 volej funkci caosvace se zpozdenim 5s
    		casovac(TLACITKO1, 5000);
    	} 
    	if(digitalRead(TLACITKO2) == 0){
    		// po stistku talcitka 2 volej funkci caosvace se zpozdenim 10s
    		casovac(TLACITKO2, 10000);
    	} 
    	if(digitalRead(TLACITKO3) == 0){
    		// po stistku tlacitka 3 volej funkci caosvace se zpozdenim 15s
    		casovac(TLACITKO3, 15000);
    	} 	
    }
    
    void casovac(int TLACITKO, unsigned long ZPOZDENI)
    {
    	// rozsvit LED a zapis si cas startu 
    	unsigned long OLDTIME = millis();
    	digitalWrite(LED, HIGH);
    	// cekej dokud neni uvolnene tlacitko
    	while(digitalRead(TLACITKO) == 0)
    	{	
    		delay(100); // odstraneni zakmitu tlacitka
    	}
    	// cekej dokud nepretece nastaveny cas
    	while(millis() < (OLDTIME + ZPOZDENI))
    	{
    		// pokud stisknu nejake tlacitko ukonci casovac tim ze vynulujes nastavenou dobu zpozdeni
    		if(digitalRead(TLACITKO1) == 0 || digitalRead(TLACITKO2) == 0 || digitalRead(TLACITKO3) == 0)
    		{
    			ZPOZDENI = 0;
    		}
    	}
    	// zhasni LED
    	digitalWrite(LED, LOW);
    	delay(1000); // zabraneni nechtenemu startu noveho cesovani
    }

    snad tě to někam posunulo a budeš mít z čeho čerpat.

Aktuálně je na stránce zobrazeno 30 příspěvků - 1. až 30. (celkem z 32)
  • Pro reakci na toto téma se musíte přihlásit.