Von Grund auf: Wie ich die Traumtastatur des Entwicklers gebaut habe

Veröffentlicht: 2022-03-11

Als ich eines Tages im August 2007 arbeitete, musste ich feststellen, dass meine normale PC-Tastatur mir nicht so gut wie möglich diente. Ich musste meine Hände exzessiv zwischen den verschiedenen Blöcken meiner Tastatur bewegen, hunderte, wenn nicht tausende Male am Tag, und meine Hände waren unangenehm nahe beieinander. Es muss einen besseren Weg geben, dachte ich.

Auf diese Erkenntnis folgte ein überwältigendes Gefühl der Aufregung, als ich darüber nachdachte, die beste Tastatur für Entwickler anzupassen - und später die Erkenntnis, dass ich als freiberuflicher Embedded-Software-Entwickler hoffnungslos ahnungslos in Sachen Hardware war.

Zu dieser Zeit war ich mit anderen Projekten ziemlich beschäftigt, aber es verging kein Tag, an dem ich nicht daran dachte, das Hacker-Keyboard zu bauen. Bald begann ich, meine Freizeit der Arbeit an dem Projekt zu widmen. Ich habe es geschafft, völlig neue Fähigkeiten zu erlernen, einen Freund von mir, Andras Volgyi, Maschinenbauingenieur der Extraklasse, davon zu überzeugen, sich dem Projekt anzuschließen, einige Schlüsselpersonen zusammenzubringen und genügend Zeit für die Erstellung funktionierender Prototypen aufzuwenden. Heutzutage ist das Ultimate Hacking Keyboard Realität. Wir machen täglich Fortschritte und der Start unserer Crowdfunding-Kampagne ist in greifbarer Nähe.

Ich begann damit, darüber nachzudenken, wie ich das Tastaturlayout ändern könnte, und beendete es damit!

Es ist eine interessante und faszinierende Erfahrung, von einem Softwarehintergrund, der nichts über Elektronik weiß, zum Design und Bau eines leistungsstarken, marktfähigen Hardwaregeräts zu wechseln. In diesem Artikel beschreibe ich das Design, wie dieses elektronische Meisterwerk funktioniert. Ein grundlegendes Verständnis elektronischer Schaltpläne kann Ihnen beim Nachvollziehen helfen.

Wie baut man eine Tastatur?

Nachdem ich diesem Thema Tausende von Stunden meines Lebens gewidmet habe, ist es eine große Herausforderung für mich, eine kurze Antwort zu geben, aber es gibt einen interessanten Weg, diese Frage zu beantworten. Was wäre, wenn wir mit etwas Einfachem wie einem Arduino-Board beginnen und es schrittweise zur ultimativen Hacking-Tastatur ausbauen? Es soll nicht nur bekömmlicher, sondern auch äußerst lehrreich sein. Lassen Sie daher unsere Tastatur-Tutorial-Reise beginnen!

Erster Schritt: Eine Tastatur ohne Tasten

Lassen Sie uns zunächst eine USB-Tastatur erstellen, die das x -Zeichen einmal pro Sekunde ausgibt. Das Arduino Micro-Entwicklungsboard ist ein idealer Kandidat für diesen Zweck, da es den Mikrocontroller ATmega32U4 enthält – einen AVR-Mikrocrontroller und den gleichen Prozessor, der das Gehirn des UHK ist.

Das Arduino Micro Board war die Grundlage für den Bau meiner Tastatur für Entwickler.

Wenn es um USB-fähige AVR-Mikrocontroller geht, ist das Lightweight USB Framework for AVRs (LUFA) die Bibliothek der Wahl. Es ermöglicht diesen Prozessoren, das Gehirn von Druckern, MIDI-Geräten, Keyboards oder fast jeder anderen Art von USB-Gerät zu werden.

Beim Anschließen eines Geräts an den USB-Anschluss muss das Gerät einige spezielle Datenstrukturen übertragen, die als USB-Deskriptoren bezeichnet werden. Diese Deskriptoren teilen dem Host-Computer den Typ und die Eigenschaften des angeschlossenen Geräts mit und werden durch eine Baumstruktur dargestellt. Um die Sache noch komplexer zu machen, kann ein Gerät nicht nur eine, sondern mehrere Funktionen implementieren. Sehen wir uns die Deskriptorenstruktur des UHK an:

  • Gerätebeschreibung
    • Konfigurationsdeskriptor
      • Schnittstellendeskriptor 0: GenericHID
        • Endpunktdeskriptor
      • Schnittstellenbeschreibung 1: Tastatur
        • Endpunktdeskriptor
      • Schnittstellendeskriptor 2: Maus
        • Endpunktdeskriptor

Die meisten Standardtastaturen stellen nur einen einzigen Tastaturschnittstellendeskriptor bereit, was sinnvoll ist. Als benutzerdefinierte Programmiertastatur stellt das UHK jedoch auch einen Mausschnittstellendeskriptor bereit, da der Benutzer beliebige Tasten der Tastatur programmieren kann, um den Mauszeiger zu steuern, sodass die Tastatur als Maus verwendet werden kann. Die GenericHID-Schnittstelle dient als Kommunikationskanal, um Konfigurationsinformationen für alle speziellen Funktionen der Tastatur auszutauschen. Die vollständige Implementierung der Geräte- und Konfigurationsdeskriptoren des UHK in LUFA können Sie hier einsehen.

Nachdem wir die Deskriptoren erstellt haben, ist es an der Zeit, das x -Zeichen jede Sekunde zu senden.

 uint8_t isSecondElapsed = 0; int main(void) { while (1) { _delay_us(1000); isSecondElapsed = 1; } } bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize) { USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; if (isSecondElapsed) { KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_X; isSecondElapsed = 0; } *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; }

USB ist ein abgefragtes Protokoll, was bedeutet, dass der Host-Computer das Gerät in regelmäßigen Abständen (normalerweise 125 Mal pro Sekunde) abfragt, um herauszufinden, ob neue Daten zu senden sind. Der relevante Callback ist die Funktion CALLBACK_HID_Device_CreateHIDReport() , die in diesem Fall immer dann den Scancode des x -Zeichens an den Host sendet, wenn die Variable isSecondElapsed 1 enthält. isSecondElapsed wird sekündlich von der Hauptschleife auf 1 und vom Callback auf 0 gesetzt.

Schritt Zwei: Eine Tastatur mit vier Tasten

An dieser Stelle ist unsere Tastatur nicht besonders nützlich. Es wäre schön, wenn wir tatsächlich darauf tippen könnten. Aber dafür brauchen wir Tasten, und die Tasten müssen in einer Tastaturmatrix angeordnet werden. Eine Tastatur mit 104 Tasten in voller Größe könnte 18 Zeilen und 6 Spalten haben, aber wir haben einfach eine bescheidene 2x2-Tastaturmatrix zum Starten. Dies ist das Schema:

Um eine Hacker-Tastatur anzupassen, müssen Sie die Tastenmatrix sorgfältig berücksichtigen.

Und so sieht es auf einem Steckbrett aus:

Das Konfigurieren des Steckbretts ist ein entscheidender Schritt beim Erstellen einer Tastatur für Entwickler.

Unter der Annahme, dass ROW1 mit PINA0 , ROW2 mit PINA1 , COL1 mit PORTB0 und COL2 mit PORTB1 verbunden ist, sieht der Scan-Code so aus:

 /* A single pin of the microcontroller to which a row or column is connected. */ typedef struct { volatile uint8_t *Direction; volatile uint8_t *Name; uint8_t Number; } Pin_t; /* This part of the key matrix is stored in the Flash to save SRAM space. */ typedef struct { const uint8_t ColNum; const uint8_t RowNum; const Pin_t *ColPorts; const Pin_t *RowPins; } KeyMatrixInfo_t; /* This Part of the key matrix is stored in the SRAM. */ typedef struct { const __flash KeyMatrixInfo_t *Info; uint8_t *Matrix; } KeyMatrix_t; const __flash KeyMatrixInfo_t KeyMatrix = { .ColNum = 2, .RowNum = 2, .RowPins = (Pin_t[]) { { .Direction=&DDRA, .Name=&PINA, .Number=PINA0 }, { .Direction=&DDRA, .Name=&PINA, .Number=PINA1 } }, .ColPorts = (Pin_t[]) { { .Direction=&DDRB, .Name=&PORTB, .Number=PORTB0 }, { .Direction=&DDRB, .Name=&PORTB, .Number=PORTB1 }, } }; void KeyMatrix_Scan(KeyMatrix_t *KeyMatrix) { for (uint8_t Col=0; Col<KeyMatrix->Info->ColNum; Col++) { const Pin_t *ColPort = KeyMatrix->Info->ColPorts + Col; for (uint8_t Row=0; Row<KeyMatrix->Info->RowNum; Row++) { const Pin_t *RowPin = KeyMatrix->Info->RowPins + Row; uint8_t IsKeyPressed = *RowPin->Name & 1<<RowPin->Number; KeyMatrix_SetElement(KeyMatrix, Row, Col, IsKeyPressed); } } }

Der Code scannt jeweils eine Spalte und liest innerhalb dieser Spalte die Zustände der einzelnen Schlüsselschalter. Der Zustand der Schlüsselschalter wird dann in einem Array gespeichert. Innerhalb unserer vorherigen Funktion CALLBACK_HID_Device_CreateHIDReport() werden dann die relevanten Scancodes basierend auf dem Status dieses Arrays gesendet.

Schritt drei: Eine Tastatur mit zwei Hälften

Bisher haben wir die Anfänge einer normalen Tastatur geschaffen. Aber in diesem Tastatur-Tutorial zielen wir auf fortgeschrittene Ergonomie ab, und da die Leute zwei Hände haben, fügen wir der Mischung besser eine weitere Tastaturhälfte hinzu.

Die andere Hälfte enthält eine andere Tastaturmatrix, die auf die gleiche Weise wie die vorherige funktioniert. Das spannende Neue ist die Kommunikation zwischen den Tastaturhälften. Die drei beliebtesten Protokolle zur Verbindung elektronischer Geräte sind SPI, I 2 C und UART. Aus praktischen Gründen werden wir in diesem Fall UART verwenden.

Um eine gute Programmiertastatur zu sein, muss zwischen beiden Hälften eine hervorragende Kommunikation bestehen.

Die bidirektionale Kommunikation fließt gemäß dem obigen Diagramm durch RX nach rechts und durch TX nach links. VCC und GND sind notwendig, um Strom zu übertragen. UART erfordert, dass die Peers dieselbe Baudrate, Anzahl von Datenbits und Anzahl von Stoppbits verwenden. Sobald der UART-Transceiver beider Peers eingerichtet ist, kann die Kommunikation beginnen zu fließen.

Im Moment sendet die linke Tastaturhälfte über UART Ein-Byte-Nachrichten an die rechte Tastaturhälfte, die Tastendruck- oder Tastenfreigabeereignisse darstellen. Die rechte Tastaturhälfte verarbeitet diese Nachrichten und manipuliert den Zustand des gesamten Tastaturmatrixarrays im Speicher entsprechend. So sendet die linke Tastaturhälfte Nachrichten:

 USART_SendByte(IsKeyPressed<<7 | Row*COLS_NUM + Col);

Der Code für die rechte Tastaturhälfte zum Empfangen der Nachricht sieht folgendermaßen aus:

 void KeyboardRxCallback(void) { uint8_t Event = USART_ReceiveByte(); if (!MessageBuffer_IsFull(&KeyStateBuffer)) { MessageBuffer_Insert(&KeyStateBuffer, Event); } }

Der Interrupt-Handler KeyboardRxCallback() wird ausgelöst, wenn ein Byte über UART empfangen wird. Da Interrupt-Handler so schnell wie möglich ausgeführt werden sollten, wird die empfangene Nachricht zur späteren Verarbeitung in einen Ringpuffer gestellt. Der Ringpuffer wird schließlich innerhalb der Hauptschleife verarbeitet und die Tastaturmatrix wird basierend auf der Nachricht aktualisiert.

Das obige ist der einfachste Weg, dies zu erreichen, aber das endgültige Protokoll wird etwas komplexer sein. Es müssen Multi-Byte-Nachrichten behandelt werden, und die einzelnen Nachrichten müssen anhand von CRC-CCITT-Prüfsummen auf Integrität geprüft werden.

An diesem Punkt sieht unser Steckbrett-Prototyp ziemlich beeindruckend aus:

Der Breadboard-Prototyp nimmt allmählich die Form einer kundenspezifischen Tastatur für Entwickler an.

Schritt vier: Lernen Sie die LED-Anzeige kennen

Eines unserer Ziele mit dem UHK war es, dem Benutzer zu ermöglichen, mehrere anwendungsspezifische Tastaturbelegungen zu definieren, um die Produktivität weiter zu steigern. Der Benutzer braucht eine Möglichkeit, sich der tatsächlich verwendeten Tastenbelegung bewusst zu sein, daher ist eine integrierte LED-Anzeige in die Tastatur eingebaut. Hier ist ein Prototyp-Display, bei dem alle LEDs leuchten:

Die LED-Anzeige ist von zentraler Bedeutung für den Aufbau der besten Tastatur für Entwickler in diesem Tutorial.

Die LED-Anzeige wird durch eine 8x6 LED-Matrix realisiert:

Hacker-Tastaturen wären ohne eine 8x6-LED-Matrix nicht vollständig.

Alle zwei Reihen roter LED-Symbole repräsentieren die Segmente einer der 14-Segment-LED-Anzeigen. Die weißen LED-Symbole repräsentieren die drei zusätzlichen Statusanzeigen.

Um Strom durch eine LED zu treiben und sie zum Leuchten zu bringen, wird die entsprechende Spalte auf Hochspannung und die entsprechende Zeile auf Niederspannung gesetzt. Eine interessante Konsequenz dieses Systems besteht darin, dass zu jedem Zeitpunkt nur eine Spalte aktiviert werden kann (alle LEDs in dieser Spalte, die leuchten sollten, haben ihre entsprechenden Zeilen auf niedrige Spannung gesetzt), während die restlichen Spalten deaktiviert sind . Man könnte denken, dass dieses System nicht funktionieren kann, um den vollen LED-Satz zu nutzen, aber in Wirklichkeit werden die Spalten und Zeilen so schnell aktualisiert, dass das menschliche Auge kein Flackern erkennen kann.

Die LED-Matrix wird von zwei integrierten Schaltkreisen (ICs) angesteuert, von denen einer seine Zeilen und der andere seine Spalten antreibt. Der Quell-IC, der die Spalten antreibt, ist der PCA9634 I2C LED-Treiber:

Zwei integrierte Schaltkreise treiben die LED-Matrix auf dem Ultimate Hacker Keyboard an.

Der LED-Matrix-Senken-IC, der die Zeilen ansteuert, ist das Leistungsschieberegister TPIC6C595:

Der IC, der die LED-Reihen antreibt, sieht so aus.

Sehen wir uns den relevanten Code an:

 uint8_t LedStates[LED_MATRIX_ROWS_NUM]; void LedMatrix_UpdateNextRow(bool IsKeyboardColEnabled) { TPIC6C595_Transmit(LedStates[ActiveLedMatrixRow]); PCA9634_Transmit(1 << ActiveLedMatrixRow); if (++ActiveLedMatrixRow == LED_MATRIX_ROWS_NUM) { ActiveLedMatrixRow = 0; } }

LedMatrix_UpdateNextRow() wird etwa jede Millisekunde aufgerufen und aktualisiert eine Reihe der LED-Matrix. Das LedStates Array speichert den Status der einzelnen LEDs und wird über UART basierend auf Nachrichten aktualisiert, die von der rechten Tastaturhälfte stammen, ziemlich genau so wie im Fall des Tastendruck-/Tastenloslass-Ereignisses.

Das große Bild

Inzwischen haben wir nach und nach alle notwendigen Komponenten für unsere individuelle Hacker-Tastatur aufgebaut, und es ist Zeit, das große Ganze zu sehen. Das Innere der Tastatur ist wie ein Mini-Computernetzwerk: viele miteinander verbundene Knoten. Der Unterschied besteht darin, dass die Entfernung zwischen den Knoten nicht in Metern oder Kilometern, sondern in Zentimetern gemessen wird und die Knoten keine vollwertigen Computer, sondern winzige integrierte Schaltkreise sind.

Das Innere unserer Tutorial-Tastatur besteht aus miteinander verbundenen Knoten.

Viel wurde bisher über die geräteseitigen Details der Entwicklertastatur gesagt, nicht so sehr aber über UHK Agent, die hostseitige Software. Der Grund dafür ist, dass Agent im Gegensatz zu Hardware und Firmware zu diesem Zeitpunkt sehr rudimentär ist. Es wird jedoch über die High-Level-Architektur von Agent entschieden, die ich gerne teilen möchte.

UHK Agent ist die Konfigurator-Anwendung, mit der die Tastatur an die Bedürfnisse des Benutzers angepasst werden kann. Obwohl es sich um einen Rich-Client handelt, verwendet Agent Webtechnologien und läuft auf der Node-Webkit-Plattform.

Der Agent kommuniziert mit der Tastatur über die Node-USB-Bibliothek, indem er spezielle, gerätespezifische USB-Steuerungsanforderungen sendet und deren Ergebnisse verarbeitet. Es verwendet Express.js, um eine REST-API für die Nutzung durch Anwendungen von Drittanbietern verfügbar zu machen. Es verwendet auch Angular.js, um eine übersichtliche Benutzeroberfläche bereitzustellen.

 var enumerationModes = { 'keyboard' : 0, 'bootloader-right' : 1, 'bootloader-left' : 2 }; function sendReenumerateCommand(enumerationMode, callback) { var AGENT_COMMAND_REENUMERATE = 0; sendAgentCommand(AGENT_COMMAND_REENUMERATE, enumerationMode, callback); } function sendAgentCommand(command, arg, callback) { setReport(new Buffer([command, arg]), callback); } function setReport(message, callback) { device.controlTransfer( 0x21, // bmRequestType (constant for this control request) 0x09, // bmRequest (constant for this control request) 0, // wValue (MSB is report type, LSB is report number) interfaceNumber, // wIndex (interface number) message, // message to be sent callback ); }

Jeder Befehl hat eine 8-Bit-Kennung und einen Satz befehlsspezifischer Argumente. Derzeit ist nur der Re-Enumerate-Befehl implementiert. Der sendReenumerateCommand() , dass das Gerät als linker Bootloader oder rechter Bootloader neu aufgezählt wird, um die Firmware zu aktualisieren, oder als Tastaturgerät.

Man hat vielleicht keine Ahnung von den erweiterten Funktionen, die mit dieser Software erreicht werden können, also nenne ich einige: Der Agent wird in der Lage sein, die Abnutzung der einzelnen Schlüssel zu visualisieren und den Benutzer über ihre Lebenserwartung zu informieren, so dass der Benutzer es könnte Kaufen Sie ein paar neue Schlüsselschalter für die bevorstehende Reparatur. Der Agent bietet auch eine Benutzeroberfläche zum Konfigurieren der verschiedenen Tastenbelegungen und Ebenen der Hacker-Tastatur. Die Geschwindigkeit und Beschleunigung des Mauszeigers sowie viele andere Uber-Funktionen können ebenfalls eingestellt werden. Der Himmel ist das Limit.

Erstellen des Prototyps

Es wird viel Arbeit in die Erstellung von benutzerdefinierten Tastaturprototypen gesteckt. Zunächst muss das mechanische Design fertiggestellt werden, das an sich schon ziemlich komplex ist und kundenspezifische Kunststoffteile, lasergeschnittene Edelstahlplatten, präzisionsgefräste Stahlführungen und Neodym-Magnete umfasst, die die beiden Tastaturhälften zusammenhalten. Alles wird im CAD konstruiert, bevor die Fertigung beginnt.

Die CAD-Zeichnung hilft beim Bau einer Tastatur, die für Entwickler gut funktioniert.

So sieht die 3D-gedruckte Tastaturhülle aus:

Wir begannen mit dem 3D-Druck des Gehäuses der Programmiertastatur.

Basierend auf dem mechanischen Design und dem Schaltplan muss die Leiterplatte entworfen werden. Die rechte Platine sieht in KiCad so aus:

Die Programmierung einer Tastatur beginnt mit dem Entwurf einer Leiterplatte.

Dann wird die Leiterplatte konfektioniert und die oberflächenmontierten Komponenten müssen von Hand gelötet werden:

Das Löten der benutzerdefinierten Tastaturkomponenten stellt sicher, dass sie ordnungsgemäß funktioniert, sobald sie sich im Gehäuse befindet.

Nachdem wir schließlich alle Teile hergestellt haben, einschließlich 3D-Druck, Polieren und Lackieren der Kunststoffteile und alles zusammengebaut haben, haben wir am Ende einen funktionierenden Hacker-Tastatur-Prototyp wie diesen:

Fazit

Ich vergleiche die Keyboards von Entwicklern gerne mit den Instrumenten von Musikern. Tastaturen sind ziemlich intime Objekte, wenn man darüber nachdenkt. Schließlich verwenden wir sie den ganzen Tag, um die Software von morgen zu erstellen, Zeichen für Zeichen.

Wahrscheinlich aus diesem Grund halte ich die Entwicklung des Ultimate Hacking Keyboard für ein Privileg, und trotz aller Schwierigkeiten war es meistens eine sehr aufregende Reise und eine unglaublich intensive Lernerfahrung.

Dies ist ein weites Thema, und ich konnte hier nur an der Oberfläche kratzen. Ich hoffe, dass dieser Artikel viel Spaß gemacht hat und voller interessantem Material ist. Wenn Sie Fragen haben, lassen Sie es mich bitte in den Kommentaren wissen.

Zu guter Letzt können Sie gerne https://ultimatehackingkeyboard.com besuchen, um weitere Informationen zu erhalten, und sich dort anmelden, um über den Start unserer Kampagne benachrichtigt zu werden.