Zdravím
Chcel by som sa poradiť. Je možné detekovať pri 4 tlačidlách krátke a dlhé stalčenie? Ak, tak ako by to bolo možné spraviť čo najjednoduchšie? Našiel som zatiaľ len pre jedno tlačidlo, snažil som sa to prerobiť, žiaľ neúspešne.
Arduino - tlačidlá
Moderátor: Moderátori
- MrWifiHifi
- Pokročilý člen
- Príspevky: 600
- Dátum registrácie: 22 Aug 2017, 10:06
-
- Ultimate člen
- Príspevky: 2574
- Dátum registrácie: 20 Júl 2010, 00:00
- Bydlisko: okolie KE
- Vek: 27
Re: Arduino - tlačidlá
Najprv používate debouncing? Ak nie, môže to robiť sprostosti.
Ak áno, verím tomu, že stačí jednoducho zaznamenať čas detekcie stlačenia a pustenia. Ich rozdiel je hľadaná dĺžka stlačenia.
Vyhýbajte sa delayom, všade kde sa dá radšej millis, aj za cenu vyššej zložitosti. Potom nevidím problém s rozšírením vyššie uvedeného na viac tlačidiel.
Ak áno, verím tomu, že stačí jednoducho zaznamenať čas detekcie stlačenia a pustenia. Ich rozdiel je hľadaná dĺžka stlačenia.
Vyhýbajte sa delayom, všade kde sa dá radšej millis, aj za cenu vyššej zložitosti. Potom nevidím problém s rozšírením vyššie uvedeného na viac tlačidiel.
0
Re: Arduino - tlačidlá
Ak to mss na ATmeli, ta milis nepouzivaj, ale su vytvor vlastnu premenu v preruseni....
0
- MrWifiHifi
- Pokročilý člen
- Príspevky: 600
- Dátum registrácie: 22 Aug 2017, 10:06
Re: Arduino - tlačidlá
Je tam debounce, programujem no Arduino Uno. Používam millis(), delay sa snažím obmedziť na minimum.
Zatiaľ sa mi podarilo len detekovať stlačenie jedného zo 4 tlačidiel, no to dlhé a krátke stlačenie sa mi zatiaľ nepodarilo implementovať.
Funkciu mám postavenú tak, že kontroluje 4 tlačidlá, ak nie je žiadne stlačené, vyhodí -1. Naopak, ak je niektoré tlačidlo stlačené, tak vyhodí číslo tlačidla, teda 1 až 4.
Rozmýšlaľ som, že by som postavil dalšiu funkciu, kde na jej začiatku by sa zistoval stav tlačidiel, ak by sa niektoré stlačilo, spustila by sa slučka, ktorá by si stále na konci zapamätala aktuálnu hodnotu millis. Slučka by sa ukončila po pustení tlačidla, zapamätali by sa millis pri stlačení tlačidla odpočítali by sa od zapamätaných millis pri pustení tlačidla, následne by bola podmieka, ktorá by určovala či šlo o krátke alebo dlhé stlačenie.
Moholo by to takto nejako fungovať...?
Zatiaľ sa mi podarilo len detekovať stlačenie jedného zo 4 tlačidiel, no to dlhé a krátke stlačenie sa mi zatiaľ nepodarilo implementovať.
Funkciu mám postavenú tak, že kontroluje 4 tlačidlá, ak nie je žiadne stlačené, vyhodí -1. Naopak, ak je niektoré tlačidlo stlačené, tak vyhodí číslo tlačidla, teda 1 až 4.
Rozmýšlaľ som, že by som postavil dalšiu funkciu, kde na jej začiatku by sa zistoval stav tlačidiel, ak by sa niektoré stlačilo, spustila by sa slučka, ktorá by si stále na konci zapamätala aktuálnu hodnotu millis. Slučka by sa ukončila po pustení tlačidla, zapamätali by sa millis pri stlačení tlačidla odpočítali by sa od zapamätaných millis pri pustení tlačidla, následne by bola podmieka, ktorá by určovala či šlo o krátke alebo dlhé stlačenie.
Moholo by to takto nejako fungovať...?
0
-
- Ultimate člen
- Príspevky: 2574
- Dátum registrácie: 20 Júl 2010, 00:00
- Bydlisko: okolie KE
- Vek: 27
Re: Arduino - tlačidlá
Znovu sa chystáte zablokovať celý program len kvôli detekcii stlačenia. Toto je cesta do pekiel, čoskoro sa budete čudovať, prečo program reaguje na vstup len sem-tam.
Napíšte to ako som spomínal, zapíšte si do premennej čas pri stlačení, pri pustení odrátate od millis a máte vyhraté.
Ako robíte debouncing? Ak znovu cez nejakú slučku ktorá blokuje program, treba prerobiť.
Napíšte to ako som spomínal, zapíšte si do premennej čas pri stlačení, pri pustení odrátate od millis a máte vyhraté.
Ako robíte debouncing? Ak znovu cez nejakú slučku ktorá blokuje program, treba prerobiť.
0
Re: Arduino - tlačidlá
Lepšie ako siahodlho opisovať, je poslať kód programu.
Pre krátke stlačenie je potrebné testovať, či sa vráti tlačidlo do pôvodnej hodnoty do časového limitu. Ostatné je dlhé stlačenie. Stlačenie píšeš, že vieš ako.
Pre krátke stlačenie je potrebné testovať, či sa vráti tlačidlo do pôvodnej hodnoty do časového limitu. Ostatné je dlhé stlačenie. Stlačenie píšeš, že vieš ako.
0
Re: Arduino - tlačidlá
Arduino nepoužívám, takže budou potřeba nějaké úpravy. Tohle je vytažené z mého programu psaném v Atmel Studiu.
V souboru "MCU_Config.h" je definovaný F_CPU, v souboru "Common.h" jsou definované názvy tlačítek na vstupech procesoru.
Program je psaný tak, že změnou #define NUM_OF_KEYS (4) a počtu (a názvů) case ve switch(_ActualKeyProcessed) upravíš program pro libovolný počet tlačítek - teda co stačí paměť a rychlost procesoru.
Položka KeyUpdated u každého tlačítka znamená, že jsou v proměnné nové stavy. Po reakci programu na jednotlivé "události" je třeba tento příznak vynulovat.
Téma presunutá do správnej sekcie,presunul:5.7.2022 mirosne.
Kód: Vybrať všetko
/*
* KeyProcessTimer.cpp
*/
#include "MCU_Config.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "KeyProcessTimer.h"
#include "Common.h"
volatile KeyStateUnion Keys[_MAX_KEY_INDEX];
unsigned int _ActualKeyProcessed = 0;
typedef struct _KeyTimersStruct
{
unsigned char Debounce;
unsigned char LongPressTimer;
unsigned char AutoRepeatTimer;
unsigned char LastState:1;
} _KeyTimersStruct;
#define LongPressTimerPreset 50
#define AutoRepeatTimerPreset 25
_KeyTimersStruct _KeysTimers[_MAX_KEY_INDEX];
void KeyProcessTimerInit(void)
{
OCR1A = ((F_CPU/(80*NUM_OF_KEYS)/8)-1);
TCCR1A = 0;
TCCR1B = (1<<WGM12)|PRE8;
TIMSK |= (1<<OCIE1A);
}
ISR(TIMER1_COMPA_vect)
{
_KeysTimers[_ActualKeyProcessed].Debounce <<= 1;
bool _ActualKeyInput;
_ActualKeyInput = false;
switch(_ActualKeyProcessed)
{
case 0: if (!KEY_CONNECT_INPUT) _ActualKeyInput = true;
break;
case 1: if (!KEY_DISCONNECT_INPUT) _ActualKeyInput = true;
break;
case 2: if (!KEY_UP_INPUT) _ActualKeyInput = true;
break;
case 3: if (!KEY_DOWN_INPUT) _ActualKeyInput = true;
break;
default:
break;
}
if (_ActualKeyInput)
{
_KeysTimers[_ActualKeyProcessed].Debounce++;
}
if (_KeysTimers[_ActualKeyProcessed].Debounce == 0xFF)
{
Keys[_ActualKeyProcessed].StateBits.ActualState = 1;
if (_KeysTimers[_ActualKeyProcessed].LastState == 0)
{
Keys[_ActualKeyProcessed].StateBits.RisingEdge = 1;
}
else
{
Keys[_ActualKeyProcessed].StateBits.RisingEdge = 0;
}
if (_KeysTimers[_ActualKeyProcessed].LongPressTimer == LongPressTimerPreset)
{
if (!_KeysTimers[_ActualKeyProcessed].AutoRepeatTimer)
{
_KeysTimers[_ActualKeyProcessed].AutoRepeatTimer = AutoRepeatTimerPreset;
Keys[_ActualKeyProcessed].StateBits.LongPress = 1;
Keys[_ActualKeyProcessed].StateBits.AutoRepeat= 1;
}
else
{
_KeysTimers[_ActualKeyProcessed].AutoRepeatTimer--;
Keys[_ActualKeyProcessed].StateBits.AutoRepeat = 0;
}
}
else
{
_KeysTimers[_ActualKeyProcessed].LongPressTimer++;
}
}
else
{
Keys[_ActualKeyProcessed].CompleteByte = 0;
if (_KeysTimers[_ActualKeyProcessed].LastState == 1)
{
Keys[_ActualKeyProcessed].StateBits.FallingEdge = 1;
}
else
{
Keys[_ActualKeyProcessed].StateBits.FallingEdge = 0;
}
_KeysTimers[_ActualKeyProcessed].AutoRepeatTimer = 0;
_KeysTimers[_ActualKeyProcessed].LongPressTimer = 0;
}
_KeysTimers[_ActualKeyProcessed].LastState = Keys[_ActualKeyProcessed].StateBits.ActualState;
Keys[_ActualKeyProcessed].StateBits.KeyUpdated = 1;
_ActualKeyProcessed++;
if (_ActualKeyProcessed>_MAX_KEY_INDEX) _ActualKeyProcessed = 0;
}
V souboru "MCU_Config.h" je definovaný F_CPU, v souboru "Common.h" jsou definované názvy tlačítek na vstupech procesoru.
Kód: Vybrať všetko
/*
* KeyProcessTimer.h
*/
#ifndef KeyProcessTimer_H_
#define KeyProcessTimer_H_
// KeyProcessTimer configuration
#define NUM_OF_KEYS (4)
#define _MAX_KEY_INDEX (NUM_OF_KEYS - 1)
typedef struct KeyStateStruct
{
unsigned char ActualState:1;
unsigned char RisingEdge:1;
unsigned char FallingEdge:1;
unsigned char LongPress:1;
unsigned char AutoRepeat:1;
unsigned char KeyUpdated:1;
} KeyStateStruct;
typedef union KeyStateUnion
{
unsigned char CompleteByte;
KeyStateStruct StateBits;
} KeyStateUnion;
extern volatile KeyStateUnion Keys[_MAX_KEY_INDEX];
void KeyProcessTimerInit(void);
#endif /* KeyProcessTimer_H_ */
Položka KeyUpdated u každého tlačítka znamená, že jsou v proměnné nové stavy. Po reakci programu na jednotlivé "události" je třeba tento příznak vynulovat.
Téma presunutá do správnej sekcie,presunul:5.7.2022 mirosne.
0
-
- Podobné témy
- Odpovedí
- Zobrazení
- Posledný príspevok
-
- 4 Odpovedí
- 1068 Zobrazení
-
Posledný príspevok od používateľa lucky62
-
- 0 Odpovedí
- 1282 Zobrazení
-
Posledný príspevok od používateľa jakubv
-
- 20 Odpovedí
- 1128 Zobrazení
-
Posledný príspevok od používateľa jankrizan
-
- 11 Odpovedí
- 2000 Zobrazení
-
Posledný príspevok od používateľa mirosne
-
- 10 Odpovedí
- 699 Zobrazení
-
Posledný príspevok od používateľa budvar10