Arduino - tlačidlá

Sekcia určená pre Arduino nadšencov

Moderátor: Moderátori

Používateľov profilový obrázok
MrWifiHifi
Pokročilý člen
Pokročilý člen
Príspevky: 600
Dátum registrácie: 22 Aug 2017, 10:06

Arduino - tlačidlá

Príspevok od používateľa MrWifiHifi » 29 Jún 2022, 19:38

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.
0

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2573
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: Arduino - tlačidlá

Príspevok od používateľa maskrtnik01 » 29 Jún 2022, 20:41

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.
0

Atlan
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1148
Dátum registrácie: 01 Feb 2008, 00:00
Bydlisko: Kosice okolie

Re: Arduino - tlačidlá

Príspevok od používateľa Atlan » 29 Jún 2022, 20:43

Ak to mss na ATmeli, ta milis nepouzivaj, ale su vytvor vlastnu premenu v preruseni....
0

Používateľov profilový obrázok
MrWifiHifi
Pokročilý člen
Pokročilý člen
Príspevky: 600
Dátum registrácie: 22 Aug 2017, 10:06

Re: Arduino - tlačidlá

Príspevok od používateľa MrWifiHifi » 29 Jún 2022, 21:25

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ť...?
0

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2573
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: Arduino - tlačidlá

Príspevok od používateľa maskrtnik01 » 30 Jún 2022, 08:21

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ť.
0

Používateľov profilový obrázok
budvar10
Pokročilý člen
Pokročilý člen
Príspevky: 989
Dátum registrácie: 15 Dec 2014, 10:55
Bydlisko: Košice

Re: Arduino - tlačidlá

Príspevok od používateľa budvar10 » 30 Jún 2022, 08:46

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.
0

Používateľov profilový obrázok
balu
Pokročilý člen
Pokročilý člen
Príspevky: 540
Dátum registrácie: 21 Feb 2022, 12:06

Re: Arduino - tlačidlá

Príspevok od používateľa balu » 30 Jún 2022, 23:27

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.

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_ */
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.
0

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok