Seeeduino XIAOで自作キーボード

2021/05/05 categories:3D Printer| tags:3D Printer|DIY Keyboard|

Seeeduino XIAOを使ってUSB type-cの自作キーボードを作ってみました。

USB type-cで接続したいと思ったので、マイコンボードはUSB type-cが実装されているSeeeduino XIAOを使用しました。接続は以下の通りです。

キーマトリクスの読み取り方法

以下の図のように、1列のみLOWレベル出力にして、1行ずつdigitalReadでキーの状態を読み取っていきます。

3Dモデル

アセンブリのSTEPファイル

  • NUMERIC_KEYPAD.step
  • STLファイル

    動画

    ソースコード

    #include "Adafruit_TinyUSB.h"
    
    Adafruit_USBD_HID usb_hid;
    
    #define KEY_NUMLOCK 0x53    // Keyboard Num Lock and Clear
    #define KEY_KPSLASH 0x54    // Keypad /
    #define KEY_KPASTERISK 0x55 // Keypad *
    #define KEY_KPMINUS 0x56    // Keypad -
    #define KEY_KPPLUS 0x57     // Keypad +
    #define KEY_KPENTER 0x58    // Keypad ENTER
    #define KEY_KP1 0x59        // Keypad 1 and End
    #define KEY_KP2 0x5a        // Keypad 2 and Down Arrow
    #define KEY_KP3 0x5b        // Keypad 3 and PageDn
    #define KEY_KP4 0x5c        // Keypad 4 and Left Arrow
    #define KEY_KP5 0x5d        // Keypad 5
    #define KEY_KP6 0x5e        // Keypad 6 and Right Arrow
    #define KEY_KP7 0x5f        // Keypad 7 and Home
    #define KEY_KP8 0x60        // Keypad 8 and Up Arrow
    #define KEY_KP9 0x61        // Keypad 9 and Page Up
    #define KEY_KP0 0x62        // Keypad 0 and Insert
    #define KEY_KPDOT 0x63      // Keypad . and Delete
    
    //uint8_t pressedKeys[16];
    
    const uint8_t keyMatrix[16] = {
      KEY_KPMINUS, KEY_KPASTERISK, KEY_KPSLASH, KEY_NUMLOCK,
      KEY_KPPLUS, KEY_KP9, KEY_KP8, KEY_KP7,
      KEY_KPENTER, KEY_KP6, KEY_KP5, KEY_KP4,
      KEY_KP0, KEY_KP3, KEY_KP2, KEY_KP1
    };
    
    const uint8_t columnPins[4] = {0, 1, 2, 3};
    const uint8_t rowOutPuts[4][4] = {
      { LOW, HIGH, HIGH, HIGH},
      {HIGH,  LOW, HIGH, HIGH},
      {HIGH, HIGH,  LOW, HIGH},
      {HIGH, HIGH, HIGH,  LOW}
    };
    
    const int row0 = 4;
    const int row1 = 5;
    const int row2 = 6;
    const int row3 = 7;
    
    uint8_t const desc_hid_report[] =
    {
      TUD_HID_REPORT_DESC_KEYBOARD(),
    };
    
    void setup() {
      pinMode(columnPins[0], INPUT);
      pinMode(columnPins[1], INPUT);
      pinMode(columnPins[2], INPUT);
      pinMode(columnPins[3], INPUT);
      
      digitalWrite(columnPins[0], HIGH);
      digitalWrite(columnPins[1], HIGH);
      digitalWrite(columnPins[2], HIGH);
      digitalWrite(columnPins[3], HIGH);
    
      pinMode(row0, OUTPUT);
      pinMode(row1, OUTPUT);
      pinMode(row2, OUTPUT);
      pinMode(row3, OUTPUT);
    
      usb_hid.setPollInterval(2);
      usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
      usb_hid.begin();
    
      while( !USBDevice.mounted() ) delay(1);
    }
    
    void loop() {
    
      delay(2);
    
      if ( !usb_hid.ready() ) return;
    
      static bool keyPressedPreviously = false;
      bool anyKeyPressed = false;
      uint8_t count = 0;
      uint8_t keycode[6] = { 0 };
    
      for (uint8_t row=0; row<4; row++) 
      {
        digitalWrite(row0, rowOutPuts[row][0]);
        digitalWrite(row1, rowOutPuts[row][1]);
        digitalWrite(row2, rowOutPuts[row][2]);
        digitalWrite(row3, rowOutPuts[row][3]);
    
        for (uint8_t column=0; column<4; column++) 
        {
          if (digitalRead(columnPins[column]) == 0)
          {
            keycode[count++] = keyMatrix[ row * 4 + column ];
            
            if (count == 6)
            {
              usb_hid.keyboardReport(0, 0, keycode);
              delay(2);
    
              count = 0;
              memset(keycode, 0, 6);
            }
            
            anyKeyPressed = true;
            keyPressedPreviously = true;
          }
        }
      }
    
      if ( count )
      {
        usb_hid.keyboardReport(0, 0, keycode);
      }
      
      if ( !anyKeyPressed && keyPressedPreviously )
      {
        keyPressedPreviously = false;
        usb_hid.keyboardRelease(0);
      }
    }

    Share post

    Related Posts

    Comments

    comments powered by Disqus