Vlastne tlacidla pre PC

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
swupy
Příspěvky: 19
Registrován: 06 bře 2018, 14:19
Reputation: 0

Vlastne tlacidla pre PC

Příspěvek od swupy » 06 dub 2018, 13:46

Ahojte, zacal som robit vlastne tlacidla pre kiosk

Pouzijem:
1x Arduino Pro Micro
4x 10kOhm R
4x 220/470 Ohm R
4x tlacidla s vlastnout LED

Princip:
Kazde tlacidlo je nastavenie tak aby poslalo nejaky prikaz do PC.
Problem mam ako vlozit podmienky pre LED-ky, viete poradit? Dakujem

Stlac B1, zapni LED 1 a ostan svietit kym sa nestlaci ine tlacidlo, odosli do PC "1"
Ked sa stalci B2 tak zhasne povodna LED, a rozvieti sa LED2, kym sa zas nestlaci ine tlacidlo:

Kód: Vybrat vše

#include <Keyboard.h> //kniznica

int keys[] = {2, 3, 4, 5}; //nastavenie klaves

void setup() {
  
 /* 
    Serial.begin (9600); 
  */
 
 Keyboard.begin(); // inicializacia
 for (int i = 2; i < 6; ++i) {
 // inicializacia vystupov
 pinMode(i, INPUT);
 
 /* //LEDs vystupy
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(13, OUTPUT);
  */
    
 }
}

void loop() {
 for (int i = 2; i < 6; ++i) {
 // kontrola tlacidiel
 if(readButton(i)) {
 doAction(i); 
 }
 }
}

boolean readButton(int pin) {
 // skontrolovat a odblokovat tlacidla
 if (digitalRead(pin) == HIGH) {
 delay(10);
 if (digitalRead(pin) == HIGH) {
 return true;
 }
 }
 return false;
}

void doAction(int pin) {
 // perform tasks
 switch (pin) {
 
 case 2: // Press button "1"
 Keyboard.press('1');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 3: // Press button "2"
 Keyboard.press('2');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 4: // Press button "3"
 Keyboard.press('3');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 5: // Press button "4"
 Keyboard.press('4');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 }
}
Do buducna sa kazde tlacidlo bude upravovat podla pouzitia, pre kiosk, napriklad spustanie prezentacie pre kazde tlacidlo.

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od AstroMiK » 06 dub 2018, 15:47

Asi bych to řešil tak, že bych vytvořil podprogram "zhasni_vsechny_LED()", který by všechno zhasnul nezávisle na tom, co zrovna svítí.

Kód: Vybrat vše

void zhasni_vsechny_LED(void)
  {
    digitalWrite(10, LOW);
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);
    digitalWrite(13, LOW);
  }

A pak bych v každém z těch "case __ :" bloků doplnil něco takovéhodle:

Kód: Vybrat vše

 case 2: // Press button "1"
 zhasni_vsechny_LED();         // zhasne vsechny LED
 digitalWrite(10, HIGH);       // rozsviti jen jednu pozadovanou LED
 Keyboard.press('1');
 delay(100);
 Keyboard.releaseAll();
 
 break;

swupy
Příspěvky: 19
Registrován: 06 bře 2018, 14:19
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od swupy » 06 dub 2018, 19:58

AstroMiK píše:
06 dub 2018, 15:47
Asi bych to řešil tak, že bych vytvořil podprogram "zhasni_vsechny_LED()", který by všechno zhasnul nezávisle na tom, co zrovna svítí.

Kód: Vybrat vše

void zhasni_vsechny_LED(void)
  {
    digitalWrite(10, LOW);
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);
    digitalWrite(13, LOW);
  }

A pak bych v každém z těch "case __ :" bloků doplnil něco takovéhodle:

Kód: Vybrat vše

 case 2: // Press button "1"
 zhasni_vsechny_LED();         // zhasne vsechny LED
 digitalWrite(10, HIGH);       // rozsviti jen jednu pozadovanou LED
 Keyboard.press('1');
 delay(100);
 Keyboard.releaseAll();
 
 break;
To znie zaujimavo odskusam to, ked dorazi zbytok HW. Este musim poriesit podmienky pre deti, co radi stlacaju vsetko :lol:

swupy
Příspěvky: 19
Registrován: 06 bře 2018, 14:19
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od swupy » 09 dub 2018, 15:22

Zatial to funguje.
Teraz potrebujem poriesit dalsiu podmienku:
1. Len jedno tlacidlo stlacene vykonaj case"x" (podla tlacidla) ... - to mame a funguje
2. Ak niekto stlaci dve a viac tlacidiel naraz - nic nevykonaj ... vie niekto poradit?

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od AstroMiK » 09 dub 2018, 18:49

A co když se stiskne tlačítko "1" a po desetině sekundy se k tomu stiskne ještě tlačítko "2"?
Má se to brát jako "naraz"? - takže se žádná akce (ani ta první) nevykoná?

A nebo to není "naraz", tak se vykonají obě akce?
Kde je ta hranice?
Jak dlouho se po stisku prvního tlačítka NEMÁ vykonávat žádná akce, ale má se testovat, jestli náhodou ještě nebylo stisknuto zároveň další tlačítko?

---

Já si myslím, že je to zadání špatně.
Asi by bylo lepší, kdyby se po stisku jakéhokoliv tlačítka okamžitě vykonala akce tlačítka, které by bylo třeba o setinu sekundy rychlejší než ostatní.
A pak by byla jakákoliv další akce zakázána až do doby, než se všechna tlačítka uvolní.

swupy
Příspěvky: 19
Registrován: 06 bře 2018, 14:19
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od swupy » 10 dub 2018, 08:56

Ano, vdaka, mas pravdu, asi by to bolo logickejsie.

Len neviem ako to spravne nastavit. Pretoze:
- Mam 4 tlacidla, kazde vykona alebo spusti svoju prezentaciu (takze su 4 prezentacie):
- Pride uzivatel stlaci akekolvet tlacidlo a spusti danu prezentaciu.
- Problem nastava ked pride uzivatel a stlaci napriklad 3,4 naraz (takze vysle signal a spusti bud prezentaciu 3 alebo 4, podla toho ako to zareaguje)

Osetrit to chcem tak, ze sa nic nevykona. Proste sa vykona odoslanie na PC len ak sa stlaci len jedno tlacidlo. Ale asi vlozim zlozitu podmienku, kde bude kontrolovat len stlacenie jedneho tlacidla.

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od AstroMiK » 10 dub 2018, 09:37

Stále je mezi námi nedorozumění.

Zkusím to popsat krok za krokem.

V normálním případě, který už teď funguje:
- Stiskne se první tlačítko.
- po několika milisekundách program vyhodnotí, že tlačítko bylo stisknuto a vykoná přslušnou akci
- během několika dalších desetin sekundy se tlačítko uvolní.


V případě, že se ale někdo pokusí stisknout dvě tlačítka zároveň:
(Úplně najednou se to většinou nepodaří. Téměř vždycky tam bude nějaká časová prodleva mezi stiskem prvního a druhého tlačítka - třeba v řádu setin sekundy.)

- Stiskne se první tlačítko.
- po několika milisekundách program vyhodnotí, že tlačítko bylo stisknuto a vykoná přslušnou akci
(až sem je to stejné, jako v předchozím případě)
- po dalších několika milisekundách se stiskne druhé tlačítko. (V reálu to vypadá, jako by tlačítka byla stisknutá současně.)

A tady je problém v tom zadání. Ty požaduješ, aby se teď žádná akce nevykonala. Jenže první akce už je spuštěná a nedá se zastavit.



Řešení existuje několik. První jsem navrhoval už minule:
První akce se vykoná okamžitě podle prvního stisknutého tlačítka.
A pak, dokud bude nějaké tlačítko stisknuté, další akce už se neprovede.
(Když tedy někdo náhodně plácne rukou přes všechny tlačítka, tak se vykoná akce tlačítka, které bylo stisknuté o nějakou setinu sekundy dříve, než ostatní.)


Jiné řešení by bylo spouštět akci až při uvolňování tlačítka.
A akci spustit jen v tom případě, že v okamžiku po uvolnění tlačítka už nebude stisknuté žádné tlačítko.



Další možnost je, spustit akci až po nějaké době od stisku tlačítka (třeba půl sekundy).
Během této doby by se zjišťovalo, jestli je stále stisknuté jen jedno tlačítko.
Pokud by po uplynutí zvolené doby bylo vyhodnoceno, že bylo stisknuté jen jedno tlačítko, vykonala by se akce.

swupy
Příspěvky: 19
Registrován: 06 bře 2018, 14:19
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od swupy » 10 dub 2018, 10:25

Rozumiem
Teraz musim premysliet, ktore riesenie bude efektivnejsie.

Teraz ked stlacim jedno tlacitko a drzim stale posiela jeden znak, a ked stacim nahodne ine tlacitko tak posle aj ten znak.
Mozno bude treba definovat kratke stlacenie, dlhe stlacenie, ... Ja riesim len HW tlacidla ktore poslu podla stlacenia znak do PC, a v PC druhy ludia robia program podla ktoreho prijme znak z tlacidiel tak podla toho spusti danu prezentaciu.

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od AstroMiK » 10 dub 2018, 10:58

... přesně tak.

Dokonce v aktuální verzi programu se při držení obou tlačítek odesílají jejich kódy opakovaně s časovým rozestupem asi 100 ms.

Takže při současném držení tlačítka 1 a 2 se odesílá:
"1", (100ms pauza), "2", (100ms pauza), "1", (100ms pauza), "2", (100ms pauza), "1", (100ms pauza), "2", (100ms pauza), .....

swupy
Příspěvky: 19
Registrován: 06 bře 2018, 14:19
Reputation: 0

Re: Vlastne tlacidla pre PC

Příspěvek od swupy » 10 dub 2018, 13:20

Tak neviem ako dalej:

Mam definovane konstanty:

Kód: Vybrat vše

// Constants: (won't change, they're used here to set pin numbers)
// Pushbuttons pins:
const int BTN1 = 2;
const int BTN2 = 3;
const int BTN3 = 4;
const int BTN4 = 5;
// LEDs pins:
const int LED1 = 10;
const int LED2 = 16;
const int LED3 = 14;
const int LED4 = 15;
viem ich zjednodusit takto?

Kód: Vybrat vše

  // Pushbuttons pins:
  const int BTN[4] = {2, 3, 4, 5};
  // LEDs pins:
  const int LED[4] = {10, 16, 14, 15};
definovanie premennych:

Kód: Vybrat vše

int ledStatus;           // The current state of the output pin
int btnStatus;           // The current reading from the input pin
int timeout;             // timeout variable used in loop
nasleduje kod:

Kód: Vybrat vše

void setup()  {
  // Intialize the buttons inputs:
    // simplification code:
    // for (int i=0; i<4; i++) {
    // pinMode(BTN[i], INPUT);
    // //Initialize control over the keyboard:
    // Keyboard.begin();
    // }
  pinMode(BTN1, INPUT);
  pinMode(BTN2, INPUT);
  pinMode(BTN3, INPUT);
  pinMode(BTN4, INPUT);
  //Initialize control over the keyboard:
  Keyboard.begin();
  // Intialize the LEDs outputs:
    // simplification code:
    // for (int j=0; j<4; j++) {
    // pinMode(LED[j], INPUT);
    // }
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
}

void loop() {
  btnStatus = getBtnStatus();                             // Read witch buttons are pressed
  if (btnStatus != 0) {                                   // If a button is pressed go into here
    sendBtnPress(btnStatus);                              // Send the button over USB
    timeout = 2000;                                       // Top of the repat delay
    while ((getBtnStatus() == btnStatus) && (--timeout))  //Decrement timeout and check if button is being held down
      delayMicroseconds(1);
    while (getBtnStatus() == btnStatus)                   //While the same button is held down
    {
      sendBtnPress(btnStatus);                            // Continue to send the button over USB
      delay(50);                                          // 50ms repat rate
    }
  }  
}

/* This function sends a single key over USB
 * This function will only send a key press if a single button is being pressed
 */

void sendBtnPress(int key)  {
  //Perform tasks:
  switch(key) {
    case 1:                 // Sends a key '1'
      Keyboard.write('1');
      break;
    case 2:                 // Sends a key '2'
      Keyboard.write('2');
      break;
    case 3:                 // Sends a key '3'
      Keyboard.write('3');
      break;
    case 4:                 // Sends a key '4'
      Keyboard.write('4');
      break;
  }
}

int getBtnStatus() {
  int BTN[4] = {2, 3, 4, 5};
  int btnStatus = 0;    // This will be what's returned
  // Initialize all pins, inputs w/ pull-ups
  for (int i=0; i<4; i++)
  {
    pinMode(BTN[i], INPUT);
    digitalWrite(BTN[i], HIGH);
  }
  return keypadStatus;
}
funkciu: int getBtnStatus() - neviem ako definovat presne ( treba asi dodat for, a if podminku), ale mam pocit, ze to stale rovnako funguje ako v predoslom pripade

Odpovědět

Kdo je online

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