2016年1月12日 星期二

DIY懶人實體快速鍵 - Arduino Pro Micro

小弟是懶人,所以在辦公室打文件時,常需要軟體開來開去,這時就好希望能有個實體快速鍵,按一下就打開程式,再按一下就關閉程式,於是懶人實體快速鍵就誕生了




明明移動一下滑鼠按一按就可以了...搞什麼實體按鍵,是吃飽太閒嗎?

科技會進步,就是有一大群懶人(宅工)因為人的天性 - 懶,而發明了許多便利的商品或商業模式,說懶是人類進步的原動力也不為過...

至於為什麼要搞這個....嗯....不想回答,大家自己想吧~~~

想像一下,你在某個應用程式裡工作時,突然想開啟另一個程式,你也許會這樣做

1. 把滑鼠移到windows logo從開始的選單裡執行你想要開啟的程式
2. 把畫面切到windows桌面,點選你想要開啟的程式

除了上述的做法,也許有人會說...Windows的捷徑本身就可以設定快速鍵啊....沒錯,確實是可以,在捷徑icon上按右鍵選內容就會看到這個畫面

上圖中間的快速鍵就是讓你設定的,但是這快速鍵是有限制的,請參考這篇
設定「捷徑」的快速鍵與注意事項

簡單來說,只有 3 個地方的「捷徑」設定快速鍵才會生效:
1. 開始功能表
2. 程式集
3. 桌面

任何放在其他地方的「捷徑」所設定的「快速鍵」都不會生效!

我討厭這個限制所以放棄,於是求助google大神,找到這個東東HotKeyPlus
這個東東真的可以實現小弟用快速鍵開啟程式(只是不是一鍵),但也很棒了
用了一段時間發現,可以用快速鍵開程式,但是卻沒有關閉程式可以選,找到最快速的方法是
ALT+F4(參考這篇Windows – 快速關閉程式、關機)
起初用覺得很不錯啊....至少比滑鼠移來移去好多了,用久了...開始覺得不舒服而且手會酸,這不符合人體工學(什麼...這要求太多了吧~)

於是想起之前DIY實用的PPT簡報器,可以用Pro Micro來實現按鍵組合,等於是幫你按鍵盤的意思,於是懶人實體快速鍵就誕生了,做法如下

1. 找塊厚一點的紙板,按5個洞,並把你的想開啟的程式寫在下面(你也可以擴展按鍵,只要pro micro的pin數夠用就可以)


2. 把按鍵裝上去,我目前定義有4個開啟程式按鍵,分別是Arduino、google chrome、outlook和PPT,最左邊的close鍵,就是關閉目前的應用程式

3. 把線用OK線焊一焊


4.中間的控制板就是使用Arduino Pro Micro

這樣就完成了,花二個小時就可以DIY完成

Arduino Pro Micro的程式碼如下
boolean Close_Key, Chrome_Key, Arduino_Key, Outlook_Key, PPT_Key;
unsigned char Button_Times = 0xFF;
unsigned char Last_Button_Times = Button_Times;
char Bnumber=0;
bool debug=0;

void setup() {
  pinMode(17, OUTPUT);
  pinMode(2, INPUT); //Close Key 
  pinMode(3, INPUT); //Chrome Key 
  pinMode(4, INPUT); //Arduino Key 
  pinMode(5, INPUT); //Outlook Key 
  pinMode(6, INPUT); //PPT Key 
  
  Serial.begin(9600);
  Keyboard.begin();
  Serial.println("The program start up...");
}

void loop() {
  
 Close_Key=digitalRead(2);
 Chrome_Key=digitalRead(3);
 Arduino_Key=digitalRead(4);
 Outlook_Key=digitalRead(5);
 PPT_Key=digitalRead(6);
 if(debug) { Serial.print("Close_Key = ");  Serial.println(Close_Key); }
 if(!Close_Key) {
    while(!digitalRead(2));
    delay(50);
    Bnumber=2;Button_Times=0x02; }     
  else if(!Chrome_Key) {
    while(!digitalRead(3));
    delay(50);
    Bnumber=3;Button_Times=0x03; }
  else if(!Arduino_Key) {
    while(!digitalRead(4));
    delay(50);
    Bnumber=4;Button_Times=0x04; }
  else if(!Outlook_Key) {
    while(!digitalRead(5));
    delay(50);
    Bnumber=5;Button_Times=0x05; }
  else if(!PPT_Key) {
    while(!digitalRead(6));
    delay(50);
    Bnumber=6;Button_Times=0x06; }
  else {
    delay(50);
    Bnumber=99;Button_Times=0xFF; 
    digitalWrite(17, HIGH); //low active
    }
      
  if(Button_Times != Last_Button_Times) {
    Last_Button_Times=Button_Times;
    switch(Bnumber) {
      case 2:
        digitalWrite(17, LOW); //low active
        Keyboard.press(KEY_LEFT_ALT); 
        delay(20);
        Keyboard.press(KEY_F4); //ALT+F4 = close program
        delay(20);
        Keyboard.releaseAll();
        break;  
      case 3: 
        digitalWrite(17, LOW); //low active
        Keyboard.press(KEY_LEFT_CTRL); 
        delay(20);
        Keyboard.press(KEY_LEFT_ALT); 
        delay(20);
        Keyboard.press(103); //小寫g的ascii code=103 , 執行Key組合 = CTRL+ALT+g = google chrome browser
        delay(20);
        Keyboard.releaseAll();
        break;    
      case 4: 
        digitalWrite(17, LOW); //low active
        Keyboard.press(KEY_LEFT_CTRL); 
        delay(20);
        Keyboard.press(KEY_LEFT_ALT); 
        delay(20);
        Keyboard.press(97); //小寫a的ascii code=97 , 執行Key組合 = CTRL+ALT+a = arduino
        delay(20);
        Keyboard.releaseAll();
        break;   
      case 5: 
        digitalWrite(17, LOW); //low active
        Keyboard.press(KEY_LEFT_CTRL); 
        delay(20);
        Keyboard.press(KEY_LEFT_ALT); 
        delay(20);
        Keyboard.press(111); //小寫a的ascii code=111 , 執行Key組合 = CTRL+ALT+o = Outlook
        delay(20);
        Keyboard.releaseAll();
        break;   
      case 6: 
        digitalWrite(17, LOW); //low active
        Keyboard.press(KEY_LEFT_CTRL); 
        delay(20);
        Keyboard.press(KEY_LEFT_ALT); 
        delay(20);
        Keyboard.press(112); //小寫p的ascii code=112 , 執行Key組合 = CTRL+ALT+p = PPT
        delay(20);
        Keyboard.releaseAll();
        break;          
      }
    }   
}

最後,錄個簡單的實際動作影片

20 則留言:

  1. 使用TTP226 8路 電容式 觸摸開關, 更懶:)P

    回覆刪除
    回覆
    1. 手TTP226也可以, 但是按鍵有點小, 緊急時容易按錯, 生氣時也容易按錯^_^

      刪除
  2. 你的程式真的很不易讀...
    然後線路也太亂.......
    用INPUT_PULLUP只要使用微動的NO就可以了 不需要用NC 就先減五條線了

    還是學生?

    回覆刪除
    回覆
    1. 你好, 首先我不是學生耶...我是個工程師, 線路太亂這個問題很難回答, 這種凌空跳線的方式, 怎麼弄才好看, 你可以分享一下你的作品嗎? 至於程式碼我重新看了一下, 很清楚也很簡單, 就偵測按鍵和判斷是那一顆按鍵並執行而已, 那裡不好讀呢?
      另外, 因為這個按鈕是有LED的, 也就是會發光, 所以它有4pin, 2根給led, 2根給微動開關, 所以我的接法是+5V先接到LED+, LED-再接到微動開關的一端, 這一端再拉回給Arduino Pro Micro做按鍵偵測, 微動開關另一端就接地, 可能我沒畫出線路圖才會感覺很亂吧!如果你不需要按下會發光, 那就可以減10條線, 歡迎你來分享你的作品喔~~~

      刪除
    2. 路過來看看,看到有人提點你代碼不易讀,我就說兩點:
      1.變數命名沒有規範,如果不是原作者,必須從頭開始看才能搞懂。
      像是Bnumber乍看之下是存放整數數字,但看了實際定義才發現存的是字元,非常混淆不清,為什麼不用cButton這樣的方式命名?

      2.變數賦值沒有意義,繼續用Bnumber來舉例,賦值2,3,4,5,6,99是個什麼意思?
      當別人想維護你的代碼時,比方說switch那邊,他還要從頭開始分析這些數字是啥意思,然後才能改版或修BUG,很沒效率,難道不能先define個有意義的名字嗎?
      例如#define KEY_CLOSE 2
      以後Bnumber要賦值就直接 Bnumber = KEY_CLOSE;
      或是判斷時變成case KEY_CLOSE:
      這樣不是更能讓人看懂?而且也能避免其他工程師亂賦值出包。

      刪除
    3. 別再刪留言了,我再留一次,他說你是學生真的剛好而已

      路過看到有人提點你代碼不好讀,我就說兩點
      1.變數命名不規範:如果不是原作者,必須要回頭看代碼才能理解意義,
      舉個例,Bnumber這個變數乍看之下是存放數值,但往前一看才知道是存放字元,
      你為什麼不用cButton這樣的方式命名?
      還有其他變數命名方式如果不從頭看的話,也是只有你才能懂啊,其實跟int a; int b;沒兩樣。

      2.變數賦值混淆不清:一樣的問題,你還是用只有你自己能懂的概念在寫代碼,Bnumber賦值2,3,4,5,6,99是個什麼意思?
      為什麼不給每個值一個定義?舉例,#define Key_Close 2
      以後你賦值或做判斷就直接Bnumber = Key_Close; 或是 case Key_Close: 這樣不就好懂多了嗎?
      否則當其他人在維護你的代碼時還要從頭開始分析,很沒效率,也容易出錯,因為值的意義只有你才真正明白,
      如果只是要對switch那部分改版或修BUG,還要從頭來過,根本浪費時間,代碼越積越多,看的時間就要越久。

      刪除
    4. 別再刪留言了,我再留一次,他說你是學生真的剛好而已

      路過看到有人提點你代碼不好讀,我就說兩點
      1.變數命名不規範:如果不是原作者,必須要回頭看代碼才能理解意義,
      舉個例,Bnumber這個變數乍看之下是存放數值,但往前一看才知道是存放字元,
      你為什麼不用cButton這樣的方式命名?
      還有其他變數命名方式如果不從頭看的話,也是只有你才能懂啊,其實跟int a; int b;沒兩樣。

      2.變數賦值混淆不清:一樣的問題,你還是用只有你自己能懂的概念在寫代碼,Bnumber賦值2,3,4,5,6,99是個什麼意思?
      為什麼不給每個值一個定義?舉例,#define Key_Close 2
      以後你賦值或做判斷就直接Bnumber = Key_Close; 或是 case Key_Close: 這樣不就好懂多了嗎?
      否則當其他人在維護你的代碼時還要從頭開始分析,很沒效率,也容易出錯,因為值的意義只有你才真正明白,
      如果只是要對switch那部分改版或修BUG,還要從頭來過,根本浪費時間,代碼越積越多,看的時間就要越久。

      刪除
    5. 嗯..首先解釋一下, 我沒有刪留言, 是因為你的留言被歸在垃圾留言, 所以我沒看到, 另外關於程式的寫作, 我不像你這麼專業, 也沒有受過專業的訓練, 我是個硬體工程師, 所以沒辦法像你這麼專業, 命名的問題, 我也有注意到我自己確實沒有取的很好, 有時回頭也真的看不懂自己寫的, 但....just for fun, 如此而已

      刪除
    6. 原來沒有刪,那是我錯了,誤會你了,對不起

      刪除
    7. 硬體工程師能有這等程度也算是厲害了。
      無論程度如何,願意分享,我就覺得了不起。
      有一句台語說:[互相漏氣求進步],善意的討論大家都受益。

      刪除
    8. 是啊, 國外都是這樣, 所以分享的風氣很興盛, 也不怕丟臉, 在國內, 總是有正義魔人, 說這個說那個, 讓大家都不想分享, 於是孤軍作戰, 最後下場都很慘, 台灣人很優秀, 但都不團結, 各懷鬼胎, 總見不得人家好

      刪除
  3. 我想到可以做關別人視窗的玩具,插入別人電腦幫他關視窗。
    不用搶滑鼠,偷偷插入拉延長USB。
    ><嘻嘻

    回覆刪除
    回覆
    1. 用延長usb線可能會被抓包, 乾脆用藍芽或NRF24L01, 改成無線更神不知鬼不覺^_^

      刪除
  4. 我寫了一個尾牙摸彩的小程式, 就差獨立按鈕這一塊!
    太棒了!!

    回覆刪除
  5. 天啊 板子上的arduino拼錯 先別管這個 這真是一個不錯的專題

    回覆刪除
  6. 您好 我最近也在玩這塊板子 但是我的電腦無法辨識到這塊板子 請問版主有遇到這樣的問題嗎

    回覆刪除

歡迎大家來討論交流一下~~~