nukeKeyboard/arduino_micro_code/arduino_micro_code.ino

259 lines
5.7 KiB
C++

#include <Keyboard.h>
#include <Mouse.h>
#include <SoftwareSerial.h>
// 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();
}
}