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, ...)
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, 21:04

Tak jsem dal dohromady celý program, který vykoná okamžitě akci prvního stisknutého tlačítka a pak čeká, než jsou všechna tlačítka zase uvolněná.

Jako základ jsem vzal ten úvodní kód, který se mi zdál nejčitelnější.

Protože teď nemám k dispozici Arduino Micro PRO, které umí simulovat USB klávesnci, vyzkoušel jsem to jen na Arduinu NANO.
Takže si zruš komentáře u příkazů, které simulují klávesnici (Keyboard.begin... a Keyboard.write...) a naopak si zakomentuj příkazy pro výstup na sériový port (Serial.println...).

Vyzkoušej a uvidíš:

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};


boolean povolena_akce = true;  // Znacka, jestli je mozne spustit akci 
byte i;                        // promenna pro ruzne smycky


//----------------------------------------------------------------
void setup()
  {
    for (i = 0; i < 4; i++)              
      {
        pinMode(BTN[i], INPUT_PULLUP);  // nastaveni smeru pinu pro tlacitka na vstup s Pull-Upy
        pinMode(LED[i], OUTPUT);        // nastaveni smeru pinu pro LED na vystup
      }
       
  //Initialize control over the keyboard:
  //  Keyboard.begin();    // PRO ARDUINO MICRO ZRUSIT KOMENTAR
  Serial.begin(9600);      // PRO ARDUINO MICRO ZAKOMENTOVAT

  }


//------------  hlavni smycka -----------
void loop()
  {
    byte cislo_akce;               // pomocna promenna s cislem stisknuteho tlacitka
    byte pocet_stisknutych = 0;    // nejdriv se zjisti, kolik je stisknutych tlacitek
    for (i = 0; i < 4; i++)
      {
        // kontrola tlacidiel
        if(cti_tlacitko(BTN[i]) == true)     
          {
            cislo_akce = i;        // nejvyssi ze stisknutych tlacitek se zapamatuje (vyuzito to bude jen v pripade, ze bude stisknuto jen jedno)
            pocet_stisknutych ++;
          }
      }

   if (pocet_stisknutych == 1)     // kdyz je stisknuto jen jedno tlacitko, provede se pozadovana akce
     {
       sendBtnPress(cislo_akce);
       povolena_akce = false;      // dalsi akce se zakazou az do doby ....
     }


   if (pocet_stisknutych == 0)     // ... dokud nebudou vsechna tlacitka uvolnena
     {
       povolena_akce = true;
     }
  }




//----------------------------------------------------------------------------
/* 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)              // key je index tlacitka a LED, pocita se od 0. Hodnota tedy muze byt 0 az 3
  {
    if (povolena_akce == true)          // akce se provadi jen v pripade, ze jsou povolene
      {
        zhasni_vsechny_LED();           // rozsviti jen jednu LED podle indexu tlacitka, ostatni zhasne
        digitalWrite(LED[key], HIGH); 

        //Perform tasks:
        switch(key)
          {
            case 0:                 // Sends a key '1'
        //      Keyboard.write('1');
              Serial.println("prvni tlacitko (index 0)");
              break;
            case 1:                 // Sends a key '2'
        //      Keyboard.write('2');
              Serial.println("druhe tlacitko (index 1)");
              break;
            case 2:                 // Sends a key '3'
        //      Keyboard.write('3');
              Serial.println("treti tlacitko (index 2)");
              break;
            case 3:                 // Sends a key '4'
        //      Keyboard.write('4');
              Serial.println("ctvrte tlacitko (index 3)");
              break;
          }
      }
  }

//----------------------------------------------------------------
// vraci true, jen kdyz je tlacitko stisknute alespon 10ms 
boolean cti_tlacitko(int pin)
  {

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

  
//----------------------------------------------------------------
void zhasni_vsechny_LED(void)
  {
    for  (i = 0 ; i<4 ; i++)
      {
        digitalWrite(LED[i], LOW);        
      }
  }

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 » 12 dub 2018, 14:34

Super dakujem za pomoc, po uprave kodu, sa nic nevykonava, povodny kod funguje, takze nieco nieje v poriadku zatial.

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

Re: Vlastne tlacidla pre PC

Příspěvek od AstroMiK » 12 dub 2018, 14:56

Zkusím někde sehnat to Arduino Micro PRO a večer to doma vyzkouším.

Už teď vidím, že tam na začátku chybí zavedení knihovny pro klávesnici:

Kód: Vybrat vše

#include <Keyboard.h> //kniznica
A pak jsem za těmi bloky "case ...." zapomněl na uvolňování tlačítek:

Kód: Vybrat vše

 delay(100);
 Keyboard.releaseAll();
Vydrž do večera, nějak to dotáhnem.

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

Re: Vlastne tlacidla pre PC

Příspěvek od AstroMiK » 12 dub 2018, 17:39

Tak mám vyzkoušeno na Arduinu Micro PRO.

Docela jsem se ale zasekl na tom, že funkce:
Keyboard.write('1');
vrací do PC znak '+'.

Podobně je to i s dalšími znaky.
místo "2" dostávám "ě"; místo '3' se mi v PC zobrazuje 'š'....
Záleží na nastavení klávesnice ve Windows.

Na internetu jsem ale našel, že při použití numerické části klávesnice by tlačítka 0 až 9 neměla být závislá na nastavení Windows.
Místo Keyboard.write('1'); se ale musí volat funkce s parametrem Keyboard.write(225);
Stejně tak pro číslo '2' se musí zadat Keyboard.write(226);
a tak dále...


Program:

Kód: Vybrat vše

#include <Keyboard.h> //kniznica

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


boolean povolena_akce = true;  // Znacka, jestli je mozne spustit akci 
byte i;                        // promenna pro ruzne smycky


//----------------------------------------------------------------
void setup()
  {
    for (i = 0; i < 4; i++)              
      {
        pinMode(BTN[i], INPUT_PULLUP);  // nastaveni smeru pinu pro tlacitka na vstup s Pull-Upy
        pinMode(LED[i], OUTPUT);        // nastaveni smeru pinu pro LED na vystup
      }
       
    //Initialize control over the keyboard:
    Keyboard.begin();          // PRO ARDUINO MICRO ZRUSIT KOMENTAR
    //Serial.begin(9600);      // PRO ARDUINO MICRO ZAKOMENTOVAT

  }


//------------  hlavni smycka -----------
void loop()
  {
    byte cislo_akce;               // pomocna promenna s cislem stisknuteho tlacitka
    byte pocet_stisknutych = 0;    // nejdriv se zjisti, kolik je stisknutych tlacitek
    for (i = 0; i < 4; i++)
      {
        // kontrola tlacidiel
        if(cti_tlacitko(BTN[i]) == true)     
          {
            cislo_akce = i;        // nejvyssi ze stisknutych tlacitek se zapamatuje (vyuzito to bude jen v pripade, ze bude stisknuto jen jedno)
            pocet_stisknutych ++;
          }
      }

   if (pocet_stisknutych == 1)     // kdyz je stisknuto jen jedno tlacitko, provede se pozadovana akce
     {
       sendBtnPress(cislo_akce);
       povolena_akce = false;      // dalsi akce se zakazou az do doby ....
     }


   if (pocet_stisknutych == 0)     // ... dokud nebudou vsechna tlacitka uvolnena
     {
       povolena_akce = true;
     }
  }




//----------------------------------------------------------------------------
/* 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)              // key je index tlacitka a LED ... pocita se od 0. Hodnota tedy muze byt 0 az 3
  {
    if (povolena_akce == true)          // akce se provadi jen v pripade, ze jsou povolene
      {
        zhasni_vsechny_LED();           // rozsviti jen jednu LED podle tlacitka
        digitalWrite(LED[key], HIGH); 

        //Perform tasks:
        switch(key)
          {
            case 0:                 // Sends a key '1'
              Keyboard.write(225);  // tyhle cisla jsou pro tlacitka v cislicove casti klavesnice a nemely by byt zavisle na narodnim nastaveni Windows  
        //      Serial.println("prvni tlacitko (index 0)");
              break;
            case 1:                 // Sends a key '2'
              Keyboard.write(226);
        //      Serial.println("druhe tlacitko (index 1)");
              break;
            case 2:                 // Sends a key '3'
              Keyboard.write(227);
        //      Serial.println("treti tlacitko (index 2)");
              break;
            case 3:                 // Sends a key '4'
              Keyboard.write(228);
        //      Serial.println("ctvrte tlacitko (index 3)");
              break;
          }
        delay(100);
        Keyboard.releaseAll();
    }
  }

//----------------------------------------------------------------
// vraci true, jen kdyz je tlacitko stisknute alespon 10ms 
boolean cti_tlacitko(int pin)
  {

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

  
//----------------------------------------------------------------
void zhasni_vsechny_LED(void)
  {
    for  (i = 0 ; i<4 ; i++)
      {
        digitalWrite(LED[i], LOW);        
      }
  }

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 » 12 dub 2018, 18:45

Hm... zaujimave ...tak uz doplnili specifikacie, tlacidiel bude 7 ... s tymto kodom to funguje super:

Kód: Vybrat vše

#include <Keyboard.h> //This is a "build-in" library no need to install

int keys[] = {2, 3, 4, 5, 6, 7, 8}; //Set up 7 buttond

void setup() {
 //Initialize the Buttons inputs:
 for (int i = 2; i < 9; ++i) {
 pinMode(i, INPUT);
 //Initialize control over the keyboard:
 Keyboard.begin();
 }
  
  /* 
  * //Open the serial port:
  * Serial.begin (9600); 
  */
  
 //Initialize the LEDs outputs:
 {
  pinMode(21, OUTPUT);
  pinMode(20, OUTPUT);
  pinMode(19, OUTPUT);
  pinMode(18, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(16, OUTPUT);
  }
}

void turn_all_the_LEDs_off(void){
  digitalWrite (21, LOW);
  digitalWrite (20, LOW);
  digitalWrite (19, LOW);
  digitalWrite (18, LOW);
  digitalWrite (15, LOW);
  digitalWrite (14, LOW);
  digitalWrite (16, LOW);
}


void loop() {
 for (int i = 2; i < 9; ++i) {
 // check buttons
 if(readButton(i)) {
 doAction(i); 
 }
 }
}

boolean readButton(int pin) {
 // check and debounce buttons:
 if (digitalRead(pin) == HIGH) {
 delay(100);
 if (digitalRead(pin) == HIGH) {
 return true;
 }
 }
 return false;
}

void doAction(int pin) {
 // perform tasks:
 switch (pin) {
 
 case 2: // Press button "1"
 turn_all_the_LEDs_off();
 digitalWrite (21, HIGH); 
 Keyboard.press('1');2211221122
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 3: // Press button "2"
 turn_all_the_LEDs_off();
 digitalWrite (20, HIGH);
 Keyboard.press('2');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 4: // Press button "3"
 turn_all_the_LEDs_off();
 digitalWrite (19, HIGH);
 Keyboard.press('3');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 5: // Press button "4"
 turn_all_the_LEDs_off();
 digitalWrite (18, HIGH);
 Keyboard.press('4');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 6: // Press button "5"
 turn_all_the_LEDs_off();
 digitalWrite (15, HIGH);
 Keyboard.press('5');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 7: // Press button "6"
 turn_all_the_LEDs_off();
 digitalWrite (14, HIGH);
 Keyboard.press('6');
 delay(100);
 Keyboard.releaseAll();
 break;
 
 case 8: // Press button "7"
 turn_all_the_LEDs_off();
 digitalWrite (16, HIGH);
 Keyboard.press('7');
 delay(100);
 Keyboard.releaseAll();
 break;
 }
}
Ako nahle chcem podmienku pre stlacenie len jedneho tlacidla ako sme riesili vyzsie s Tebou, tak sa nic nedeje, ziadna reakcia:

Kód: Vybrat vše

#include <Keyboard.h> // This is a "build-in" library no need to install

// Constants: (won't change; to set pin numbers)
// Push-buttons attachment to this pins:
const int BTN[7] = {2, 3, 4, 5, 6, 7, 8};
// LEDs attachment to this pins:
const int LED[7] = {21, 20, 19, 18, 15, 14, 16};

//Variables: (will change)
boolean allowedAction = true;   // Marker if the action can be triggered
byte i;                         // Variable for different loops

void setup()  {
  // Intialize the buttons inputs & LEDs outputs:
  for (int i=0; i<7; i++) {
  pinMode(BTN[i], INPUT);
  pinMode(LED[i], OUTPUT);
  }
  //Initialize control over the keyboard:
  Keyboard.begin();
}

void loop() {
  byte noAction;                     // Variable: Pressed button name
  byte noOfPressed = 0;              // First, find out how many buttons are pressed
  for (i = 0; i < 7; i++) {
    // Check buttons
    if (btnRead(BTN[i]) == true) {
      noAction = i;                  // The highest number of the pressed buttons will be remembered (this will only be used if only one is pressed)
      noOfPressed ++;
    }
  }
  if (noOfPressed == 1) {            // If is pressed only one button, performs the desired action
    sendBtnPress(noAction);
    allowedAction = false;           // The next actions are forbidden until ...
  }

  if (noOfPressed == 0) {            // ... until all the buttons are released
    allowedAction = true;
  }
}

/* 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)  {     // "key" is index of the button & LED, it is counted from 0. The value may therefore be from 0 to 6.
  if (allowedAction == true) {    // Action shall be implemented only if it is allowed
    LEDsOff();                    // Only one LED light up according to the index of button, others turn off
    digitalWrite(LED[key], HIGH); 
  
    //Perform tasks:
    switch(key) {
      case 0:                 // Send a key '1'
        Keyboard.write('1');
        break;
      case 1:                 // Send a key '2'
        Keyboard.write('2');
        break;
      case 2:                 // Send a key '3'
        Keyboard.write('3');
        break;
      case 3:                 // Send a key '4'
        Keyboard.write('4');
        break;
      case 4:                 // Send a key '5'
        Keyboard.write('5');
        break;
      case 5:                 // Send a key '6'
        Keyboard.write('6');
        break;
      case 6:                 // Send a key '7'
        Keyboard.write('7');
        break; 
      }
      delay(100);
      Keyboard.releaseAll();
   }
}

// Returns true only when the button is pressed for at least 10ms
boolean btnRead(int pin) {
  boolean output = false;
  // Check and debounce buttons:
  if (digitalRead(pin) == LOW) {
    delay(10);
    if (digitalRead(pin) == LOW) {
      output = true;
    }
  }
  return output;
}

// Turn all the LEDs off
void LEDsOff(void) {
  for (i = 0; i < 7; i++) {
    digitalWrite(LED[i], LOW);
  }
}

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 » 12 dub 2018, 18:52

Uz som nasiel chybu; musel som upravit podmienku z LOW na HIGH:

Kód: Vybrat vše


// Returns true only when the button is pressed for at least 10ms
boolean btnRead(int pin) {
  boolean output = false;
  // Check and debounce buttons:
  if (digitalRead(pin) == HIGH) {
    delay(10);
    if (digitalRead(pin) == HIGH) {
      output = true;
    }
  }
  return output;
}

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 » 13 dub 2018, 10:30

Takze mal si pravdu:

1. ked dam posielat: '1';'2';'3';'4'; atd. - tak musi byt klavesnica nstavena na eng
2. ked dam posielat: 225;226;227;228; atd. - tak zas musi byt aktivny numlok

Osetrovat to nebudem, necham to povodne, tak aby nastavili eng klavesnici, pretoze, ked to niekto pripoji k notebooku bez numlocku, tak mu to nebude fungovat spravne. Kazdopadne vdaka moc za pomoc.

Odpovědět

Kdo je online

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