Stisk více tlačítek

Ludek
Příspěvky: 289
Registrován: 02 pro 2019, 08:14
Reputation: 0
Bydliště: České Budějovice

Stisk více tlačítek

Příspěvek od Ludek » 16 dub 2021, 11:47

Zdravím,
mám problém, asi jednoduchý, ale nedaří se mi.
Potřebuji řešit stisk dvou tlačítek takto:
Stisk A - neděje se nic, provede akci 1 až po jeho uvolnění
Stisk B - neděje se nic, provede akci 2 až po jeho uvolnění
ale
Stisknu A a držím. Stisknu ještě B a provede se akce 3 IHNED - a mohu obě tlačítka pustit
Stisknu B a držím. Stisknu ještě A a provede se akce 4 IHNED - a mohu obě tlačítka pustit
poradíte? díky

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

Re: Stisk více tlačítek

Příspěvek od ondraN » 16 dub 2021, 15:26

Tak to zase tak triviální problém není. Předpokládám, že se vyžaduje to, aby vyhodnocení bylo neblokující, takže je zapotřebí stavový automat. Teď nemám čas, ale o víkendu se na to zkusím podívat, pokud nebude někdo rychlejší :mrgreen:

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

Re: Stisk více tlačítek

Příspěvek od ondraN » 16 dub 2021, 20:12

Kód: Vybrat vše

//porty pro pripojeni tlacitek, tlacitko spina pin na zem
#define BUTT_A  9     
#define BUTT_B  10

enum whatcall_t{CALL_NONE, CALL_A, CALL_B, CALL_AB, CALL_BA};

whatcall_t  callFunc;

whatcall_t  CheckButtons(uint8_t portButtA, uint8_t portButtB, uint32_t samplePeriod);  //prototyp funkce 


void setup() {
  // put your setup code here, to run once:
  pinMode(BUTT_A, INPUT_PULLUP);
  pinMode(BUTT_B, INPUT_PULLUP);
}

void loop() {
  // neco tady muzu delat
  callFunc=CheckButtons(BUTT_A, BUTT_B, 50);
  // neco tady muzu delat
  switch(callFunc){
    case CALL_NONE:
    break;
    case CALL_A:
      //provadim akci pro stisk a pusteni tlac. A
    break;
    case CALL_B:
      //provadim akci pro stisk a pusteni tlac. B
    break;
    case CALL_AB:
      //provadim akci pro stisk tlac. A a nasledny stisk B
    break;
    case CALL_BA:
      //provadim akci pro stisk tlac. B a nasledny stisk A
    break;
  }
}

whatcall_t  CheckButtons(uint8_t portButtA, uint8_t portButtB, uint32_t samplePeriod){ 
                        //pin tlacitka A, pin tlacitka B, po kolika ms se bude samplovat a vyhodnocovat stav
  static  uint8_t     stage=0;
  static  uint32_t    nextTime=0;
          bool        buttA,buttB;
          whatcall_t  outVal=CALL_NONE;
  if(millis()<nextTime){
    return CALL_NONE;
  }
  nextTime=millis()+samplePeriod;
  if(digitalRead(portButtA)==LOW){
    buttA=true;
  }else{
    buttA=false;
  }
  if(digitalRead(portButtB)==LOW){
    buttB=true;
  }else{
    buttB=false;
  }
  switch(stage){
    case 0:
      if(buttA && (!buttB)){  //pouze A stisknuto
        stage=1;
      }else{
        if(buttB && (!buttA)){  //pouze B stisknuto
          stage=3;
        }      
      }
    break;   
    case 1:
      if((!buttA)&&(!buttB)){  //uvolneno A i B
        stage=0;
        outVal=CALL_A;
      }else{
        if(buttA && buttB){ //pridan stisk B
          stage=2;
          outVal=CALL_AB;
        }
      }
    break;   
    case 2:
      if((!buttA)&&(!buttB)){  //uvolneno A i B, prechod do zakladniho stavu
        stage=0;
      }
    break;    
    case 3:
      if((!buttA)&&(!buttB)){  //uvolneno A i B
        stage=0;
        outVal=CALL_B;
      }else{
        if(buttA && buttB){ //pridan stisk A
          stage=2;
          outVal=CALL_BA;
        }
      }
    break;    
   }
  return outVal;
}
upozorňuji že to není otestované, ale mělo by to fungovat

Ludek
Příspěvky: 289
Registrován: 02 pro 2019, 08:14
Reputation: 0
Bydliště: České Budějovice

Re: Stisk více tlačítek

Příspěvek od Ludek » 17 dub 2021, 15:45

Ondro Ty jsi genius....
šlape to. Je to trochu delší, snad to nacpu do ATtiny...
Potřebuji připojit Rx přijímač, má jen dvě tlačitka a já potřebuji 4 funkce :-)
Díky, že jsi tomu věnoval takový čas... klobouk dolů

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

Re: Stisk více tlačítek

Příspěvek od ondraN » 17 dub 2021, 21:16

To jsem rád, že to šlape. Ušetřit paměť se dá ještě tím, že se nebudou předávat hodnoty portů, ale dají se do těla funkce natvrdo ty v define a z hlavičky se odstraní proměnné. Taky by šlo boolovské proměnné strčit do jednoho byte, ale tím to dost ztratí přehlednost. Pokud víš, že skenovací interval bude jen do 255ms, tak místo uint32_t může být jen uint8_t a další tři byte jsou volné. Pokud bude nejhůře, nemusíš to vůbec dělat jako funkci, ale může se to dát rovnou do těla loopu, ušetří se i něco na režii volání funkce, ale zase za cenu horší přehlednosti kódu.

RomanB
Příspěvky: 90
Registrován: 04 zář 2017, 14:28
Reputation: 0
Bydliště: Havířov

Re: Stisk více tlačítek

Příspěvek od RomanB » 18 dub 2021, 15:02

Nevím, jestli jsem požadavek dobře pochopil, ale je taky možné použít jen jeden PIN a funkci analogread podle https://www.codrey.com/arduino-projects ... ino-input/

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: Stisk více tlačítek

Příspěvek od KamilV » 18 dub 2021, 21:49

RomanB píše:
18 dub 2021, 15:02
Nevím, jestli jsem požadavek dobře pochopil, ale je taky možné použít jen jeden PIN a funkci analogread podle https://www.codrey.com/arduino-projects ... ino-input/
To sice lze, ale pokud to není nutné, bývá lépe se tomu vyhnout. Toto jsou místa, která při rušení přestanou fungovat jako první...

Ludek
Příspěvky: 289
Registrován: 02 pro 2019, 08:14
Reputation: 0
Bydliště: České Budějovice

Re: Stisk více tlačítek

Příspěvek od Ludek » 19 dub 2021, 20:47

Máte pravdu, nepochopili jste.
Nešla by funkce AB a BA nebo BC a CB atd atd... už vyřešeno...

ALE mám ještě jeden problém. Zase jiné tlačítko, jiná aplikace.
Potřebuji :
krátký stisk - do 200 ms, aby to udělalo nějakou funkci - třeba LED1
a dlouhý stisk nad 200 ms, aby to udělalo druhou funkci - třeba LED2
ALE
LED2 se musí rozsvítit, i když budu držet tlačítko dlouho, třeba 3 sec...
:-(

Ludek
Příspěvky: 289
Registrován: 02 pro 2019, 08:14
Reputation: 0
Bydliště: České Budějovice

Re: Stisk více tlačítek

Příspěvek od Ludek » 19 dub 2021, 21:50

Už jsem to našel !!!!!!!!!!!!!!!!
Google a toto Forum je super :-)

https://arduinogetstarted.com/tutorials ... hort-press

Vencir86
Příspěvky: 3
Registrován: 06 kvě 2021, 22:42
Reputation: 0

Stisk více tlačítek

Příspěvek od Vencir86 » 06 kvě 2021, 22:56

Zdravím, měl bych dotaz ohledně zapojení s tlacitky. Potřeboval bych něco podobného, ale místo tlačítka by bylo magnetické čidlo. Potrebuju hlídat otáčení 6 kol na mašině soucasne a v případě zablokování kteréhokoliv kola, aby se na displeji 16x2 zobrazilo XX pod konkrétním cislem kola a spustilo se pipani. Ale zase zároveň když se mašina zvedne a dojde k zastavení všech kol, tak aby to nepipalo. Lze ten program nějak jednoduše poskladat, aby to bylo přehledný pro pokročilého začátečníka? Uz si s tím lamu hlavu tejden a pořád mi to nejde poskladat. Díky moc za radu.

Odpovědět

Kdo je online

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