#include #include #include // Setup --------------------------------------------- int SoftSerialRX = 8; int SoftSerialTX = 9; // Types --------------------------------------------- #define KEY_F13 0xF0 // 0x68 + 0x88 #define KEY_F14 0xF1 // 0x69 + 0x88 #define KEY_F15 0xF2 // 0x6A + 0x88 #define KEY_F16 0xF3 // 0x6B + 0x88 #define KEY_F17 0xF4 // 0x6C + 0x88 #define KEY_F18 0xF5 // 0x6D + 0x88 #define key_timeout 100 enum parse_mode{ none, regular_key, special_key, trackball_x, trackball_y, trackball_key }; // Globals ------------------------------------------- parse_mode ParseMode; SoftwareSerial KeyboardSerial(SoftSerialRX, SoftSerialTX); unsigned long TrackballY; unsigned long TrackballX; bool shift; bool mouse_left; bool mouse_middle; bool mouse_right; unsigned long time_since_last_key; // Functions ----------------------------------------- void setup() { digitalWrite(SoftSerialTX, HIGH); pinMode(SoftSerialRX, INPUT); pinMode(SoftSerialTX, OUTPUT); Serial.begin(2400); Keyboard.begin(); Mouse.begin(); ParseMode = parse_mode::none; KeyboardSerial.begin(2400); while (!Serial) { ; } TrackballX = 0; TrackballY = 0; shift = false; mouse_left = false; mouse_right = false; mouse_middle = false; time_since_last_key = millis(); } void parseRegularKey(unsigned long v) { char result; bool parsed = false; if ((v & 32) == 32) { shift = true; } else { shift = false; } if (v <= 126) { // main keyboard result = v; parsed = true; } // A few keys that need some adjustments to match their label. if (v == 13) result = '\n'; if (v == 94) result = '^'; if (v == 126) result = '~'; // tab if (v == 129){ result = 9; shift = false; parsed = true; } // shift+tab if (v == 130) { Keyboard.press(KEY_LEFT_SHIFT); Keyboard.press(KEY_TAB); parsed = false; } if (parsed == true) { Keyboard.print(result); } } void parseSpecialKey(unsigned long v) { switch(v) { case 49: Keyboard.press(KEY_HOME); break; case 50: // insert line Keyboard.write(KEY_HOME); Keyboard.write(KEY_RETURN); Keyboard.write(KEY_UP_ARROW); break; case 51: // delete line (using the vim way for this) // non-vim people might want to do: // END-SHIFT-HOME-BS or something... Keyboard.write(KEY_ESC); Keyboard.write('d'); Keyboard.write('d'); Keyboard.write('i'); break; case 53: // insert char - using this as regular insert. Keyboard.write(KEY_INSERT); break; case 54: // delete char - using this as regular delete. Keyboard.write(KEY_DELETE); break; case 48: // up / down arrow (they send the same keycode?!) Keyboard.write(KEY_UP_ARROW); break; case 120: Keyboard.write(KEY_RIGHT_ARROW); break; case 126: Keyboard.write(KEY_LEFT_ARROW); break; } // F1..F12 if ((v >= 86) && (v <= 97)) { Keyboard.write(v + 108); } if (v == 98) Keyboard.write(KEY_F13); if (v == 99) Keyboard.write(KEY_F14); if (v == 100) Keyboard.write(KEY_F14); // the 'cancel' key we'll use as ESC key, since there // is no actual key labeled escape. if (v == 101) Keyboard.write(KEY_ESC); } void parse_trackball(unsigned long x, unsigned long y) { Mouse.move(x, -y); } void parse_trackball_key(unsigned long v) { switch(v) { case 0x40: // T1 key Mouse.press(MOUSE_LEFT); mouse_left = true; //Serial.println("Pressed left mouse"); break; case 0x41: // T2 key Mouse.press(MOUSE_MIDDLE); //Serial.println("Pressed middle mouse"); mouse_middle = true; break; case 0x42: // T3 key Mouse.press(MOUSE_RIGHT); //Serial.println("Pressed right mouse"); mouse_right = true; break; } } void detect_key_release() { if ((millis() - time_since_last_key) > key_timeout) { Keyboard.releaseAll(); if (mouse_right == true) { Mouse.release(MOUSE_RIGHT); mouse_right = false; //Serial.println("Released right mouse"); } if (mouse_left == true) { Mouse.release(MOUSE_LEFT); mouse_left = false; //Serial.println("Released left mouse"); } if (mouse_middle == true) { Mouse.release(MOUSE_MIDDLE); mouse_middle = false; //Serial.println("Released middle mouse"); } } } void loop() { KeyboardSerial.listen(); if (KeyboardSerial.available()) { unsigned long v = KeyboardSerial.read(); switch (v) { case 0xA8: ParseMode = parse_mode::regular_key; Serial.println("Regular key"); break; case 0xA1: ParseMode = parse_mode::special_key; Serial.println("Special key"); break; case 0xA2: ParseMode = parse_mode::trackball_x; break; case 0xA4: ParseMode = parse_mode::trackball_key; break; default: if (ParseMode == parse_mode::regular_key) { parseRegularKey(v); } else if (ParseMode == parse_mode::special_key) { parseSpecialKey(v); } else if (ParseMode == parse_mode::trackball_x) { TrackballX = v; ParseMode = parse_mode::trackball_y; } else if (ParseMode == parse_mode::trackball_y) { TrackballY = v; ParseMode = parse_mode::none; parse_trackball(TrackballX, TrackballY); } else if (ParseMode == parse_mode::trackball_key) { parse_trackball_key(v); } break; } //Serial.println(v, BIN); //Serial.println(v, HEX); time_since_last_key = millis(); } else { detect_key_release(); } }