Frage zum Leonardo, Keyboard.press() etc.

Hallo,

lt. Online-Doku kann man Klartext an die Methode press/unpress übergeben. Das bedeutet doch, dass man, wenn ein deutsches Layout am PC eingestellt ist, z.B. nach press('ß') ein Minus bekommt. Richtig?

Gibt's die Möglichkeit, direkt USB HID Codes anzugeben? Derzeit benutze ich einen Duemillanove mit USB-Shield und der AVR-USB Library. Da hier hin und wieder das Timing nicht hinhaut (der Arduino muss noch einen Tastaturcontroller bedienen), würde ich es gerne mit dem Leonardo versuchen und möchte sowenig Änderungen am Sketch vornehmen wie möglich.

Danke!

Richtig?

Leider falsch. Es ist zwar richtig, dass man Klartext-Buchstaben übergeben kann, aber das geht nur für die ASCII-Zeichen. Alle Umlaute und deutsche Sonderzeichen (ß) sind nicht im ASCII-Zeichenvorrat enthalten. Auch weden die Zeichen nur auf die amerikanische Tastaturbelegung umgerechnet. Du kannst das aber ändern, die entsprechende Tabelle ist in hardware/arduino/cores/arduino/HID.cpp enthalten. Du kannst mit den gleichen Methoden Deine eigene press-Routine schreiben, die dann deutsche Zeichen z.B. im ISO-8859-15-Encoding oder gar in UTF-8 entgegennimmt. Beachte einfach die Modifiers, die sind momentan im oberen Bereich einkodiert, das müsstest Du ändern.

Prima, danke Pylon.

Die Methoden press und release habe ich umgeschrieben, so dass sie HID Codes und Modifier direkt übernehmen. USBAPI.h ist entsprechend geändert. Offenbar muss nun eine Library neu übersetzt werden fehlt noch irgendwo eine Deklaration, und da stehe ich schon wieder auf dem Schlauch :-(.

Tipps?

Hi thradtke,

ich habe mich damit auch mal auseinander gesetzt http://arduino.cc/forum/index.php/topic,108717.0.html da müssten auch noch die aktuellesten Änderungen von mir drin sein, mich würde interessieren wie du Änderungen vorgenommen hast.

Grüsse

Markus

Moin Markus,

ich übergebe einfach nur Key und Modifier und lasse diese Codes direkt in den Report übernehmen. Beim Modifier ist's ja einfach, der wird dazuge-OR-t bzw. dazuge-NAND-t (unpress). Den Keyeintrag habe ich gelassen, wie er war (Test auf doppelte Eintrage z.B.).

So müsste es funktionieren. Compilieren konnte ich das hier inzwischen, aber mein Arduino ist grade nicht in Reichweite. Heute abend weiß ich mehr und gebe Rückmeldung.

VG

Thomas

Edit: Das Ganze ist gedacht, eine weitgehend anders organisierte Tastatur (Amiga) an den Raspberry Pi anzuschließen. Ich habe also eigene Tabellen, um von Amiga Key-Codes zu den erforderlichen HID-Codes zu kommen. Und ja, man muss dabei um die Ecke denken, insbesondere wenn man das deutsche Layout aktiviert hat. Es funktioniert aber, was diese Logik angeht, bereits mit einem nicht-Leonardo. Der Haken: Die gleichen Tabellen funktionieren nicht mehr, wenn das US Layout aktiv ist. Das ist aber ein Fehler, der aufgrund der unterschiedlichen Belegung unvermeidlich und wenig tragisch ist.

Ok - was geht hier vor? Der identische Sketch lässt sich unter Arduino-1.0.1 auf einem i5/Win7Pro compileren, bricht aber unter der gleichen Distribution (kopiert) auf einem i3/Win7 HomePrem. mit folgendem Fehler ab:

C:\Program Files (x86)\arduino-1.0.1\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega32u4 -DF_CPU=16000000L -MMD -DUSB_VID=0x2341 -DUSB_PID=0x8036 -DARDUINO=101 -IC:\Program Files (x86)\arduino-1.0.1\hardware\arduino\cores\arduino -IC:\Program Files (x86)\arduino-1.0.1\hardware\arduino\variants\leonardo C:\Users\Thomas\AppData\Local\Temp\build6000611932258292467.tmp\amiga_leo_1.cpp -o C:\Users\Thomas\AppData\Local\Temp\build6000611932258292467.tmp\amiga_leo_1.cpp.o
amiga_leo_1.cpp: In function 'void setup()':
amiga_leo_1:71: error: 'class Keyboard_' has no member named 'press2'

Ich hatte auf dem i3 vorher Arduino-1.0 benutzt, auf dem i5 nicht. Liegt's daran? Wenn ja, wie räume ich auf?

Edit: Grade alles rübergeschoben in die VBox, Win2003 - funktioniert soweit. Toll.

Hat bitte jemand die komplette HID.cpp mit deutschen Umlauten :slight_smile:

Hat bitte jemand die komplette HID.cpp mit deutschen Umlauten

Für welches Encoding, welche Tastaturbelegung? Das solltest Du erwähnen. Ich habe zwar keine vorrätig, aber die entsprechende Routine muss zuerst das Encoding richtig erkennen und dann noch die richtigen Scancodes für die entsprechende Belegung schicken.

ü
Key code=186

ö
Key code=192

ä
Key code=222

Ü, Ä, Ö | SHIFT

Vorzugsweise ISO-8859-1-Zeichensatz

450px-KB_Germany.svg.png

ü
Key code=186

ö
Key code=192

ä
Key code=222

Woher Du diese Keycodes hast, weiss ich nicht, aber sie stimmen weder für das ISO-8859-1 encoding, noch haben sie etwas mit den Raw Codes von HID zu tun.

Ich habe das mal für Dich zusammengehackt, ich hoffe, ich bin nie verrutscht. Die _asciimap musst Du ersetzen, die zwei Funktionen sind zusätzlich, denn bei den Originalen sind die Codes oberhalb 128 auch belegt. Der Rest von HID.cpp bleibt gleich.

extern
const uint8_t _asciimap[256] PROGMEM;

#define SHIFT 0x80
#define ALTGR 0x40
const uint8_t _asciimap[256] =
{
	0x00,             // NUL
	0x00,             // SOH
	0x00,             // STX
	0x00,             // ETX
	0x00,             // EOT
	0x00,             // ENQ
	0x00,             // ACK  
	0x00,             // BEL
	0x2a,			// BS	Backspace
	0x2b,			// TAB	Tab
	0x28,			// LF	Enter
	0x00,             // VT 
	0x00,             // FF 
	0x00,             // CR 
	0x00,             // SO 
	0x00,             // SI 
	0x00,             // DEL
	0x00,             // DC1
	0x00,             // DC2
	0x00,             // DC3
	0x00,             // DC4
	0x00,             // NAK
	0x00,             // SYN
	0x00,             // ETB
	0x00,             // CAN
	0x00,             // EM 
	0x00,             // SUB
	0x00,             // ESC
	0x00,             // FS 
	0x00,             // GS 
	0x00,             // RS 
	0x00,             // US 

	0x2c,		   //  ' '
	0x1e|SHIFT,	   // !
	0x1f|SHIFT,	   // "
	0x31,          // #
	0x21|SHIFT,    // $
	0x22|SHIFT,    // %
	0x23|SHIFT,    // &
	0x31|SHIFT,    // '
	0x25|SHIFT,    // (
	0x26|SHIFT,    // )
	0x30|SHIFT,    // *
	0x30,          // +
	0x36,          // ,
	0x38,          // -
	0x37,          // .
	0x24|SHIFT,    // /
	0x27,          // 0
	0x1e,          // 1
	0x1f,          // 2
	0x20,          // 3
	0x21,          // 4
	0x22,          // 5
	0x23,          // 6
	0x24,          // 7
	0x25,          // 8
	0x26,          // 9
	0x37|SHIFT,    // :
	0x36|SHIFT,    // ;
	0x03,          // <
	0x27|SHIFT,    // =
	0x03|SHIFT,    // >
	0x2d|SHIFT,    // ?
	0x14|ALTGR,    // @
	0x04|SHIFT,    // A
	0x05|SHIFT,    // B
	0x06|SHIFT,    // C
	0x07|SHIFT,    // D
	0x08|SHIFT,    // E
	0x09|SHIFT,    // F
	0x0a|SHIFT,    // G
	0x0b|SHIFT,    // H
	0x0c|SHIFT,    // I
	0x0d|SHIFT,    // J
	0x0e|SHIFT,    // K
	0x0f|SHIFT,    // L
	0x10|SHIFT,    // M
	0x11|SHIFT,    // N
	0x12|SHIFT,    // O
	0x13|SHIFT,    // P
	0x14|SHIFT,    // Q
	0x15|SHIFT,    // R
	0x16|SHIFT,    // S
	0x17|SHIFT,    // T
	0x18|SHIFT,    // U
	0x19|SHIFT,    // V
	0x1a|SHIFT,    // W
	0x1b|SHIFT,    // X
	0x1d|SHIFT,    // Y
	0x1c|SHIFT,    // Z
	0x25|ALTGR,    // [
	0x2d|ALTGR,    // bslash
	0x26|ALTGR,    // ]
	0x35,          // ^
	0x38|SHIFT,    // _
	0x2e|SHIFT,    // `
	0x04,          // a
	0x05,          // b
	0x06,          // c
	0x07,          // d
	0x08,          // e
	0x09,          // f
	0x0a,          // g
	0x0b,          // h
	0x0c,          // i
	0x0d,          // j
	0x0e,          // k
	0x0f,          // l
	0x10,          // m
	0x11,          // n
	0x12,          // o
	0x13,          // p
	0x14,          // q
	0x15,          // r
	0x16,          // s
	0x17,          // t
	0x18,          // u
	0x19,          // v
	0x1a,          // w
	0x1b,          // x
	0x1d,          // y
	0x1c,          // z
	0x24|ALTGR,    // 
	0x03|ALTGR,    // |
	0x27|ALTGR,    // }
	0x35|SHIFT,    // ~
	0x2a           // DEL

	0x00,             // NUL
	0x00,             // SOH
	0x00,             // STX
	0x00,             // ETX
	0x00,             // EOT
	0x00,             // ENQ
	0x00,             // ACK  
	0x00,             // BEL
	0x2a,			// BS	Backspace
	0x2b,			// TAB	Tab
	0x28,			// LF	Enter
	0x00,             // VT 
	0x00,             // FF 
	0x00,             // CR 
	0x00,             // SO 
	0x00,             // SI 
	0x00,             // DEL
	0x00,             // DC1
	0x00,             // DC2
	0x00,             // DC3
	0x00,             // DC4
	0x00,             // NAK
	0x00,             // SYN
	0x00,             // ETB
	0x00,             // CAN
	0x00,             // EM 
	0x00,             // SUB
	0x00,             // ESC
	0x00,             // FS 
	0x00,             // GS 
	0x00,             // RS 
	0x00,             // US 

	0x2c|ALTGR,       // nobr
	0x1e|ALTGR|SHIFT, // ¡
	0x06|ALTGR,       // ¢
	0x20|ALTGR|SHIFT, // £
	0,                // currency sign
	0,                // yen sign
	0x03|ALTGR|SHIFT, // ¦
	0x20|SHIFT,       // §
	0x2f|ALTGR,       // "
	0,                // copy
	0,                // fem
	0,                // left pointing double angle
	0,                // not
	0,                // soft hyphen
	0,                // reg
	0,                // macron
	0x35|SHIFT,       // degree
	0,                // plus-minus
	0,                // super2
	0,                // super3
	0,                // acute
	0,                // µ
	0,                // pilcrow
	0,                // mid dot
	0,                // cedilla
	0,                // super1
	0,                // masc
	0,                // right pointing double angle
	0,                // quarter
	0,                // half
	0,                // 3 quarter
	0,                // inv questmark
	0,                // À
	0,                // Á
	0,                // Â
	0,                // Ã
	0x34|SHIFT,       // Ä
	0,                // ringA
	0,                // Æ
	0,                // Cedi
	0,                // È
	0,                // É
	0,                // Ê
	0,                // Ë
	0,                // Ì
	0,                // Í
	0,                // Î
	0,                // Ï
	0,                // Eth
	0,                // Ñ
	0,                // Ò
	0,                // Ó
	0,                // Ô
	0,                // Õ
	0x31|SHIFT,       // Ö
	0,                // mult
	0,                // Ø
	0,                // Ù
	0,                // Ú
	0,                // Û
	0x2f|SHIFT,       // Ü
	0,                // Ý
	0,                // Thorn
	0x2d,             // ß
	0,                // à
	0,                // á
	0,                // â
	0,                // ã
	0x34,             // ä
	0,                // æ
	0,                // ç
	0,                // è
	0,                // é
	0,                // ê
	0,                // ë
	0,                // ì
	0,                // í
	0,                // î
	0,                // ï
	0,                // eth
	0,                // ñ
	0,                // ò
	0,                // ó
	0,                // ô
	0,                // õ
	0x31,             // ö
	0,                // div
	0,                // ø
	0,                // ù
	0,                // ú
	0,                // û
	0x2f,             // ü
	0,                // ?
	0,                // thorn
	0,                // ÿ
};

uint8_t USBPutChar(uint8_t c);

// press() adds the specified key (iso-8859-1 encoded)
// to the persistent key report and sends the report.  Because of the way 
// USB HID works, the host acts like the key remains pressed until we 
// call release(), releaseAll(), or otherwise clear the report and resend.
size_t Keyboard_::press_iso(uint8_t k) 
{
	uint8_t i;
	k = pgm_read_byte(_asciimap + k);
	if (!k) {
		setWriteError();
		return 0;
	}
	if (k & 0x80) {						// it's a capital letter or other character reached with shift
		_keyReport.modifiers |= 0x02;	// the left shift modifier
		k &= 0x7F;
	}
	if (k & 0x40) {
		_keyReport.modifiers |= 0x40;
		k &= 0x3F;
	}
	if (k == 0x03) { // special case 0x64
		k = 0x64;
	}
	
	// Add k to the key report only if it's not already present
	// and if there is an empty slot.
	if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && 
		_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
		_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
		
		for (i=0; i<6; i++) {
			if (_keyReport.keys[i] == 0x00) {
				_keyReport.keys[i] = k;
				break;
			}
		}
		if (i == 6) {
			setWriteError();
			return 0;
		}	
	}
	sendReport(&_keyReport);
	return 1;
}

// release() takes the specified key out of the persistent key report and
// sends the report.  This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t Keyboard_::release_iso(uint8_t k) 
{
	uint8_t i;
	k = pgm_read_byte(_asciimap + k);
	if (!k) {
		return 0;
	}
	if (k & 0x80) {							// it's a capital letter or other character reached with shift
		_keyReport.modifiers &= ~(0x02);	// the left shift modifier
		k &= 0x7F;
	}
	if (k & 0x40) {
		_keyReport.modifiers &= ~(0x40);
		k &= 0x3F;
	}
	if (k == 0x03) { // special case 0x64
		k = 0x64;
	}
	
	// Test the key report to see if k is present.  Clear it if it exists.
	// Check all positions in case the key is present more than once (which it shouldn't be)
	for (i=0; i<6; i++) {
		if (0 != k && _keyReport.keys[i] == k) {
			_keyReport.keys[i] = 0x00;
		}
	}

	sendReport(&_keyReport);
	return 1;
}

Ahh Danke, muss was missverstanden haben :blush: :slight_smile:

Ich habe die Lösung von pylon umgesetzt und die zwei Dateien HID.cpp und USBAPI.h angepasst (Ich arbeite mit Arduino 1.5.6).
Des weiteren beinhalten die Dateien auch noch die Änderung um die Feststelltaste, Rollen und Numpad Status abzufragen.

Keys sendet man dann (iso-8859-1 encoded) so:

  Keyboard.press_iso(Zeichen);
  delay(1);
  Keyboard.releaseAll();

An dieser Stelle Danke an pylon!

GERMAN_HID.zip (6.62 KB)

Zunächst mal Vielen Dank für deine Mühe.

Da meine Programmierkünste (vorsichtig ausgedrückt) suboptimal sind, hab ich es nicht geschafft die Änderungen aus GERMAN_HID.zip in die 1.6 zu übernehmen.

Ich habe einen diff gegen die Original 1.0.6 gemacht und damit versucht die 1.6 zu patchen.
Dabei weist mir patch den ersten chunk für USBAPI.h zurück.

--- USBAPI.h 2014-09-16 15:42:48.000000000 +0200
+++ USBAPI.h 2014-10-08 19:42:38.000000000 +0200
@@ -25,27 +25,38 @@
 //================================================================================
 // Serial over CDC (Serial1 is the physical port)
 
+struct ring_buffer;
+
+#if (RAMEND < 1000)
+#define SERIAL_BUFFER_SIZE 16
+#else
+#define SERIAL_BUFFER_SIZE 64
+#endif
+
 class Serial_ : public Stream
 {
-private:
- int peek_buffer;
 public:
- Serial_() { peek_buffer = -1; };
 void begin(unsigned long);
 void begin(unsigned long, uint8_t);
 void end(void);
 
 virtual int available(void);
+ virtual void accept(void);
 virtual int peek(void);
 virtual int read(void);
 virtual void flush(void);
 virtual size_t write(uint8_t);
- virtual size_t write(const uint8_t*, size_t);
 using Print::write; // pull in write(str) and write(buf, size) from Print
 operator bool();
+
+ volatile uint8_t _rx_buffer_head;
+ volatile uint8_t _rx_buffer_tail;
+ unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
 };
 extern Serial_ Serial;
 
+#define HAVE_CDCSERIAL
+
 //================================================================================
 //================================================================================
 // Mouse

Hat jemand einen funktionierenden patch oder eine Idee was diesen reject auslöst und wie ich das beheben kann?

-NoGi

Hi,

Ich habe Keyboard Library an Deutsche Layout angepasst.

Alle Umlaute und ß ESZET funktionieren.

Arduino Leonardo USB Keyboard Deutsch library

Und Hier ist Mein Projekt

USB Macro Keypad

Arduino USB Tastatur frei Programmierbar Deutsch selber bauen.
Eine Resistiven Touchscreen Panel mit Papierhintergrund fungiert als macro Keypad / TouchPad.

mischaka:
Hi,

Ich habe Keyboard Library an Deutsche Layout angepasst.

Alle Umlaute und ß ESZET funktionieren.

Du weisst aber schon, dass die Frage vor 7 Jahren gestellt wurde und der TO anscheinend nicht mehr aktiv ist?
Stelle doch dein Projekt lieber in einem neuen Thread vor. z.B. hier: Zeigt her eure geilen Projekte! - Deutsch - Arduino Forum

Vielen dank,
Ich wüste nicht über diesen Thread.