Arduino jako klávesnice 2

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, ...)
gilhad
Příspěvky: 331
Registrován: 07 bře 2018, 11:22
Reputation: 2

Re: Arduino jako klávesnice 2

Příspěvek od gilhad » 14 čer 2019, 18:22

Odpověď, která asi moc nepotěší, ale uvede věci na pravou míru

Arduino jako klávesnice používá USB protokol pro klávesnici, ten sám je docela omezený (odesílá maximálně 6 kláves naráz + modifikátory (jako levý shift, pravý alt atd celkem 8 bitů=1byte) a docela složitý (

https://www.usb.org/documents?search=&i ... r_page=All
https://www.usb.org/sites/default/files ... id1_11.pdf Device Class Definition for HID 1.11
https://usb.org/sites/default/files/doc ... 1_12v2.pdf HID Usage Tables 1.12
)


V podstatě (kromě spousty režie) klávesnice posílá počítači toto ( viz Arduino/build/linux/work/libraries/Keyboard/src ) :

Keyboard.h :75

Kód: Vybrat vše

typedef struct
{
  uint8_t modifiers;
  uint8_t reserved;
  uint8_t keys[6];
} KeyReport;


Aby to nebylo složité a lidi to nevyděsilo (=Arduino way), tak to je celé zabalené v něčem, co to umožní používat jednoduše, za cenu ztráty funkcionality a nepřesností - ta knihovna Keyboard - najděte si ji na svém počítači)

modifiers jsou různé "shifty" viz Keyboard.h :37 (akorát ta čísla (-0x80) odpovídají jednotlivým bitům)

Kód: Vybrat vše

    
    #define KEY_LEFT_CTRL   0x80
    #define KEY_LEFT_SHIFT    0x81
    #define KEY_LEFT_ALT    0x82
    #define KEY_LEFT_GUI    0x83
    #define KEY_RIGHT_CTRL    0x84
    #define KEY_RIGHT_SHIFT   0x85
    #define KEY_RIGHT_ALT   0x86
    #define KEY_RIGHT_GUI   0x87
    
keys[6] je pole aktuálně stisknutých tlačítek podle specifikace HID Usage Tables 1.12 strana 53 a další, v knihovně je "nějak" převádějí ze zadaných písmen (a předpokládají anglickou klávesnici) a dál s tím dělají všeliké vylomeniny, aby to "nějak" fungovalo

Keyboard.cpp :86

Kód: Vybrat vše

const uint8_t _asciimap[128] =
číslice se berou z řady kláves nad QWERTY, bez shiftu

Takže když zkoušíte psát ALT+0397 přez alt a číslice, tak vám to pochotitelně na té číslicové řadě nejde, (protože to počítač "vidí" jako ALT+éšíý a nedává mu to smysl).

Navíc knihovna Keyboard předpokládá vypnutý NumLock a šipky píše na něm (s tím, že aby poznala, že jde o "speciální znaky" tak jsou ty kódu posunuté o 136 nahoru a při použití od nich zase 136 odečte

Kód: Vybrat vše

    #define KEY_UP_ARROW    0xDA
    #define KEY_DOWN_ARROW    0xD9
    #define KEY_LEFT_ARROW    0xD8
    #define KEY_RIGHT_ARROW   0xD7
Takže buď si pro tyhle speciální kódy nadefinovat vlastní funkci, která přepíše Keyboard_::press, nebo si ty kódy pro numerickou klávesnici dopočítat a dodefinovat jako konstanty, tak aby to té funkci vyšlo správně (a možná bude potřeba to posílat jako sekvenci NumLock,Alt+0397,Numlock, nebo Shift+Alt+0397 - to už musíte vyzkoušet, co Windows pochopí správně)

---

Shrnutí: USB klávesnice (ať už Arduino, nebo klasická) vůbec neví nic o rozložení znaků, nebo jaký jazyk se právě používá a jen odesílá, jaké klávesy byly namačkané. OS z toho nějak usoudí, jaké písmena (nebo jiné věci, jako multimediální, spuštění programů a podobně) by to asi tak mohlo znamenat (aniž by tušil, co je na klávesnici napsáno)

Arduino knihovna Keyboard dělá spoustu triků, aby to před uživatelem schovala a složitě a nepřesně předstírá, že umi psát písmena. Pro složitější věci doporučuju si projít její kód a buď ji ošidit, nebo si napsat vlastní, která to bude dělat požadovaným způsobem (není to až zas tak těžké)

gilhad
Příspěvky: 331
Registrován: 07 bře 2018, 11:22
Reputation: 2

Re: Arduino jako klávesnice 2

Příspěvek od gilhad » 14 čer 2019, 19:06

Tady odkaz na můj blog:

Arduino jako klávesnice 1
http://micro-corner.gilhad.cz/blog/Adru ... ice-1.html

Vejv-cz
Příspěvky: 8
Registrován: 26 dub 2019, 20:53
Reputation: 0

Re: Arduino jako klávesnice 2

Příspěvek od Vejv-cz » 15 čer 2019, 23:02

Velmi děkuji za odpověď. Díval jsem se na to a zdálo se mi to strašně složité a nějak jsem přišel na toto řešení:

1) Povolil jsem v nastavení oblasti "Používat Unicode UTF-8 pro celosvětovou podporu jazyků". Následně jsem restartoval PC.
2) Nepsal jsem tento kód, který nejspíše nebude správně napsaný, ale funguje:

Kód: Vybrat vše

#include "Keyboard.h"

int cisla[10][10] = {
  {234, 225, 226, 227, 228, 229, 230, 231, 232, 233},
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
};
unsigned long delayStart = 0;

void setup() {
  Serial.begin(115200);
  Keyboard.begin();
  delay(1000);
}
String vstup;
int prvni; int druhe; int treti;
char in1; char in2; char in3;
void loop() {
  if (Serial.available()) {

    vstup = Serial.readStringUntil('\n');

    in1 = vstup.charAt(0);
    in2 = vstup.charAt(1);
    in3 = vstup.charAt(2);

    for (byte i = 0; i < 10; i++) {
      if (cisla[0][i + 10] == in1 - 48) {
        prvni = cisla[0][i];
      }
      if (cisla[0][i + 10] == in2 - 48) {
        druhe = cisla[0][i];
      }
      if (cisla[0][i + 10] == in3 - 48) {
        treti = cisla[0][i];
      }
    }
    Keyboard.press(KEY_LEFT_ALT);
    Keyboard.write(234);
    Keyboard.write(prvni);
    Keyboard.write(druhe);
    if (vstup.length() >= 3) {
      Keyboard.write(treti);
    }
    Keyboard.releaseAll();
  }
}
Pokud by někdo měl chuť to opravit, rád se podívám jak se to dá udělat lépe.
Nyní stačí poslat kód znaku podle ISO8859-2 a je to.

Nyní se ovšem pokouším napsat program v Pythonu, který zvládne do Arduina posílat přes serial linku kódy písmen, ale vždy musím čekat sekundu a až potom můžu poslat další znak. Serial monitor u Arduina IDE zvládne posílat znaky mnohem rychleji, takže chyba by neměla být v kódu Arduina. Nemá náhodou někdo zkušenost s rychlým posíláním dat z Pythonu do Arduina?

Kód: Vybrat vše

import serial, time
arduino = serial.Serial('COM5', 9600, timeout=0.1)
time.sleep(1)
 

text= "Testovací text.@"
for x in text:
    zadani= str(ord(x))
    arduino.write(zadani.encode())
    time.sleep(1)
Středně pokročilý nováček.

gilhad
Příspěvky: 331
Registrován: 07 bře 2018, 11:22
Reputation: 2

Re: Arduino jako klávesnice 2

Příspěvek od gilhad » 16 čer 2019, 01:55

Posílat kód z Pythonu do Arduina jsem nezkoušel, ale poku se v Arduinu Serial.readStringUntil('\n'); tak bych docela čekal, že v Pythonu se to \n taky někde pošle, třeba v tom arduino.write(zadani.encode()) nebo, že použiješ místo write(), které konec řádku neposílá, něco jako writeln(), které ho posílá (pokud ho tam máš, jinak prostě

Kód: Vybrat vše

    arduino.write(zadani.encode())
    arduino.write('\n')

RomanB
Příspěvky: 42
Registrován: 04 zář 2017, 14:28
Reputation: 0
Bydliště: Havířov

Re: Arduino jako klávesnice 2

Příspěvek od RomanB » 16 čer 2019, 08:38

Do arduina to posíláš pythonem rychlostí 9600 a v arduinu to čteš 115200

Vejv-cz
Příspěvky: 8
Registrován: 26 dub 2019, 20:53
Reputation: 0

Re: Arduino jako klávesnice 2

Příspěvek od Vejv-cz » 16 čer 2019, 12:54

Díky, bylo to tak, jak říkáte oba dva.
V kódu Arduina jsem změnil rychlost na 115200 a v Pythonu jsem to upravil takto:

Kód: Vybrat vše

import serial, time
arduino = serial.Serial('COM5', 115200, timeout=0.0001)
time.sleep(1)
 

text= ("ěščřžght")
for x in text:
    znak= str(ord(x.encode('Windows-1250')))
    arduino.write(znak.encode('Windows-1250'))
    arduino.write(b'\n')
Nakonec ani změna v nastavení "Používat Unicode UTF-8 pro celosvětovou podporu jazyků" není správná. Taky jsem se spletl s ISO8859-2, je to Windows-1250.

Ale jinak mi to už funguje :D .
Díky všem, kteří ochotně poradili.
Středně pokročilý nováček.

Odpovědět

Kdo je online

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