You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
13 KiB
332 lines
13 KiB
5 years ago
|
/* IRLib_P12_CYKM.h
|
||
|
Chris Young keyboard mouse protocol
|
||
|
See COPYRIGHT.txt and LICENSE.txt for license information (spoilers it's GPL 3)
|
||
|
|
||
|
This library implements a custom protocol for IRLib to assist in creating
|
||
|
Arduino based mouse and keyboard controls. Documentation will be updated soon.
|
||
|
|
||
|
Protocol information: Header 3100, 3100
|
||
|
Zero bit: 650, 650,
|
||
|
One bit: 650*3, 650, 38 kHz, stop=true
|
||
|
15 bits of data which means 34 intervals of marks and spaces
|
||
|
Description of bits high order to low order
|
||
|
3 bits: Command: 3 bits
|
||
|
0 mouse click
|
||
|
1 mouse hold
|
||
|
2 mouse move
|
||
|
3 mouse and keyboard toggle
|
||
|
4 keyboard hold
|
||
|
5 keyboard write
|
||
|
6 speed command
|
||
|
7 Custom devices
|
||
|
4 bits: Modifier one time use. Only valid for mouse click,
|
||
|
mouse hold and keyboard write and hold not toggles
|
||
|
1 Shift
|
||
|
2 Control
|
||
|
4 Alt
|
||
|
8 GUI
|
||
|
8 bits: data
|
||
|
If mouse click or hold or toggle
|
||
|
1 left click
|
||
|
2 right click
|
||
|
4 middle click
|
||
|
If mouse move
|
||
|
1 right, 2 left, 4 up, 8 down
|
||
|
0x10 wheel up, 0x20 wheel down
|
||
|
0x40 increase speed, 0x80 decrease speed
|
||
|
If keyboard hold or key write then ASCII or Arduino code
|
||
|
If speed command = absolute speed 0 to 255
|
||
|
If Toggle 255= clear everything
|
||
|
If custom devices… To be determined later.
|
||
|
*/
|
||
|
|
||
|
#define CYKM_MOUSE_CLICK 0x0000
|
||
|
#define CYKM_MOUSE_HOLD 0x1000
|
||
|
#define CYKM_MOUSE_MOVE 0x2000
|
||
|
#define CYKM_TOGGLE 0x3000
|
||
|
#define CYKM_KEY_HOLD 0x4000
|
||
|
#define CYKM_KEY_WRITE 0x5000
|
||
|
#define CYKM_SPEED 0x6000
|
||
|
#define CYKM_CUSTOM_DEVICE 0x7000
|
||
|
#define CYKM_SHIFT 0x100
|
||
|
#define CYKM_CONTROL 0x200
|
||
|
#define CYKM_ALT 0x400
|
||
|
#define CYKM_GUI 0x800
|
||
|
#define CYKM_LEFT_BUTTON 1
|
||
|
#define CYKM_RIGHT_BUTTON 2
|
||
|
#define CYKM_MIDDLE_BUTTON 4
|
||
|
#define CYKM_DIR_RIGHT 0x01
|
||
|
#define CYKM_DIR_LEFT 0x02
|
||
|
#define CYKM_DIR_UP 0x04
|
||
|
#define CYKM_DIR_DOWN 0x08
|
||
|
#define CYKM_WHEEL_UP 0x10
|
||
|
#define CYKM_WHEEL_DOWN 0x20
|
||
|
#define CYKM_SPEED_INCREASE 0x40
|
||
|
#define CYKM_SPEED_DECREASE 0x80
|
||
|
#define CYKM_TOGGLE_LEFT 0x01
|
||
|
#define CYKM_TOGGLE_RIGHT 0x02
|
||
|
#define CYKM_TOGGLE_MIDDLE 0x04
|
||
|
#define CYKM_TOGGLE_SHIFT 0x08
|
||
|
#define CYKM_TOGGLE_CONTROL 0x10
|
||
|
#define CYKM_TOGGLE_ALT 0x20
|
||
|
#define CYKM_TOGGLE_GUI 0x40
|
||
|
#define CYKM_TOGGLE_RESET 0xff
|
||
|
#ifndef IRLIB_PROTOCOL_12_H
|
||
|
#define IRLIB_PROTOCOL_12_H
|
||
|
#define IR_SEND_PROTOCOL_12 case 12: IRsendCYKM::send(data); break;
|
||
|
#define IR_DECODE_PROTOCOL_12 if(IRdecodeCYKM::decode()) return true;
|
||
|
#ifdef IRLIB_HAVE_COMBO
|
||
|
#define PV_IR_DECODE_PROTOCOL_12 ,public virtual IRdecodeCYKM
|
||
|
#define PV_IR_SEND_PROTOCOL_12 ,public virtual IRsendCYKM
|
||
|
#else
|
||
|
#define PV_IR_DECODE_PROTOCOL_12 public virtual IRdecodeCYKM
|
||
|
#define PV_IR_SEND_PROTOCOL_12 public virtual IRsendCYKM
|
||
|
#endif
|
||
|
|
||
|
#if defined(__AVR_ATmega32U4__) || defined(ARDUINO_SAM_DUE) || defined(ARDUINO_SAM_ZERO)
|
||
|
#include <Keyboard.h>
|
||
|
#include <Mouse.h>
|
||
|
#include <HID.h>
|
||
|
#endif
|
||
|
|
||
|
#ifdef IRLIBSENDBASE_H
|
||
|
class IRsendCYKM: public virtual IRsendBase {
|
||
|
public:
|
||
|
void send(uint32_t data) {
|
||
|
sendGeneric(data,15, 3100, 3100, 650, 650, 650*3, 650, 38, true);
|
||
|
delay(10);
|
||
|
};
|
||
|
};
|
||
|
#endif //IRLIBSENDBASE_H
|
||
|
|
||
|
#ifdef IRLIBDECODEBASE_H
|
||
|
class IRdecodeCYKM: public virtual IRdecodeBase {
|
||
|
public:
|
||
|
bool decode(void) {
|
||
|
IRLIB_ATTEMPT_MESSAGE(F("CYKM"));
|
||
|
if(!decodeGeneric(34,3100,3100,650,650*3,650)) return false;
|
||
|
protocolNum = CYKM;
|
||
|
parseValue();
|
||
|
return true;
|
||
|
}
|
||
|
virtual void dumpResults(void){
|
||
|
Serial.print(F("Gap=")); Serial.print(recvGlobal.decodeBuffer[0],DEC);
|
||
|
Serial.print(F(" CYKM decoded:")); Serial.print(value,HEX);Serial.print(" ");
|
||
|
switch (cmdType) {
|
||
|
case CYKM_MOUSE_CLICK: //deliberate fall through
|
||
|
case CYKM_MOUSE_HOLD:
|
||
|
Serial.print(F("Mouse "));
|
||
|
showMods();
|
||
|
switch(cmdData) {
|
||
|
case CYKM_LEFT_BUTTON: Serial.print(F("left"));break;
|
||
|
case CYKM_RIGHT_BUTTON: Serial.print(F("right"));break;
|
||
|
case CYKM_MIDDLE_BUTTON: Serial.print(F("middle"));break;
|
||
|
default: Serial.println(F("ERROR"));
|
||
|
};
|
||
|
if (cmdType==CYKM_MOUSE_CLICK)Serial.println(F(" click")); else Serial.println(F(" hold"));
|
||
|
break;
|
||
|
case CYKM_MOUSE_MOVE:
|
||
|
if(cmdData & (CYKM_DIR_RIGHT|CYKM_DIR_LEFT|CYKM_DIR_UP|CYKM_DIR_DOWN)){
|
||
|
Serial.print(F("Mouse move "));
|
||
|
if(cmdData & CYKM_DIR_RIGHT) Serial.print(F("right ")); else if(cmdData & CYKM_DIR_LEFT) Serial.print(F("left "));
|
||
|
if(cmdData & CYKM_DIR_UP) Serial.print(F("up ")); else if(cmdData & CYKM_DIR_DOWN) Serial.print(F("down "));
|
||
|
} else {
|
||
|
if(cmdData & (CYKM_WHEEL_UP|CYKM_WHEEL_DOWN)){
|
||
|
Serial.print(F("Mouse Wheel "));
|
||
|
if(cmdData & CYKM_DIR_UP) Serial.print(F("up ")); else Serial.print(F("down "));
|
||
|
} else {
|
||
|
if (cmdData & CYKM_SPEED_DECREASE) {
|
||
|
Serial.print(F("Decrease speed from "));
|
||
|
} else {
|
||
|
if (cmdData & CYKM_SPEED_INCREASE) {
|
||
|
Serial.print(F("Increase speed from "));
|
||
|
} else Serial.println(F("Mouse Move Error"));
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
Serial.println(mouseSpeed,DEC);
|
||
|
break;
|
||
|
case CYKM_TOGGLE:
|
||
|
Serial.print(F("Toggle"));
|
||
|
if(cmdData==CYKM_TOGGLE_RESET) {
|
||
|
Serial.print(F(" clear all"));
|
||
|
} else {
|
||
|
if(cmdData & CYKM_TOGGLE_LEFT) Serial.print(F(" left button"));
|
||
|
if(cmdData & CYKM_TOGGLE_RIGHT) Serial.print(F(" right button"));
|
||
|
if(cmdData & CYKM_TOGGLE_MIDDLE) Serial.print(F(" middle button"));
|
||
|
if(cmdData & CYKM_TOGGLE_SHIFT ) Serial.print(F(" shift key"));
|
||
|
if(cmdData & CYKM_TOGGLE_CONTROL) Serial.print(F(" control key"));
|
||
|
if(cmdData & CYKM_TOGGLE_ALT) Serial.print(F(" alt key"));
|
||
|
if(cmdData & CYKM_TOGGLE_GUI) Serial.print(F(" GUI"));
|
||
|
}
|
||
|
Serial.print(F(" Bits= "));Serial.println(toggleData,HEX);
|
||
|
break;
|
||
|
case CYKM_KEY_WRITE:
|
||
|
case CYKM_KEY_HOLD:
|
||
|
if (cmdType==CYKM_KEY_WRITE) {
|
||
|
Serial.print(F("Key write"));showMods();
|
||
|
} else {
|
||
|
Serial.print(F("Key hold"));
|
||
|
};
|
||
|
Serial.print(F(" value:")); Serial.print(cmdData,HEX); Serial.print(" "); Serial.print(cmdData,DEC);
|
||
|
if((cmdData>31) && (cmdData< 128)) {Serial.print(" '"); Serial.write(cmdData);Serial.print("'");};
|
||
|
Serial.println();
|
||
|
break;
|
||
|
case CYKM_SPEED:
|
||
|
Serial.print(F("Change speed to:")); Serial.println(cmdData,DEC);
|
||
|
break;
|
||
|
case CYKM_CUSTOM_DEVICE: Serial.print(F("Custom Device data:")); Serial.println(cmdData,HEX);
|
||
|
};
|
||
|
|
||
|
};
|
||
|
void doMouseKeyboard(void){
|
||
|
#if defined(__AVR_ATmega32U4__) || defined(ARDUINO_SAM_DUE) || defined(ARDUINO_SAM_ZERO)
|
||
|
int8_t Button;
|
||
|
int8_t xDir=0; int8_t yDir=0; int8_t wDir=0;
|
||
|
switch (cmdType) {
|
||
|
case CYKM_MOUSE_CLICK: //deliberate fall through
|
||
|
case CYKM_MOUSE_HOLD:
|
||
|
doMods (true); //presses modifier key
|
||
|
switch(cmdData) {
|
||
|
case CYKM_LEFT_BUTTON: Button= MOUSE_LEFT; break;
|
||
|
case CYKM_RIGHT_BUTTON: Button= MOUSE_RIGHT; break;
|
||
|
case CYKM_MIDDLE_BUTTON: Button= MOUSE_MIDDLE; break;
|
||
|
};
|
||
|
//only release if this was a click and not a hold
|
||
|
if (cmdType==CYKM_MOUSE_CLICK) {
|
||
|
Mouse.click(Button); doMods(false);
|
||
|
} else Mouse.press(Button);
|
||
|
break;
|
||
|
case CYKM_MOUSE_MOVE:
|
||
|
if(cmdData & CYKM_DIR_RIGHT) xDir=mouseSpeed; else if(cmdData & CYKM_DIR_LEFT) xDir= -mouseSpeed;
|
||
|
//NOTE: Upper left corner is 0, 0 and positive numbers go down
|
||
|
if(cmdData & CYKM_DIR_UP) yDir=-mouseSpeed; else if(cmdData & CYKM_DIR_DOWN) yDir= mouseSpeed;
|
||
|
if(cmdData & CYKM_WHEEL_UP) wDir=1; else if(cmdData & CYKM_WHEEL_DOWN) wDir= -1;
|
||
|
if(xDir || yDir || wDir) {
|
||
|
Mouse.move(xDir,yDir,wDir);
|
||
|
} else {
|
||
|
if ( (cmdData & CYKM_SPEED_DECREASE) && (mouseSpeed>0) ) mouseSpeed--;
|
||
|
if ( (cmdData & CYKM_SPEED_INCREASE) && (mouseSpeed<=255) ) mouseSpeed++;
|
||
|
};
|
||
|
break;
|
||
|
case CYKM_TOGGLE:
|
||
|
if(cmdData==CYKM_TOGGLE_RESET) {
|
||
|
Mouse.release(MOUSE_LEFT);
|
||
|
Mouse.release(MOUSE_RIGHT);
|
||
|
Mouse.release(MOUSE_MIDDLE);
|
||
|
Keyboard.releaseAll();
|
||
|
} else {
|
||
|
if(cmdData & CYKM_TOGGLE_LEFT) {if(toggleData & CYKM_TOGGLE_LEFT) Mouse.release(MOUSE_LEFT);else Mouse.press(MOUSE_LEFT);};
|
||
|
if(cmdData & CYKM_TOGGLE_RIGHT) {if(toggleData & CYKM_TOGGLE_RIGHT) Mouse.release(MOUSE_RIGHT);else Mouse.press(MOUSE_RIGHT);};
|
||
|
if(cmdData & CYKM_TOGGLE_MIDDLE) {if(toggleData & CYKM_TOGGLE_MIDDLE) Mouse.release(MOUSE_MIDDLE);else Mouse.press(MOUSE_MIDDLE);};
|
||
|
if(cmdData & CYKM_TOGGLE_SHIFT) {if(toggleData & CYKM_TOGGLE_SHIFT) Keyboard.release(KEY_LEFT_SHIFT);else Keyboard.press(KEY_LEFT_SHIFT);};
|
||
|
if(cmdData & CYKM_TOGGLE_CONTROL) {
|
||
|
if(toggleData & CYKM_TOGGLE_CONTROL) Keyboard.release(KEY_LEFT_CTRL);else Keyboard.press(KEY_LEFT_CTRL);
|
||
|
};
|
||
|
if(cmdData & CYKM_TOGGLE_ALT) {if(toggleData & CYKM_TOGGLE_ALT) Keyboard.release(KEY_LEFT_ALT);else Keyboard.press(KEY_LEFT_ALT);};
|
||
|
if(cmdData & CYKM_TOGGLE_GUI) {if(toggleData & CYKM_TOGGLE_GUI) Keyboard.release(KEY_LEFT_GUI);else Keyboard.press(KEY_LEFT_GUI);};
|
||
|
toggleData= toggleData ^ cmdData;
|
||
|
}
|
||
|
break;
|
||
|
case CYKM_KEY_WRITE:
|
||
|
doMods(true); //press modifier key
|
||
|
Keyboard.write(cmdData);
|
||
|
doMods(false); //release modifier key
|
||
|
break;
|
||
|
case CYKM_KEY_HOLD:
|
||
|
doMods(true);//press modifier key
|
||
|
Keyboard.press(cmdData);
|
||
|
//Do not release modifier
|
||
|
break;
|
||
|
case CYKM_SPEED:
|
||
|
mouseSpeed=cmdData;
|
||
|
break;
|
||
|
// case CYKM_CUSTOM_DEVICE:
|
||
|
// break;
|
||
|
};
|
||
|
#endif
|
||
|
};
|
||
|
void doMouseKeyboard(uint16_t code) {
|
||
|
#if defined(__AVR_ATmega32U4__) || defined(ARDUINO_SAM_DUE) || defined(ARDUINO_SAM_ZERO)
|
||
|
value=code;
|
||
|
parseValue();
|
||
|
doMouseKeyboard();
|
||
|
#endif
|
||
|
};
|
||
|
uint8_t mouseSpeed;
|
||
|
uint8_t toggleData;
|
||
|
uint16_t cmdType;
|
||
|
uint16_t cmdData;
|
||
|
private:
|
||
|
void showMods(void){
|
||
|
if(value & CYKM_SHIFT) Serial.print(F(" shift"));
|
||
|
if(value & CYKM_CONTROL) Serial.print(F(" control"));
|
||
|
if(value & CYKM_ALT) Serial.print(F(" alt"));
|
||
|
if(value & CYKM_GUI) Serial.print(F(" GUI"));
|
||
|
};
|
||
|
void doMods(bool Press){
|
||
|
#if defined(__AVR_ATmega32U4__) || defined(ARDUINO_SAM_DUE) || defined(ARDUINO_SAM_ZERO)
|
||
|
if(value & CYKM_SHIFT) {if(Press) Keyboard.press(KEY_LEFT_SHIFT); else Keyboard.release(KEY_LEFT_SHIFT);}
|
||
|
if(value & CYKM_CONTROL) {if(Press) Keyboard.press(KEY_LEFT_CTRL); else Keyboard.release(KEY_LEFT_CTRL);}
|
||
|
if(value & CYKM_ALT) {if(Press) Keyboard.press(KEY_LEFT_ALT); else Keyboard.release(KEY_LEFT_ALT);}
|
||
|
if(value & CYKM_GUI) {if(Press) Keyboard.press(KEY_LEFT_GUI); else Keyboard.release(KEY_LEFT_GUI);}
|
||
|
#endif
|
||
|
};
|
||
|
void parseValue(void) {
|
||
|
cmdType= value & 0x7000; //highest order 3 bits command type
|
||
|
cmdData= value & 0xff; //lowest order 8 bits command data
|
||
|
//To get Shift,Control,Alt, GUI modifiers do (value & CYKM_SHIFT) etc.
|
||
|
};
|
||
|
};
|
||
|
|
||
|
#endif //IRLIBDECODEBASE_H
|
||
|
|
||
|
#define IRLIB_HAVE_COMBO
|
||
|
/*
|
||
|
If you have a board capable of using the "Keyboard.h" library
|
||
|
such as a Leonardo then these defines are already defined.
|
||
|
However suppose you want to transmit a signal for the up arrow
|
||
|
from an Arduino Uno you would need to look up the value.
|
||
|
We are going to presume that if KEY_LEFT_CTRL is not defined
|
||
|
then none of the are defined so we will define here for your convenience.
|
||
|
*/
|
||
|
#ifndef KEY_LEFT_CTRL
|
||
|
#define KEY_LEFT_CTRL 0x80
|
||
|
#define KEY_LEFT_SHIFT 0x81
|
||
|
#define KEY_LEFT_ALT 0x82
|
||
|
#define KEY_LEFT_GUI 0x83
|
||
|
#define KEY_RIGHT_CTRL 0x84
|
||
|
#define KEY_RIGHT_SHIFT 0x85
|
||
|
#define KEY_RIGHT_ALT 0x86
|
||
|
#define KEY_RIGHT_GUI 0x87
|
||
|
#define KEY_UP_ARROW 0xDA
|
||
|
#define KEY_DOWN_ARROW 0xD9
|
||
|
#define KEY_LEFT_ARROW 0xD8
|
||
|
#define KEY_RIGHT_ARROW 0xD7
|
||
|
#define KEY_BACKSPACE 0xB2
|
||
|
#define KEY_TAB 0xB3
|
||
|
#define KEY_RETURN 0xB0
|
||
|
#define KEY_ESC 0xB1
|
||
|
#define KEY_INSERT 0xD1
|
||
|
#define KEY_DELETE 0xD4
|
||
|
#define KEY_PAGE_UP 0xD3
|
||
|
#define KEY_PAGE_DOWN 0xD6
|
||
|
#define KEY_HOME 0xD2
|
||
|
#define KEY_END 0xD5
|
||
|
#define KEY_CAPS_LOCK 0xC1
|
||
|
#define KEY_F1 0xC2
|
||
|
#define KEY_F2 0xC3
|
||
|
#define KEY_F3 0xC4
|
||
|
#define KEY_F4 0xC5
|
||
|
#define KEY_F5 0xC6
|
||
|
#define KEY_F6 0xC7
|
||
|
#define KEY_F7 0xC8
|
||
|
#define KEY_F8 0xC9
|
||
|
#define KEY_F9 0xCA
|
||
|
#define KEY_F10 0xCB
|
||
|
#define KEY_F11 0xCC
|
||
|
#define KEY_F12 0xCD
|
||
|
#endif
|
||
|
|
||
|
#endif //IRLIB_PROTOCOL_12_H
|