6_Project/소소한 플젝

SCK - 230917 단축키 키보드 제작

Mi:sAng 2023. 9. 10. 20:56

0.서론

허구한 날 Got Designer 3 으로 터치 작화하는데 생산성이 낮아 답답했었다. 

컴퓨터 성능도 별로라서 오브젝트 지정 하나도 시간이 오래걸린다. 

짧게 말해 컴퓨터는 느려터졌고, 프로그램은 맘에 안들고, 야근은 하기 싫어서 단축키 키보드를 설계했다. 

좌우상하 정렬은 GOT 에서 단축키가 없다. 그래서 정렬 단축키를 걸어 두었다. 

(Short Cut Key : SCK)

 

1.부품

*GATERON 기계식 키보드 스위치 갈출 [SZH-SW032] x 10 : 개당 600원

*아두이노 프로마이크로 x1 : 7000원

*마이크로 5핀 USB 케이블 - 가지고 있는 거 사용 : 0원

*키캡 -가지고 있는 거 사용 : 0원

 

집에 있던 아두이노 나노로 테스트 하려는데 Keyboard, Mouse 라이브러리가 호환이 안되었다. 

어쩔 수 없이 아두이노 프로 마이크로를 구매했다....

 

2.코드

#include <Mouse.h>
#include <Keyboard.h>
#include <KeyboardLayout.h>
#include <Keyboard_da_DK.h>
#include <Keyboard_de_DE.h>
#include <Keyboard_es_ES.h>
#include <Keyboard_fr_FR.h>
#include <Keyboard_it_IT.h>
#include <Keyboard_sv_SE.h>



/*
우클릭      
업 14      
우 1      
*Enter      Left
*Dn 1 + Enter      Center (horizontal)
*Dn 2 + Enter      Right
*Dn 3 + Enter      Top
*Dn 4 + Enter      Center(Vertical)
*Dn 5 + Enter      Bottom
*/




const int UP_ARROW = 218;//0xDA;
const int DOWN_ARROW = 217;//0xD9;
const int LEFT_ARROW = 216;//0xD8;
const int RIGHT_ARROW = 215;//0xD7;
const int MENU = 237;//0xED;
const int ENTER = 224;//0xE0;


boolean state = false;
const byte interruptPin = 8; //d2
const int SW_LEFT = 2;//d3
const int SW_CENTER_H = 3;//d4
const int SW_RIGHT = 4;//d5
const int SW_UP = 5;//d6
const int SW_CENTER_V = 6;//d7
const int SW_DOWN = 7;//d8
/*
 * ■  ■  ■    Interrupt(2)  None     None
 * ■  ■  ■    Left(3)       CenterH(4)  Right(5)
 * ■  ■  ■    Up(6)         CenterV(7)  Down(8)
 * 
 * 
 */




void pressMouseRight();
void pressKey(int key);
void pressUpKey();

void pressDownKey(int num);
void shortcutKey(int shortKey);
void showKey(int key);

void setup()
{
    Serial.begin(9600);
    pinMode(interruptPin, INPUT_PULLUP);
    pinMode(SW_LEFT, INPUT_PULLUP);

    pinMode(SW_CENTER_H, INPUT_PULLUP);
    pinMode(SW_RIGHT, INPUT_PULLUP);
    pinMode(SW_UP, INPUT_PULLUP);
    pinMode(SW_CENTER_V, INPUT_PULLUP);
    pinMode(SW_DOWN, INPUT_PULLUP);
    //attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);

    Mouse.begin();
    Keyboard.begin();
}
void loop()
{
    int val = 0;
    if (state == false)
    {
        Serial.println("state == false");
        if (digitalRead(SW_LEFT) == LOW)
        {
            val = 1;
            Serial.println("LEFT");
            delay(5);
        }
        else if (digitalRead(SW_CENTER_H) == LOW)
        {
            val = 2;
            Serial.println("CENTER H");
            delay(5);
        }
        else if (digitalRead(SW_RIGHT) == LOW)
        {
            val = 3;
            Serial.println("RIGHT");
            delay(5);
        }
        else if (digitalRead(SW_UP) == LOW)
        {
            val = 4;
            Serial.println("UP");
            delay(5);
        }
        else if (digitalRead(SW_CENTER_V) == LOW)
        {
            val = 5;
            Serial.println("CENTER V");
            delay(5);
        }
        else if (digitalRead(SW_DOWN) == LOW)
        {
            val = 6;
            Serial.println("DOWN");
            delay(5);
        }
        shortcutKey(val);
    }
    else
    {//when state==true
        Serial.println("state == true");
    }
}
void exchange()
{
    state = !state;
}

void pressMouseRight()
{
    Mouse.press(MOUSE_RIGHT);
    delay(5);
    Mouse.release(MOUSE_RIGHT);
    delay(5);

    // pressKey(KEY_MENU);


}
void showKey(int key)
{
    if (key == UP_ARROW)
    {
        Serial.println("UP");
    }
    else if (key == DOWN_ARROW)
    {
        Serial.println("DOWN");
    }
    else if (key == LEFT_ARROW)
    {
        Serial.println("LEFT");
    }
    else if (key == RIGHT_ARROW)
    {
        Serial.println("RIGHT");
    }
    else if (key == MENU)
    {
        Serial.println("MENU");
    }
    else if (key == ENTER)
    {
        Serial.println("ENTER");
    }
}

void pressKey(int key)
{
    Keyboard.press(key); //키 누름
    showKey(key);
    delay(5);
    Keyboard.releaseAll(); //키 해제
    delay(5);

}
void pressUpKey()
{
    for (int i = 0; i < 14; i++)
    {
        pressKey(UP_ARROW);
    }
}
void pressDownKey(int num)
{
    for (int i = 0; i < num; i++)
    {
        pressKey(DOWN_ARROW);
    }
}

void shortcutKey(int shortKey)
{
    //1:Left, 2:Center(H), 3:Right, 4:Top, 5:Center(T), 6:Button
    switch (shortKey)
    {
        case 1:
            pressMouseRight();
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressKey(ENTER);
            break;
        case 2:
            pressMouseRight();
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(1);
            pressKey(ENTER);
            break;
        case 3:
            pressMouseRight();
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(2);
            pressKey(ENTER);
            break;
        case 4:
            pressMouseRight();
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(3);
            pressKey(ENTER);
            break;
        case 5:
            pressMouseRight();
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(4);
            pressKey(ENTER);
            break;
        case 6:
            pressMouseRight();
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(5);
            pressKey(ENTER);
            break;


    }

}

 

2-2. 코드(ver 2023 0919)

마우스 우클릭을 사용하면 동작하는 와중에 마우스가 움직이면 동작이 부정확하게 된다

마우스 대신에 Menu 키를 이용하는 코드다 

Shift 키도 추가하였다. Shift키의 경우 delay를 너무 짧게 주면 연타하는 효과가 나서 고정키 창이 뜨므로 

정당히 딜레이를 주었다.

 

#include <Mouse.h>
#include <Keyboard.h>
#include <KeyboardLayout.h>
#include <Keyboard_da_DK.h>
#include <Keyboard_de_DE.h>
#include <Keyboard_es_ES.h>
#include <Keyboard_fr_FR.h>
#include <Keyboard_it_IT.h>
#include <Keyboard_sv_SE.h>



/*
우클릭      
업 14      
우 1      
*Enter      Left
*Dn 1 + Enter      Center (horizontal)
*Dn 2 + Enter      Right
*Dn 3 + Enter      Top
*Dn 4 + Enter      Center(Vertical)
*Dn 5 + Enter      Bottom
*/




const int UP_ARROW = 218;//0xDA;
const int DOWN_ARROW = 217;//0xD9;
const int LEFT_ARROW = 216;//0xD8;
const int RIGHT_ARROW = 215;//0xD7;
const int MENU = 237;//0xED;
const int ENTER = 224;//0xE0;
const int LEFT_SHIFT=133;//129;//0x81;

boolean state = false;
const byte interruptPin = 8; //d2
const int SW_LEFT = 5;//d3
const int SW_CENTER_H = 3;//d4
const int SW_RIGHT = 7;//d5
const int SW_UP = 3;//d6
//const int SW_CENTER_V = 6;//d7
const int SW_DOWN = 6;//d8
const int SW_SHIFT = 2;//d2

// sw 4,5,6,7,8,9 =d2,3,4,5,6,7,
/*
 * ■  ■  ■    Interrupt(2)  None     None
 * ■  ■  ■    Left(3)       CenterH(4)  Right(5)
 * ■  ■  ■    Up(6)         CenterV(7)  Down(8)
 * 
 * 
 */
/* Updated Ver : 20230919
 * ■  ■  ■    None          None     None
 * ■  ■  ■    Shift(3       Up(4)    None
 * ■  ■  ■    Left(6)       DOWN(7)  RIGHT(8)
 * 
 * 
 */



void pressMouseRight();
void pressKey(int key);
void pressUpKey();

void pressDownKey(int num);
void shortcutKey(int shortKey);
void showKey(int key);

void setup()
{
    Serial.begin(9600);
    pinMode(interruptPin, INPUT_PULLUP);
    pinMode(SW_LEFT, INPUT_PULLUP);

    pinMode(SW_SHIFT, INPUT_PULLUP);
    pinMode(SW_RIGHT, INPUT_PULLUP);
    pinMode(SW_UP, INPUT_PULLUP);
    //pinMode(SW_CENTER_V, INPUT_PULLUP);
    pinMode(SW_DOWN, INPUT_PULLUP);
    //attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);

    Mouse.begin();
    Keyboard.begin();
}
void loop()
{
    int val = 0;
    if (state == false)
    {
        Serial.println("state == false");
        if (digitalRead(SW_SHIFT) == LOW)
        {   Keyboard.press(LEFT_SHIFT); //키 누름        
                //Keyboard.releaseAll(); //키 해제
                //delay(5);
            Serial.println("SHIFT");
            delay(200);
            Keyboard.release(LEFT_SHIFT);
            delay(2);
            
        }

        
        if (digitalRead(SW_LEFT) == LOW)
        {
            val = 1;
            Serial.println("LEFT");
            delay(2);
            shortcutKey(val);
        }
        if (digitalRead(SW_RIGHT) == LOW)
        {
            val = 3;
            Serial.println("RIGHT");
            delay(2);
            shortcutKey(val);
        }
        if (digitalRead(SW_UP) == LOW)
        {
            val = 4;
            Serial.println("UP");
            delay(2);
            shortcutKey(val);
        }
        /*else if (digitalRead(SW_CENTER_V) == LOW)
        {
            val = 5;
            Serial.println("CENTER V");
            delay(5);
        }
        */
        if (digitalRead(SW_DOWN) == LOW)
        {
            val = 6;
            Serial.println("DOWN");
            delay(2);
            shortcutKey(val);
        }
        
    }
    else
    {//when state==true
        Serial.println("state == true");
    }
}
void exchange()
{
    state = !state;
}

void pressMouseRight()
{
    Mouse.press(MOUSE_RIGHT);
    delay(5);
    Mouse.release(MOUSE_RIGHT);
    delay(5);

    // pressKey(KEY_MENU);


}
void showKey(int key)
{
    if (key == UP_ARROW)
    {
        Serial.println("UP");
    }
    else if (key == DOWN_ARROW)
    {
        Serial.println("DOWN");
    }
    else if (key == LEFT_ARROW)
    {
        Serial.println("LEFT");
    }
    else if (key == RIGHT_ARROW)
    {
        Serial.println("RIGHT");
    }
    else if (key == MENU)
    {
        Serial.println("MENU");
    }
    else if (key == ENTER)
    {
        Serial.println("ENTER");
    }
}

void pressKey(int key)
{
    Keyboard.press(key); //키 누름
    showKey(key);
    delay(4);
    Keyboard.releaseAll(); //키 해제
    delay(4);

}
void pressUpKey()
{
    for (int i = 0; i < 14; i++)
    {
        pressKey(UP_ARROW);
    }
}
void pressDownKey(int num)
{
    for (int i = 0; i < num; i++)
    {
        pressKey(DOWN_ARROW);
    }
}

void shortcutKey(int shortKey)
{
    //1:Left, 2:Center(H), 3:Right, 4:Top, 5:Center(T), 6:Button
    switch (shortKey)
    {
        case 1:
            //pressMouseRight();
            pressKey(MENU);
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressKey(ENTER);
            break;
        case 2:
            //pressMouseRight();
            pressKey(MENU);
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(1);
            pressKey(ENTER);
            break;
        case 3:
            //pressMouseRight();
            pressKey(MENU);
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(2);
            pressKey(ENTER);
            break;
        case 4:
            //pressMouseRight();
            pressKey(MENU);
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(3);
            pressKey(ENTER);
            break;
        case 5:
            //pressMouseRight();
            pressKey(MENU);
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(4);
            pressKey(ENTER);
            break;
        case 6:
            //pressMouseRight();
            pressKey(MENU);
            pressUpKey();
            pressKey(RIGHT_ARROW);
            pressDownKey(5);
            pressKey(ENTER);
            break;


    }

}

 

 

 

3. 회로

갈축 7개만 사용한다 . D2~D8까지만 직접 연결한다. 

매트릭스로 구성된 회로를 사용한다면 정류다이오드가 필요하겠지만

8개 밖에 없는데 굳이.... 매트릭스로 회로 설계할 필요는 없을 듯하다. 

인두기가 박살난 이유로 Interrupt Pin은 사용하지 않았고, 6개의 스위치만 동작가능하다

 

4.결과물

*사진

 

5. 추후 계획

Winform에 연동하는 것도 나쁘지 않을 것 같기도하다. 상황에 따라서 모드를 선택할 수 있게 하는 방법으로.

하드웨어 만드는 건 효율이 영 아닌 것 같다.

지금은 GOT Align으로 했지만 다른 기능들을 더 추가할 수 있도록 할 계획이다.

속도가 빨라졌다고는 그닥 생각하지는 않는다. pywinauto 라이브러리 이용해서 다른 접근으로 해봐야겠다

 

 

 

6. 레퍼런스

https://guzene.tistory.com/271

 

아두이노 키보드 만들기

친구 한명이 이걸 만들어보자고 얘기했을 때, 아니 지금 키보드 있는데 왜 만들어? 하면서 반신반의하다가 한번 이거저거 뒤져봤다. 그리고 상상의 나래를 펼치고 펼쳐서... 엇 그러면 인체공학

guzene.tistory.com

https://worklab.tistory.com/7

 

아두이노로 커스텀 키보드 만들기 - 5. 스위치 매트릭스

지난 글에서 설명한 이론을 바탕으로 이번에는 단일 스위치에서 시작해 스위치 매트릭스까지 한단계씩 확장해가며 키보드에 사용할 회로를 만들어 보겠습니다. 접지 라인 통합 아두이노에 스

worklab.tistory.com

https://steemit.com/kr-arduino/@codingman/2ftgce

https://github.com/arduino-libraries/Keyboard/blob/master/src/Keyboard.h

https://www.arduino.cc/reference/en/language/functions/usb/keyboard/keyboardmodifiers/

'6_Project > 소소한 플젝' 카테고리의 다른 글

파이썬으로 자동화한 액셀과 PPT  (2) 2024.01.04