//キーボード #define KDATA 6 #define KCLOCK 7 //割り込みに使用 //PC #define PDATA 8 #define PCLOCK 9 //LED #define LED1 4 #define LED2 5 #define BUFFER_SIZE 32 #define WAIT 30 static volatile uint8_t keyBuffer[BUFFER_SIZE]; static volatile uint8_t head, tail; static volatile uint8_t command; const PROGMEM uint8_t normal[] = { 0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, //00-07 0, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0, //08-0F 0, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0, //10-17 0, 0, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, //18-1F 0, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, //20-27 0, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, //28-2F 0, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0, //30-37 0, 0, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0, //38-3F 0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0, //40-47 0, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0, //48-4F 0, 0x51, 0x52, 0, 0x54, 0x55, 0, 0, //50-57 0x58, 0x59, 0x5A, 0x5B, 0, 0x6A, 0, 0, //58-5F 0, 0, 0, 0, 0x64, 0, 0x66, 0x67, //60-67 0, 0x69, 0x6A, 0x6B, 0x6C, 0, 0, 0, //68-6F 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, //70-77 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0, //78-7F 0, 0, 0, 0x83, 0x84 }; //80-84 const PROGMEM uint8_t custom[] = { 0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, //00-07 0, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0, //08-0F 0, 0x11, 0x12, 0x13, 0x14, 0x25, 0x16, 0, //10-17 0, 0, 0x1A, 0x3E, 0x3D, 0x2E, 0x1E, 0x1F, //18-1F 0, 0x21, 0x22, 0x46, 0x36, 0x25, 0x26, 0x27, //20-27 0, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, //28-2F 0, 0x31, 0x32, 0x33, 0x34, 0x0B, 0x36, 0, //30-37 0, 0, 0x3A, 0x3B, 0x83, 0x3D, 0x3E, 0, //38-3F 0, 0x41, 0x42, 0x0A, 0x01, 0x45, 0x46, 0, //40-47 0, 0x49, 0x4A, 0x4B, 0x4C, 0x09, 0x4E, 0, //48-4F 0, 0x51, 0x52, 0, 0x54, 0x55, 0, 0, //50-57 0x58, 0x59, 0x5A, 0x5B, 0, 0x6A, 0, 0, //58-5F 0, 0, 0, 0, 0x64, 0, 0x66, 0x67, //60-67 0, 0x69, 0x6A, 0x6B, 0x6C, 0, 0, 0, //68-6F 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, //70-77 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0, //78-7F 0, 0, 0, 0x83, 0x84 }; //80-84 uint8_t *keytable; uint8_t ps2code, beforeCode = 0; bool lshift, rshift; //シフトキーが押されているか bool customMode, jpMode; void setup() { pinMode(PCLOCK, INPUT_PULLUP); pinMode(PDATA, INPUT_PULLUP); pinMode(KCLOCK, INPUT_PULLUP); pinMode(KDATA, INPUT_PULLUP); pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); head = 0; tail = 0; //キー初期状態 keytable = normal; lshift = false; rshift = false; jpMode = false; customMode = false; attachInterrupt(digitalPinToInterrupt(KCLOCK), keyCodeInt, FALLING); } void loop() { if (digitalRead(PCLOCK) == LOW || digitalRead(PDATA) == LOW) { sendCommand(getCommand()); //PCからのコマンドコード } else { ps2code = getKeyCode(); if(ps2code > 0xA9) //キーボードからのACK { sendKeyCode(ps2code); } else { switch(ps2code) { case 0: break; case 0x12: //LeftShift if(beforeCode == 0xF0) //キーリリース lshift = false; else lshift = true; sendKeyCode(0x12); break; case 0x59: //RightShift if(beforeCode == 0xF0) //キーリリース rshift = false; else rshift = true; sendKeyCode(0x59); break; case 0x0E: //`~ if(beforeCode == 0xF0) //キーリリース { if(jpMode) sendKeyCode(0x5D); else if(lshift || rshift) { sendKeyCode(0x55); //JP ^~ } else { sendKeyCode(0x54); //JP @` sendKeyCode(0xF0); //キーリリース sendKeyCode(0x12); //LeftShift } } else { if(jpMode) sendKeyCode(0x5D); else if(lshift || rshift) { sendKeyCode(0x55); //JP ^~ } else { sendKeyCode(0x12); //LeftShift sendKeyCode(0x54); //JP @` } } break; case 0x1E: //2@ if(beforeCode == 0xF0) //キーリリース { if(lshift) { sendKeyCode(0x54); //JP @` sendKeyCode(0x12); //LeftShift } else if(rshift) { sendKeyCode(0x54); //JP @` sendKeyCode(0x59); //RightShift } else { sendKeyCode(0x1E); } } else { if(lshift) { sendKeyCode(0xF0); //キーリリース sendKeyCode(0x12); //LeftShift sendKeyCode(0x54); //JP @` } else if(rshift) { sendKeyCode(0xF0); //キーリリース sendKeyCode(0x59); //RightShift sendKeyCode(0x54); //JP @` } else { sendKeyCode(0x1E); } } break; case 0x36: //6^ if(beforeCode == 0xF0) //キーリリース { if(lshift) { if(jpMode) sendKeyCode(0x36); else { sendKeyCode(0x55); //JP ^~ sendKeyCode(0x12); //LeftShift } } else if(rshift) { if(jpMode) sendKeyCode(0x36); else { sendKeyCode(0x55); //JP ^~ sendKeyCode(0x59); //RightShift } } else { sendKeyCode(0x36); } } else { if(lshift) { if(jpMode) sendKeyCode(0x36); else { sendKeyCode(0xF0); //キーリリース sendKeyCode(0x12); //LeftShift sendKeyCode(0x55); //JP ^~ } } else if(rshift) { if(jpMode) sendKeyCode(0x36); else { sendKeyCode(0xF0); //キーリリース sendKeyCode(0x59); //RightShift sendKeyCode(0x55); //JP ^~ } } else { sendKeyCode(0x36); } } break; case 0x3D: //7& if(beforeCode == 0xF0) //キーリリース { if(lshift || rshift) { if(jpMode) sendKeyCode(0x3D); else sendKeyCode(0x36); //JP 6& } else { sendKeyCode(0x3D); } } else { if(lshift || rshift) { if(jpMode) sendKeyCode(0x3D); else sendKeyCode(0x36); //JP 6& } else { sendKeyCode(0x3D); } } break; case 0x3E: //8* if(beforeCode == 0xF0) //キーリリース { if(lshift || rshift) { if(jpMode) sendKeyCode(0x3E); else sendKeyCode(0x52); //JP :* } else { sendKeyCode(0x3E); } } else { if(lshift || rshift) { if(jpMode) sendKeyCode(0x3E); else sendKeyCode(0x52); //JP :* } else { sendKeyCode(0x3E); } } break; case 0x46: //9( if(beforeCode == 0xF0) //キーリリース { if(lshift || rshift) { if(jpMode) sendKeyCode(0x46); else sendKeyCode(0x3E); //JP 8( } else { sendKeyCode(0x46); } } else { if(lshift || rshift) { if(jpMode) sendKeyCode(0x46); else sendKeyCode(0x3E); //JP 8( } else { sendKeyCode(0x46); } } break; case 0x45: //0) if(beforeCode == 0xF0) //キーリリース { if(lshift || rshift) { if(jpMode) sendKeyCode(0x45); else sendKeyCode(0x46); //JP 9) } else { sendKeyCode(0x45); } } else { if(lshift || rshift) { if(jpMode) sendKeyCode(0x45); else sendKeyCode(0x46); //JP 9) } else { sendKeyCode(0x45); } } break; case 0x4E: //-_ if(beforeCode == 0xF0) //キーリリース { if(lshift || rshift) { sendKeyCode(0x51); //JP \_ } else { sendKeyCode(0x4E); } } else { if(lshift || rshift) { sendKeyCode(0x51); //JP \_ } else { sendKeyCode(0x4E); } } break; case 0x55: //=+ if(beforeCode == 0xF0) //キーリリース { if(jpMode) sendKeyCode(0x55); else if(lshift || rshift) { sendKeyCode(0x4C); //JP ;+ } else { sendKeyCode(0x4E); //JP -= sendKeyCode(0xF0); //キーリリース sendKeyCode(0x12); //LeftShift } } else { if(jpMode) sendKeyCode(0x55); else if(lshift || rshift) { sendKeyCode(0x4C); //JP ;+ } else { sendKeyCode(0x12); //LeftShift sendKeyCode(0x4E); //JP -= } } break; case 0x4C: //;: if(beforeCode == 0xF0) //キーリリース { if(lshift) { sendKeyCode(0x52); //JP :* sendKeyCode(0x12); //LeftShift } else if(rshift) { sendKeyCode(0x52); //JP :* sendKeyCode(0x59); //RightShift } else { sendKeyCode(0x4C); } } else { if(lshift) { sendKeyCode(0xF0); //キーリリース sendKeyCode(0x12); //LeftShift sendKeyCode(0x52); //JP :* } else if(rshift) { sendKeyCode(0xF0); //キーリリース sendKeyCode(0x59); //RightShift sendKeyCode(0x52); //JP :* } else { sendKeyCode(0x4C); } } break; case 0x52: //'" if(beforeCode == 0xF0) //キーリリース { if(jpMode) sendKeyCode(0x52); else if(lshift || rshift) { sendKeyCode(0x1E); //JP 2" } else { sendKeyCode(0x3D); //JP 7' sendKeyCode(0xF0); //キーリリース sendKeyCode(0x12); //LeftShift } } else { if(jpMode) sendKeyCode(0x52); else if(lshift || rshift) { sendKeyCode(0x1E); //JP 2" } else { sendKeyCode(0x12); //LeftShift sendKeyCode(0x3D); //JP 7' } } break; case 0x54: //[{ if(jpMode) sendKeyCode(0x54); else sendKeyCode(0x5B); //JP [{ break; case 0x5B: //]} if(jpMode) sendKeyCode(0x5B); else sendKeyCode(0x5D); //JP ]} break; case 0x33: //H if(customMode) //← { if(beforeCode != 0xF0) //キーリリース { sendKeyCode(0xE0); sendKeyCode(0x6B); sendKeyCode(0xE0); sendKeyCode(0xF0); sendKeyCode(0x6B); } } else sendKeyCode(0x33); break; case 0x3B: //J if(customMode) //↓ { if(beforeCode != 0xF0) //キーリリース { sendKeyCode(0xE0); sendKeyCode(0x72); sendKeyCode(0xE0); sendKeyCode(0xF0); sendKeyCode(0x72); } } else sendKeyCode(0x3B); break; case 0x42: //K if(customMode) //↑ { if(beforeCode != 0xF0) //キーリリース { sendKeyCode(0xE0); sendKeyCode(0x75); sendKeyCode(0xE0); sendKeyCode(0xF0); sendKeyCode(0x75); } } else sendKeyCode(0x42); break; case 0x4B: //L if(customMode) //→ { if(beforeCode != 0xF0) //キーリリース { sendKeyCode(0xE0); sendKeyCode(0x74); sendKeyCode(0xE0); sendKeyCode(0xF0); sendKeyCode(0x74); } } else sendKeyCode(0x4B); break; case 0x64: //IMEオン・オフ if(beforeCode == 0xF0) //キーリリース { jpMode = !jpMode; if(jpMode) { digitalWrite(LED2, HIGH); } else { digitalWrite(LED2, LOW); } } sendKeyCode(0x0E); //半角/全角 break; case 0x67: //機能キーオン・オフ if(beforeCode == 0xF0) //キーリリース { customMode = !customMode; if(customMode) { keytable = custom; //ユーザー定義キーテーブル digitalWrite(LED1, HIGH); } else { keytable = normal; //標準キーテーブル digitalWrite(LED1, LOW); } } break; default: sendKeyCode(pgm_read_byte(keytable + ps2code)); } } if(ps2code) beforeCode = ps2code; } } //PCにキーコードを送る void sendKeyCode(uint8_t code) { uint8_t onebit, parity = 0; if(digitalRead(PCLOCK) == LOW) //PCがキーボードの通信を禁止 return; if(digitalRead(PDATA) == LOW) //PCからの送信要求 return; pinMode(PCLOCK, OUTPUT); pinMode(PDATA, OUTPUT); digitalWrite(PDATA, LOW); //スタートビット digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); digitalWrite(PCLOCK, HIGH); delayMicroseconds(WAIT); if(digitalRead(PCLOCK) == LOW) //送信を中断 return; //コードを1バイト送る for (int i = 0; i < 8; i++) { onebit = (code >> i) & 1; digitalWrite(PDATA, onebit); digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); digitalWrite(PCLOCK, HIGH); delayMicroseconds(WAIT); parity += onebit; if(digitalRead(PCLOCK) == LOW) //送信を中断 return; } digitalWrite(PDATA, ~parity & 1); //パリティビット digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); digitalWrite(PCLOCK, HIGH); delayMicroseconds(WAIT); if(digitalRead(PCLOCK) == LOW) //送信を中断 return; pinMode(PDATA, INPUT_PULLUP); //ストップビット digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); pinMode(PCLOCK, INPUT_PULLUP); delayMicroseconds(WAIT); } //PCからコマンドを受け取る uint8_t getCommand() { uint8_t code = 0, onebit; while (digitalRead(PDATA) == HIGH); //スタートビットを待つ while (digitalRead(PCLOCK) == LOW); //HIGHを待つ pinMode(PCLOCK, OUTPUT); digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); digitalWrite(PCLOCK, HIGH); delayMicroseconds(WAIT); for (int i = 0; i < 8; i++) { onebit = digitalRead(PDATA); code |= onebit << i; delayMicroseconds(WAIT); digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); digitalWrite(PCLOCK, HIGH); delayMicroseconds(WAIT); //ループ内の8回目のクロックでパリティビットは読み取らない } //ストップビットも読み取らない digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); digitalWrite(PCLOCK, HIGH); delayMicroseconds(WAIT); digitalWrite(PCLOCK, LOW); //クロック delayMicroseconds(WAIT); //ACK pinMode(PDATA, OUTPUT); digitalWrite(PDATA, LOW); delayMicroseconds(WAIT); pinMode(PCLOCK, INPUT_PULLUP); delayMicroseconds(WAIT); pinMode(PDATA, INPUT_PULLUP); return code; } //キーコードのバッファからコードを取り出す static inline uint8_t getKeyCode(void) { uint8_t ret; if (head == tail) return 0; ret = keyBuffer[head++]; if (head == BUFFER_SIZE) { head = 0; } return ret; } //キーボードにコマンドを送る void sendCommand(uint8_t comm) { uint8_t onebit, parity = 0; command = comm; //割り込みで使用 pinMode(KDATA, OUTPUT); pinMode(KCLOCK, OUTPUT); detachInterrupt(digitalPinToInterrupt(KCLOCK)); digitalWrite(KCLOCK, LOW); //キーボードの通信を禁止 delayMicroseconds(60); attachInterrupt(digitalPinToInterrupt(KCLOCK), commandInt, FALLING); digitalWrite(KDATA, LOW); pinMode(KCLOCK, INPUT_PULLUP); //PCからの送信要求 } //キーボードからキーコードを受け取る(割り込みエントリ) void keyCodeInt(void) { static uint8_t past = 0; static uint8_t counter = 0; static uint8_t code; static uint8_t parity; uint8_t now, onebit, p; onebit = digitalRead(KDATA); now = millis(); if (now - past > 250) counter = 0; past = now; switch (counter++) { case 0: //スタートビット code = 0; parity = 0; break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: code |= onebit << counter - 2; parity += onebit; break; case 9: if (onebit == (~parity & 1)) { //キーバッファにコードを入れる p = tail; keyBuffer[p++] = code; if (p == BUFFER_SIZE) p = 0; if (p == head) p = tail; else tail = p; } break; case 10: //ストップビット counter = 0; break; } } //キーボードにコマンドを送る(割り込みエントリ) void commandInt(void) { static uint8_t parity; static uint8_t counter = 0; uint8_t onebit; switch (counter++) { case 0: digitalWrite(KDATA, LOW); //スタートビット parity = 0; break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: onebit = (command >> (counter - 2)) & 1; digitalWrite(KDATA, onebit); parity += onebit; break; case 9: digitalWrite(KDATA, ~parity & 1); //パリティビット break; case 10: pinMode(KDATA, INPUT_PULLUP);//ストップビット break; case 11: //ACK detachInterrupt(digitalPinToInterrupt(KCLOCK)); while (digitalRead(KDATA) == HIGH); //LOWを待つ counter = 0; while (digitalRead(KCLOCK) == LOW); //HIGHを待つ while (digitalRead(KDATA) == LOW); //HIGHを待つ attachInterrupt(digitalPinToInterrupt(KCLOCK), keyCodeInt, FALLING); break; } }