1. //(1)シリアルLEDライブラリ(配布先 https://github.com/adafruit/Adafruit_NeoPixel)
  2. #include <Adafruit_NeoPixel.h>
  3. //(2)Arduino HID Project 2.4.4(配布先 https://github.com/NicoHood/HID#arduino-hid-project-244)
  4. #include <HID-Project.h>
  5. #include <HID-Settings.h>
  6. //キーコード指定
  7. #define KC_NUML 0x53 // [NUM LOCK]
  8. //KEY SCAN用 I/O定義
  9. #define ROW_NUM 7
  10. #define COL_NUM 4
  11. const int rowPins[ROW_NUM] = { 2, 3, 4, 5, 6, 7, 8 }; // OUTPUT指定
  12. const int colPins[COL_NUM] = { 9, 10, 16, 14 }; // INPUT_PULLUP指定
  13. //LED制御用 I/O定義
  14. #define NUMPIXELS 1 // シリアルLED個数
  15. #define NUM_LOCK_LED 21 // NumLock/動作モード状態LEDポート番号
  16. //シリアルLED定義
  17. // D2812 = NEO_RGB
  18. // WS2812B = NEO_GRB
  19. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NUM_LOCK_LED, NEO_GRB + NEO_KHZ800); //NumLock LED制御Pin初期化
  20. //NumLock・LED制御
  21. int R[3]; // LED色 Red (0-255)
  22. int G[3]; // LED色 Green(0-255)
  23. int B[3]; // LED色 Blue (0-255)
  24. //KEY状態制御用配列定義
  25. //KEY状態を前回と最新状態で比較して、変化があった場合にキーコードを送信する
  26. bool cur_key_sts[ROW_NUM][COL_NUM]; //最新のKEY状態
  27. bool old_key_sts[ROW_NUM][COL_NUM]; //前回のKEY状態
  28. void setup()
  29. {
  30.   // put your setup code here, to run once:
  31.   //キースキャン行のPinを初期化する
  32.   for (int i = 0; i < ROW_NUM; i++)
  33.   {
  34.     pinMode(rowPins[i], OUTPUT);
  35.   }
  36.   //キースキャン列のPinを初期化する
  37.   for (int i = 0; i < COL_NUM; i++)
  38.   {
  39.     pinMode(colPins[i], INPUT_PULLUP);
  40.   }
  41.   //キー状態を初期化する
  42.   for (int row = 0; row < ROW_NUM; row++)
  43.   {
  44.     //キー状態を「リリース」とする
  45.     for (int c = 0; c < COL_NUM; c++)
  46.     {
  47.       cur_key_sts[row][c] = HIGH;
  48.       old_key_sts[row][c] = HIGH;
  49.     }
  50.     //キースキャン行のPinをHIGH(inactive)にする
  51.     digitalWrite(rowPins[row], HIGH);
  52.   }
  53.   //LED表示初期化(各動作モード別にRGBで色指定する)
  54.   //色1=緑
  55.   R[0]=0;
  56.   G[0]=10;
  57.   B[0]=0;
  58.   //シリアルLEDライブラリ初期化
  59.   pixels.begin();
  60.   //HIDデバイス初期化(ホストLED状態取得用)
  61.   BootKeyboard.begin();
  62. }
  63. void loop()
  64. {
  65.   // put your main code here, to run repeatedly:
  66.   static int mode = 0;//色変更用
  67.   //キー押下状態変化なしとする(フラグ初期化)
  68.   int chg = 0;
  69.   // key matrix scan
  70.   for (int row = 0; row < ROW_NUM; row++)
  71.   {
  72.     // 行指定:キースキャン開始(LOW出力)
  73.     digitalWrite(rowPins[row], LOW);
  74.     for (int col = 0; col < COL_NUM; col++)
  75.     {
  76.       // 列指定:キー状態読み出し(押下:LOW)
  77.       cur_key_sts[row][col] = digitalRead(colPins[col]);
  78.       // 前回の状態と変化あり?
  79.       if (cur_key_sts[row][col] != old_key_sts[row][col])
  80.       {
  81.         //「キー押下状態変化あり」とする
  82.         chg = 1;
  83.       
  84.         // キーが押下されている?
  85.         if (cur_key_sts[row][col] == LOW)
  86.         {
  87.             // キーコード追加(押下)
  88.             BootKeyboard.add(KeyboardKeycode(KC_NUML));
  89.         }
  90.         else
  91.         {
  92.             // キーコード削除(離す)
  93.             BootKeyboard.remove(KeyboardKeycode(KC_NUML));
  94.         }
  95.         //現在のキー状態を前回の状態にコピーする
  96.         old_key_sts[row][col] = cur_key_sts[row][col];
  97.       }
  98.     }
  99.     // 行指定:キースキャン終了(HIGHに戻す)
  100.     digitalWrite(rowPins[row], HIGH);
  101.   }
  102.   //キー押下状態変化あり?
  103.   if ( chg == 1 )
  104.   {
  105.     //ホスト側に変化したキーコードを送信する
  106.     BootKeyboard.send();
  107.   }
  108.   //ホスト側のLED状態を取得
  109.   int cur_led_sts = BootKeyboard.getLeds();
  110.   
  111.   //ホスト側NumLock状態はONか
  112.   if( cur_led_sts & LED_NUM_LOCK )
  113.   {
  114.     //LED点灯(key_modeに従いRGB指定する)
  115.     pixels.setPixelColor(0, pixels.Color(R[mode],G[mode],B[mode]));
  116.   }
  117.   else
  118.   {
  119.     //LED消灯(黒)
  120.     pixels.setPixelColor(0, pixels.Color(0,0,0));
  121.   }
  122.   //LED出力
  123.   pixels.show();
  124. }