Ovládání arduino jedním tlačítkem.

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Neznalec365
Příspěvky: 3
Registrován: 14 srp 2020, 10:47
Reputation: 0

Ovládání arduino jedním tlačítkem.

Příspěvek od Neznalec365 » 14 srp 2020, 10:49

Zdravím všechny co této problematice rozumějí víc než já, což je tady každý.

Jako naprostý začátečník bych potřeboval malou radu. Řekněme, že mám třeba pět úkonů, jedno tlačítko a chci aby je arduino postupně vykonávalo po stisku tlačítka. Zkrátka stisknu tlačítko - provede se úkon číslo 1, stisknu tlačítko podruhé - provede se úkon číslo 2 a tak dále, přičemž po úkonu číslo pět se opět vracím na začátek.
Asi je to pro většinu z vás úplně triviální, ale já jsem programováním nepolíbený a zatím těžce tápu :(
Díky


martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od martinius96 » 14 srp 2020, 11:39

Je to úplne jednoduché.
Stačí overiť, či je tlačidlo stlačené aspoň 50 milisekúnd (debounce), aby ti to počítadlo nepripočítalo pri stisku 10 krát.
Následne pri pustení tlačidla pripočítaš +1 k počítadlu, ošetríš pretečenie cez hodnotu 5.

V jednoduchom vetvení cez switch() si spustíš úkon, ktorý konkrétne sedí.
Ak tam však pustíš úkon typu: digitalWrite(led, HIGH); delay(10000);, tak ti tých 10 sekúnd systém na zmenu tlačidla vôbec nezareaguje, pretože si beh tej slučky zablokuješ tým delayom.

Program je pre zapojenie tlačidla INPUT_PULLUP, teda stlačenie znamená privedenie GND na pin D6. Využíva sa interný pullup rezistor Arduina pre vstup.

Kód: Vybrat vše

//Ovládanie jedným tlačidlom
//Zapojenie INPUT_PULLUP

const int buttonPin1 = 6;
int pocitadlo = 0;
int buttonState1 = HIGH;
int lastButtonState1 = HIGH;
unsigned long lastDebounceTime1 = 0;
unsigned long debounceInterval = 50;

void setup() {
  pinMode(buttonPin1, INPUT_PULLUP);

}

void loop() {
  int reading1 = digitalRead(buttonPin1);
  if (reading1 != lastButtonState1) {
    lastDebounceTime1 = millis();
  }
  if ((millis() - lastDebounceTime1) > debounceInterval) {
    if (reading1 != buttonState1) {
      buttonState1 = reading1;
      if (buttonState1 == HIGH) {
        pocitadlo++;
        if (pocitadlo > 5) {
          pocitadlo = 1;
        }

        //AK CHCEME UKON VYKONAVAT CYKLICKY, VLOZIME CELY SWITCH DO LOOP MIMO IF POMIENKY
        switch (pocitadlo) {
          case 1:
            // ukon1();
            break;
          case 2:
            // ukon2();
            break;
          case 3:
            // ukon3();
            break;
          case 4:
            // ukon4();
            break;
          case 5:
            // ukon5();
            break;
          default:
            // toto sa nevykona
            break;
        }
      }
    }
  }
  lastButtonState1 = reading1;
}

Neznalec365
Příspěvky: 3
Registrován: 14 srp 2020, 10:47
Reputation: 0

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od Neznalec365 » 19 srp 2020, 09:53

Díky za detailní odpověď a nápovědu, na tom už dokážu vyřešit svůj problém.

Neznalec365
Příspěvky: 3
Registrován: 14 srp 2020, 10:47
Reputation: 0

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od Neznalec365 » 11 říj 2020, 08:09

Měl bych ještě jeden nový problém k řešení. Rád bych s pomocí arduina opravil částečně nefunkční řízení vysoušecí skříně.
Potřebuji podle senzoru vlhkosti spínat ventilátor, to je první část úkolu, má původní představa je naprosto primitivní podmínka pokud je vlhkost víc než 5 (například), tak spusť ventilátor, pokud méně, tak nedělej nic. Tu hodnotu nechám v kódu natvrdo, žádné nastavování není třeba. Potom jsem si ovšem řekl, že v momentě kdy budu kolem té nastavené hodnoty, tak mi to začne pořád dokola zapínat a vypínat, čili tam budu muset nahrnout nějaké čekání/zpoždění nevím jestli natvrdo delay, či jestli bude vhodnější použít millis. Navíc potřebuji sepnout ventilátor i v případě že běží funkce regenerace (tu zdetekuji z původní řídící jednotky), na to mi přijde (z mých omezených znalostí) nejlepší využít funkci přerušení, kdy bych nechal ventilátor běžet dokud regenerace nekončí. Asi to popisují poněkud chaoticky :)

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od kiRRow » 11 říj 2020, 09:32

Řešením jet řeba hystereze ... uvedu příklad na teplotě. Chci udržovat teplotu 20°C a hystereze bude 1°C. Topení se sepne v momentě, kdy teplota spadne pod 20 - 1 °C a bude topit do doby než teplota přesáhne 20 + 1 °C. Sice nikdy nebudu mít 20°C, ale tak nějak mezi 19 - 21°C.

bokuba
Příspěvky: 5
Registrován: 03 kvě 2021, 16:32
Reputation: 0

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od bokuba » 03 kvě 2021, 16:41

martinius96 píše:
14 srp 2020, 11:39
Je to úplne jednoduché.
Stačí overiť, či je tlačidlo stlačené aspoň 50 milisekúnd (debounce), aby ti to počítadlo nepripočítalo pri stisku 10 krát.
Následne pri pustení tlačidla pripočítaš +1 k počítadlu, ošetríš pretečenie cez hodnotu 5.

V jednoduchom vetvení cez switch() si spustíš úkon, ktorý konkrétne sedí.
Ak tam však pustíš úkon typu: digitalWrite(led, HIGH); delay(10000);, tak ti tých 10 sekúnd systém na zmenu tlačidla vôbec nezareaguje, pretože si beh tej slučky zablokuješ tým delayom.

Program je pre zapojenie tlačidla INPUT_PULLUP, teda stlačenie znamená privedenie GND na pin D6. Využíva sa interný pullup rezistor Arduina pre vstup.

Kód: Vybrat vše

//Ovládanie jedným tlačidlom
//Zapojenie INPUT_PULLUP

const int buttonPin1 = 6;
int pocitadlo = 0;
int buttonState1 = HIGH;
int lastButtonState1 = HIGH;
unsigned long lastDebounceTime1 = 0;
unsigned long debounceInterval = 50;

void setup() {
  pinMode(buttonPin1, INPUT_PULLUP);

}

void loop() {
  int reading1 = digitalRead(buttonPin1);
  if (reading1 != lastButtonState1) {
    lastDebounceTime1 = millis();
  }
  if ((millis() - lastDebounceTime1) > debounceInterval) {
    if (reading1 != buttonState1) {
      buttonState1 = reading1;
      if (buttonState1 == HIGH) {
        pocitadlo++;
        if (pocitadlo > 5) {
          pocitadlo = 1;
        }

        //AK CHCEME UKON VYKONAVAT CYKLICKY, VLOZIME CELY SWITCH DO LOOP MIMO IF POMIENKY
        switch (pocitadlo) {
          case 1:
            // ukon1();
            break;
          case 2:
            // ukon2();
            break;
          case 3:
            // ukon3();
            break;
          case 4:
            // ukon4();
            break;
          case 5:
            // ukon5();
            break;
          default:
            // toto sa nevykona
            break;
        }
      }
    }
  }
  lastButtonState1 = reading1;
}
Zaujal mě tenhle příspěvek, rád bych to využil ve své záležitosti, jen bych potřeboval drobnou úpravu.

A to "namontovat" do toho ještě jedno přepínání, kdy bych potřeboval na dlouhý stisk tlačítka (cca 5 sekund ) posílat či spíše střídat dvě akce - zkrátka po dlouhém stisku proveď A, po dalším proveď B, pak zase A - nejspíš je to jednoduché, ale já na to asi nemám tu programátorskou hlavu :( . Nedokáže mi někdo trochu poradit?
Víceméně se dokážu obejít bez debounce funkce (kondenzátor 200 nf přes tlačítko mi pomohl), ale stejně se nějak ztrácím v tom zbytku...

Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od gilhad » 03 kvě 2021, 19:03

Debouncovani je zaklad :)
Spravne by se melo debouncovat zvlast stisknuti a zvlast pusteni, ale casto se to udela jednou pri zmene.
pro dlouha a kratka stisknuti si pridas pomocnou promennou DLOUHE, kterou pri stisknuti nastavis na false a pak tam das treti debouncnuti pri stisku (treba na 5 sec), ktere ji zmeni na true

Kdyz dojde k pusteni tlacitka, tak se podle te promenne DLOUHE rozhodnes, zda jit jednou vetvi pro kratke stisky, nebo druhou pro dlouhe.
Jinak se to stejne.

Pripadne ji muzes udelat celociselnou, dat tam tech debouncnuti vic a rozeskakovat se podle jeji hodnoty

----
Jinak ten kondenzator - no, ono to muze vetsinou tak nejak jako vlastne skoro fungovat, pro blikani LEDkou asi dobry, ale principialne spatny - protoze nespolehlivost jedne soucastky (zakmitavajiciho tlacitka) obchazis tim, ze na vstup dlouhodobe privadis nedefinovany signal (vetsi nez logicka nula, mensi nez logicka jedna) a ackoli pro takovy signal vyrobce nic nezarucuje (klidne to pri nem muze kmitat taky), tak proste tak nejak jako doufas, ze zrovna tobe se to i tak bude chovat hezky a v nejakou naprosto nedefinovanou chvili se to najednou prepne a uz to prepnute zustane. Pricemz potrebna velikost toho kondenzatoru zavisi na spouste veci, ktere nijak nemeris a proste tam picnes neco, kde se ti zda, ze to chodi tak nejak asi dobre - a pokud to tak nejak chodi, tak ta doba v zakazanem pasmu je pravdepodobne podstatne delsi, nez je potrebna.

Naproti tomu SW debounce lze nastavit tak, ze informaci o kontaktu mas ihned jak k nemu poprve dojde (ne az nekdy kdovi kdy), navic muzes i sledovat, co to tlacitko fakt dela a "odblokovat" ho, az se se ustali - coz je doba, ktere se s casem a opotrebenim tlacitka meni a eventualne i sledovat, jak se tato doba meni a kdy zacina to tlacitko byt mene spolehlive (skace podstatne dele, nez na zacatku) a vcas signalizovat potrebu jeho vymeny driv, nez definitivne odejde na srotiste. (OK, tim se dostavame dost jinam, nez je Arduino urcene na blikani LEDkou, ale porad zustavame na stejnem HW, jen ho pro zmenu bereme trochu vazne)

bokuba
Příspěvky: 5
Registrován: 03 kvě 2021, 16:32
Reputation: 0

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od bokuba » 03 kvě 2021, 20:46

No jo, já to chápu, to je jen snaha lempla si zjednodušit život :)
Musím se do toho víc opřít.

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od pavel1tu » 03 kvě 2021, 21:05

jako akce 1 při krátkém
a akce 2 při dlouhém stisku ?

jen jsem doprznil co už bylo načnuté
je to i otestované

Kód: Vybrat vše

//Ovládanie jedným tlačidlom
//Zapojenie INPUT_PULLUP

const int buttonPin1 = 6;
int buttonState1 = HIGH;
int lastButtonState1 = HIGH;
unsigned long lastDebounceTime = 0;
unsigned long debounceInterval1 = 50;
unsigned long debounceInterval2 = 2000;

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin1, INPUT_PULLUP);

}

void loop() {
  int reading1 = digitalRead(buttonPin1);
  
  if (reading1 != lastButtonState1 && reading1 == LOW) {
    lastDebounceTime = millis();
  }
  
  if ((millis() - lastDebounceTime) > debounceInterval1 && (millis() - lastDebounceTime) < debounceInterval2) {
    if (reading1 != buttonState1) {
      buttonState1 = reading1;
      if (buttonState1 == HIGH) {
      Serial.println("Kratky stisk");
  
      }
    }
  }
  
  if ((millis() - lastDebounceTime) > debounceInterval2) {
    if (reading1 != buttonState1) {
      buttonState1 = reading1;
      if (buttonState1 == HIGH) {
      Serial.println("Dlouhy stisk");
  
      }
    }
  }  
  
  
  
  
  lastButtonState1 = reading1;
}

UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

bokuba
Příspěvky: 5
Registrován: 03 kvě 2021, 16:32
Reputation: 0

Re: Ovládání arduino jedním tlačítkem.

Příspěvek od bokuba » 04 kvě 2021, 18:17

Díky pavel1tu, já se špatně vyjádřil, potřebuji abych na krátký stisk cykloval těch několik akcí, jako je to v tom původním, ale zároveň abych na dlouhý stisk uměl přepínat mezi dvojicí jiných akcí - řekněme vypsat dlouhý stisk_A / dlouhý stisk_B.
V každém případě i to co jsi napsal mě trochu pomáhá se v tom zorientovat.
Díky

Odpovědět

Kdo je online

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