- //(1)シリアルLEDライブラリ(配布先 https://github.com/adafruit/Adafruit_NeoPixel)
- #include <Adafruit_NeoPixel.h>
- //(2)Arduino HID Project 2.4.4(配布先 https://github.com/NicoHood/HID#arduino-hid-project-244)
- #include <HID-Project.h>
- #include <HID-Settings.h>
- //キーコード指定
- #define C_SHIFT 0x1000 // SHIFT+ 指定コード
- #define C_MEDIA 0x2000 // メディアキー(コンシューマー機能用)
- #define KC_CALC (C_MEDIA | 0x1 ) // 電卓キー
- #define KC_SHIFT 0xe1 // 左 SHIFT
- #define KC_DOT 0x63 // Keypad [.]
- #define KC_P0 0x62 // Keypad [0]
- #define KC_P9 0x61 // Keypad [9]
- #define KC_P8 0x60 // Keypad [8]
- #define KC_P7 0x5f // Keypad [7]
- #define KC_P6 0x5e // Keypad [6]
- #define KC_P5 0x5d // Keypad [5]
- #define KC_P4 0x5c // Keypad [4]
- #define KC_P3 0x5b // Keypad [3]
- #define KC_P2 0x5a // Keypad [2]
- #define KC_P1 0x59 // Keypad [1]
- #define KC_ENTER 0x58 // Keypad [Enter]
- #define KC_PLUS 0x57 // Keypad [+]
- #define KC_MINS 0x56 // Keypad [-]
- #define KC_ASTR 0x55 // Keypad [*]
- #define KC_DIV 0x54 // Keypad [/]
- #define KC_NUML 0x53 // [NUM LOCK]
- #define KC_COMMA 0x36 // Keyboard [,]
- #define KC_EQL (C_SHIFT | 0x2d) // Keyboard [=] ([SHIFT]+[-])
- #define KC_BS 0x2a // [BACK SPACE]
- #define KC_ESC 0x29 // [ESC]
- #define KC_9 (C_SHIFT | 0x26) // Keyboard [)] ([SHIFT]+[9])
- #define KC_8 (C_SHIFT | 0x25) // Keyboard [(] ([SHIFT]+[8])
- //KEY SCAN用 I/O定義
- #define ROW_NUM 7
- #define COL_NUM 4
- const int rowPins[ROW_NUM] = { 2, 3, 4, 5, 6, 7, 8 }; // OUTPUT指定
- const int colPins[COL_NUM] = { 9, 10, 16, 14 }; // INPUT_PULLUP指定
- //KEY MAP定義(JISコード)
- const unsigned int keyMap[ROW_NUM][COL_NUM] = {
- { KC_NUML , KC_NUML , KC_NUML , KC_NUML }, //MODEキーはダミー
- { KC_NUML , KC_CALC , KC_ESC , KC_BS }, //NML CALC ESC BS
- { KC_8 , KC_9 , KC_MINS , KC_DIV }, // ( ) - /
- { KC_P7 , KC_P8 , KC_P9 , KC_ASTR }, // 7 8 9 *
- { KC_P4 , KC_P5 , KC_P6 , KC_PLUS }, // 4 5 6 +
- { KC_P1 , KC_P2 , KC_P3 , KC_EQL }, // 1 2 3 =
- { KC_P0 , KC_COMMA , KC_DOT , KC_ENTER } // 0 , . RET
- };
- //LED制御用 I/O定義
- #define NUMPIXELS 1 // シリアルLED個数
- #define NUM_LOCK_LED 21 // NumLock/動作モード状態LEDポート番号
- //シリアルLED定義
- // D2812 = NEO_RGB
- // WS2812B = NEO_GRB
- Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NUM_LOCK_LED, NEO_GRB + NEO_KHZ800); //NumLock LED制御Pin初期化
- //NumLock・LED制御
- int R[3]; // LED色 Red (0-255)
- int G[3]; // LED色 Green(0-255)
- int B[3]; // LED色 Blue (0-255)
- //KEY状態制御用配列定義
- //KEY状態を前回と最新状態で比較して、変化があった場合にキーコードを送信する
- bool cur_key_sts[ROW_NUM][COL_NUM]; //最新のKEY状態
- bool old_key_sts[ROW_NUM][COL_NUM]; //前回のKEY状態
- void setup()
- {
- // put your setup code here, to run once:
- //キースキャン行のPinを初期化する
- for (int i = 0; i < ROW_NUM; i++)
- {
- pinMode(rowPins[i], OUTPUT);
- }
- //キースキャン列のPinを初期化する
- for (int i = 0; i < COL_NUM; i++)
- {
- pinMode(colPins[i], INPUT_PULLUP);
- }
- //キー状態を初期化する
- for (int row = 0; row < ROW_NUM; row++)
- {
- //キー状態を「リリース」とする
- for (int c = 0; c < COL_NUM; c++)
- {
- cur_key_sts[row][c] = HIGH;
- old_key_sts[row][c] = HIGH;
- }
- //キースキャン行のPinをHIGH(inactive)にする
- digitalWrite(rowPins[row], HIGH);
- }
- //LED表示初期化(各動作モード別にRGBで色指定する)
- //色1=緑
- R[0]=0;
- G[0]=10;
- B[0]=0;
- //シリアルLEDライブラリ初期化
- pixels.begin();
- //HIDデバイス初期化(ホストLED状態取得用)
- BootKeyboard.begin();
- //コンシューマー機能初期化
- Consumer.begin();
- }
- void loop()
- {
- // put your main code here, to run repeatedly:
- static int mode = 0;//色変更用
- //キー押下状態変化なしとする(フラグ初期化)
- int chg = 0; //通常キー
- int media = 0; //メディアキー
- // key matrix scan
- for (int row = 0; row < ROW_NUM; row++)
- {
- // 行指定:キースキャン開始(LOW出力)
- digitalWrite(rowPins[row], LOW);
- for (int col = 0; col < COL_NUM; col++)
- {
- // 列指定:キー状態読み出し(押下:LOW)
- cur_key_sts[row][col] = digitalRead(colPins[col]);
- // 前回の状態と変化あり?
- if (cur_key_sts[row][col] != old_key_sts[row][col])
- {
- //「キー押下状態変化あり」とする
- chg = 1;
-
- //キーコードをマップから取得
- unsigned int key_code = keyMap[row][col];
-
- // キーが押下されている?
- if (cur_key_sts[row][col] == LOW)
- {
- //メディアキー指定?
- if(key_code & C_MEDIA)
- {
- //メディアキー押下ありとする。
- media = 1;
- }
- else
- {
- //SHIFT+同時押し指定?
- if(key_code & C_SHIFT)
- {
- // SHIFTキー押下
- BootKeyboard.add(KeyboardKeycode(KC_SHIFT));
- }
- // キーコード追加(押下)
- BootKeyboard.add(KeyboardKeycode(key_code&0xff));
- }
- }
- else
- {
- //メディアキー指定?
- if(key_code & C_MEDIA)
- {
- //メディアキーリリース時は何もしない
- ;
- }
- else
- {
- // キーコード削除(リリース)
- BootKeyboard.remove(KeyboardKeycode(key_code&0xff));
- //SHIFT+同時押し指定?
- if(key_code & C_SHIFT)
- {
- // SHIFTキーリリース
- BootKeyboard.remove(KeyboardKeycode(KC_SHIFT));
- }
- }
- }
- //現在のキー状態を前回の状態にコピーする
- old_key_sts[row][col] = cur_key_sts[row][col];
- }
- }
- // 行指定:キースキャン終了(HIGHに戻す)
- digitalWrite(rowPins[row], HIGH);
- }
- //メディアキー押下あり?
- if( media==1 )
- {
- //電卓キーを送信する
- Consumer.write(ConsumerKeycode(CONSUMER_CALCULATOR));
- }
- //キー押下状態変化あり?
- if ( chg == 1 )
- {
- //ホスト側に変化したキーコードを送信する
- BootKeyboard.send();
- }
- //ホスト側のLED状態を取得
- int cur_led_sts = BootKeyboard.getLeds();
-
- //ホスト側NumLock状態はONか
- if( cur_led_sts & LED_NUM_LOCK )
- {
- //LED点灯(key_modeに従いRGB指定する)
- pixels.setPixelColor(0, pixels.Color(R[mode],G[mode],B[mode]));
- }
- else
- {
- //LED消灯(黒)
- pixels.setPixelColor(0, pixels.Color(0,0,0));
- }
- //LED出力
- pixels.show();
- }