virtuelles USB-Keyboard mit Keypad (Matrix)

vor 1 year 34 weeks von y.o.r.k

Mein aktuelles Projekt soll folgendes können:

Ich möchte ein Handheld für meine CNC-Maschine realisieren. Das Steuerprogramm unterstützt leider keinen Handbedienteil und Shortcuts für Funktionen sind hier leider Mangelware. Mein Gerät soll dann z.B. bei einem Tastendruck eine "Alt + A + U"-Sequenz senden um eine Funktion auszuführen. Das funktioniert ja prinzipiell schon.
Ausgangsbasis ist: http://www.practicalarduino.com/projects/virtual-usb-keyboard
Soweit habe ich mich in die USB-Keyboard-Bibliothek schon eingearbeitet, dass ich die um die fehlenden Tasten ergänzen kann.

Jetzt brauch ich aber mehr Tasten als mein Freeduino anbietet, daher will ich das mit einer KeyPad-Matrix lösen.
Hier ist meine Quelle das mitgelieferte Beispiel "Custom Keypad bzw. Dynamic Keypad"

Den Code versuchte ich zu erweitern, aber irgendwie werden meine Matrixdaten (für Testzwecke auf 2x2 abgespeckt) nicht ausgewertet.
Die "Extra Schalter" sind hier nur als Test noch im Code zu finden- Funktionieren die, kann ich sehen ob das Keyboard vom Windows-System erkannt wird. Die "delayMs(80);" sollen dem Prellen der Taster entgegenwirken, ist aber auch noch nicht das gelbe vom Ei ;(
Kann mir hier jemand sagen was da im Code nicht stimmt? Als absoluter Newbie finde ich den Fehler nicht.

 
#include <Keypad.h>
#include "UsbKeyboard.h"
// Extra Schalter
#define BUTTON_ENTER 8
#define BUTTON_RED 9
#define BUTTON_BLUE 10
 
// DEfinition der Matrix
const byte ROWS = 2; 
const byte COLS = 2; 
char hexaKeys[ROWS][COLS] = {
  {'A','B'},
  {'C','D'},
};
byte rowPins[ROWS] = {11, 12}; 
byte colPins[COLS] = {6, 7}; 
 
Keypad cusomKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
 
// LED für Extra Schalter
int ledPin = 3;
 
 
void setup()
{
  Serial.begin(9600);  
  // Initialisieren der LED
  pinMode (ledPin, OUTPUT);
  digitalWrite (ledPin, HIGH);
 
  pinMode (BUTTON_RED, INPUT);
  pinMode (BUTTON_BLUE, INPUT);
  pinMode (BUTTON_ENTER, INPUT);
 
  // aktiviert die internen PullUp
  digitalWrite (BUTTON_RED, HIGH);
  digitalWrite (BUTTON_BLUE, HIGH);
  digitalWrite (BUTTON_ENTER, HIGH); 
 
  // Disable timer0 since it can mess with the USB timing. Note that
  // this means some functions such as delay() will no longer work.
  TIMSK0&=!(1<<TOIE0);
 
  // Clear interrupts while performing time-critical operations
  cli();
 
  // Force re-enumeration so the host will detect us
  usbDeviceDisconnect();
  delayMs(250);
  usbDeviceConnect();
 
  // Set interrupts again
  sei();
}
 
 
/**
 * Main program loop. Scan for keypresses and send a matching keypress
 * event to the host
 * FIXME: currently repeats as fast as it can. Add transition detection
 */
void loop()
{
  
  // Einlesen der Matrix und serielle Ausgabe des Ergebnisses
  char customKey = cusomKeypad.getKey();
  
  if (customKey != NO_KEY){
    Serial.println(customKey);
  }
  // Einlesen der Extraschalter 
  UsbKeyboard.update();
 
  if (digitalRead(BUTTON_RED) == LOW) {
    delayMs(80);
    UsbKeyboard.sendKeyStroke(KEY_R);
    digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle status LED
  }
 
 
   if (digitalRead(BUTTON_BLUE) == LOW) {
    UsbKeyboard.sendKeyStroke(KEY_H, MOD_SHIFT_LEFT);
    UsbKeyboard.sendKeyStroke(KEY_E);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_O);
    UsbKeyboard.sendKeyStroke(KEY_SPACE);
    UsbKeyboard.sendKeyStroke(KEY_W, MOD_SHIFT_LEFT);
    UsbKeyboard.sendKeyStroke(KEY_O);
    UsbKeyboard.sendKeyStroke(KEY_R);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_D);
    UsbKeyboard.sendKeyStroke(KEY_ENTER);
    digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle status LED
  }
 
  if (digitalRead(BUTTON_ENTER) == LOW) {
    delayMs(80);
    UsbKeyboard.sendKeyStroke(KEY_E);
    digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle status LED
  }
  
  
}
 
 
/**
 * Define our own delay function so that we don't have to rely on
 * operation of timer0, the interrupt used by the internal delay()
 */
void delayMs(unsigned int ms)
{
  for (int i = ; i < ms; i++) {
    delayMicroseconds(1000);
  }
}

Ähnliche Posts

3 Antworten auf “virtuelles USB-Keyboard mit Keypad (Matrix)”


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
  1. y.o.r.k sagt:

    was macht eigentlich diese Zeile genau?

    TIMSK0&=!(1<<TOIE0);

    wenn ich die entferne, cli() und sei() ebenfalls, dann funktioniert das mit der Matrix. Allerdings funktioniert dann das USB-Keyboard nicht mehr.

    Login or register to post comments

  1. chrimbo sagt:

    Die schaltet den Timer ab.
    Ich hab mal nachgeschaut, die Library für das Keypad verwendet millis() ich bin mir nicht sicher, aber wahrscheinlich verwendet millis() den Timer und kehrt deshalb nicht zurück.
    Du könntest probieren, immer kurz bevor du etwas über USB senden willst den Timer abzuschalten und danach wieder einzuschalten. Ich würde dazu zuerst das Register sichern.
    zb.

    int timerconfig = TIMSK0;
    ...
    TIMSK0&=!(1<<TOIE0);
    USB SENDEN....
    TIMSK0 = timerconfig;
    ...

    und so weiter :) aber wie gesagt, bin mir nicht sicher. Good Luck!

    Login or register to post comments

  1. y.o.r.k sagt:

    thx, aber ich glaub ich habe das Problem gelöst. Wenn ich ein paar Tests gemacht habe dann stell ich den neuen Code hier rein.

    Ich habe in den Weiten des WWW eine Keypad-Matrix ohne Bibliothek gefunden, das dürfte jetzt mit dem USB-Keyboard zusammen spielen.

    aber ich werde mir das mit dem Timer auf jeden Fall auch ansehen.

    wenn denn nicht alles immer so zeitaufwändig wär ;(

    Login or register to post comments