IR Remote and IR Receiver for KODI (Arduino sketch)
Hi Lattepanders! If you want to control Kodi with an IR remote this is for you.
Works on all versions of LattePanda.
SOFTWARE
KODI - Open Source Home Theater Software:
https://kodi.tv/download
To run Kodi when Windows starts:
Put a Kodi.exe shortcut in the startup folder (Win + R | shell:startup)
To run Kodi when Windows starts and bypass the explorer shell:
Run the Group Policy Editor (gpedit.msc), then navigate to:
User Configuration -> Administrative Templates -> System and then select “Custom User Interface”
Enable it and enter the entire path of Kodi.exe
(ie: C:\Program Files (x86)\Kodi\Kodi.exe)
*To get back into Windows from Kodi. Exit Kodi and then start the task manager (Ctrl:Alt:Del) and run task ‘explorer.exe’
Arduino IDE sketch & Libraries (IRremote & Keyboard):
Download from Google Drive: https://drive.google.com/file/d/1WGziGu ... lkzps/view
Extract the two libraries folders (IRreceiver, Keyboard) into "C:\Program Files (x86)\Arduino\libraries"Extract the IR_Receiver_for_KODI folder into "Documents\Arduino"Open "IR_Receiver_for_KODI.ino" with the Arduino IDEUpload the skecth (make sure the Arduino Leonardo board and their COM port is selected in Tools)
Sketch Code:
*Note: The remote IR codes are from the "Gravity: IR Kit for Arduino" remote https://www.dfrobot.com/product-366.html
If you are using another remote just monitor the serial output and press the remote buttons. Then change the HEXA codes in the ( REMOTE IR CODES ) section.
/*
* Using a IR Remote and IR Receiver to control KODI
* by Luis N.C
* ver 1.0
*/
/*-----( INCLUDING THE LIBRARIES )-----*/
#include <IRremote.h>
#include <Keyboard.h>
/*-----( REMOTE IR CODES )-----*/
#define power 0xFD00FF // Power
#define power_1 0xB2EEDF3D // Power
#define func_stop 0xFD40BF // Func/Stop
#define func_stop_1 0x2C87261 // Func/Stop
#define pause_play 0xFDA05F // >||
#define pause_play_1 0xA6B913BD // >||
#define foward 0xFD609F // >>|
#define foward_1 0xD0529225 // >>|
#define backward 0xFD20DF // |<<
#define backward_1 0x1644C1C1 // |<<
#define vol_up 0xFD807F // VOL+
#define vol_up_1 0xC9C3741 // VOL+
#define vol_down 0xFD906F // VOL-
#define vol_down_1 0x925D5B5D // VOL-
#define up_arrow 0xFD50AF // ^
#define up_arrow_1 0xCB3D6F7D // ^
#define down_arrow 0xFD10EF // v
#define down_arrow_1 0x1E90961 // v
#define st_rept 0xFD708F // ST/REPT
#define st_rept_1 0x6BFD8B01 // ST/REPT
#define eq 0xFDB04F // EQ
#define eq_1 0x42640C99 // EQ
#define button_0 0xFD30CF // 0
#define button_0_1 0xB1EFBA9D // 0
#define button_1 0xFD08F7 // 1
#define button_1_1 0xDEE522C1 // 1
#define button_2 0xFD8877 // 2
#define button_2_1 0x6F5974BD // 2
#define button_3 0xFD48B7 // 3
#define button_3_1 0x986FB325 // 3
#define button_4 0xFD28D7 // 4
#define button_4_1 0xCBD2CCFD // 4
#define button_5 0xFDA857 // 5
#define button_5_1 0x25802501 // 5
#define button_6 0xFD6897 // 6
#define button_6_1 0x85E09D61 // 6
#define button_7 0xFD18E7 // 7
#define button_7_1 0xC76EF4E5 // 7
#define button_8 0xFD9867 // 8
#define button_8_1 0x57E346E1 // 8
#define button_9 0xFD58A7 // 9
#define button_9_1 0x90C35B01 // 9
#define hold_press 0xFFFFFFFF // Button press holded
/*-----( GLOBAL VARIABLES )-----*/
int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11
long unsigned int lastCode; // Save the last remote code for REPEAT
/*-----( DECLARE OBJECTS )-----*/
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'
/*----( SETUP: RUNS ONCE )----*/
void setup()
{
Keyboard.begin();
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
/*--( END SETUP )---*/
/*----( LOOP: RUNS CONSTANTLY )----*/
void loop()
{
if (irrecv.decode(&results)) // Have we received an IR signal?
{
translateIR();
irrecv.resume(); // Receive the next value
}
}
/* --(END MAIN LOOP )-- */
/*-----( FUNCTIONS )-----*/
void translateIR() // Takes action based on IR code received
// Describing Remote IR codes, sending Keyboard presses to control KODI
{
if(results.value == hold_press)
{
Serial.println(" REPEAT");
results.value = lastCode;
}
switch(results.value)
{
case power: // KODI Shutdown menu-Show preset(Music Visualisation)
lastCode = results.value, HEX;
Serial.print("POWER");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('s');
Keyboard.release('s');
break;
case power_1: // KODI Shutdown menu-Show preset(Music Visualisation)
lastCode = results.value, HEX;
Serial.print("POWER");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('s');
Keyboard.release('s');
break;
case func_stop: // Stop
lastCode = results.value, HEX;
Serial.print("FUNC/STOP");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('x');
Keyboard.release('x');
break;
case func_stop_1: // Stop
lastCode = results.value, HEX;
Serial.print("FUNC/STOP");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('x');
Keyboard.release('x');
break;
case pause_play: // Pause/Play-Current playlist window (video & music listings)-Highlight (File manager)
lastCode = results.value, HEX;
Serial.print(">||");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press((char) 32);
Keyboard.release((char) 32);
break;
case pause_play_1: // Pause/Play-Current playlist window (video & music listings)-Highlight (File manager)
lastCode = results.value, HEX;
Serial.print(">||");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press((char) 32);
Keyboard.release((char) 32);
break;
case foward: // Fast forward
lastCode = results.value, HEX;
Serial.print(">>|");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('f');
Keyboard.release('f');
break;
case foward_1: // Fast forward
lastCode = results.value, HEX;
Serial.print(">>|");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('f');
Keyboard.release('f');
break;
case backward: // Rewind - Rename (File manager)
lastCode = results.value, HEX;
Serial.print("|<<");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('r');
Keyboard.release('r');
break;
case backward_1: // Rewind - Rename (File manager)
lastCode = results.value, HEX;
Serial.print("|<<");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('r');
Keyboard.release('r');
break;
case vol_up: // Volume up
lastCode = results.value, HEX;
Serial.print("VOL+");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press((char) 223);
Keyboard.release((char) 223);
break;
case vol_up_1: // Volume up
lastCode = results.value, HEX;
Serial.print("VOL+");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press((char) 223);
Keyboard.release((char) 223);
break;
case vol_down: // Volume down
lastCode = results.value, HEX;
Serial.print("VOL-");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press((char) 222);
Keyboard.release((char) 222);
break;
case vol_down_1: // Volume down
lastCode = results.value, HEX;
Serial.print("VOL-");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press((char) 222);
Keyboard.release((char) 222);
break;
case up_arrow: // Page up - Skip to next queued video or next chapter if no videos are queued
lastCode = results.value, HEX;
Serial.print("^");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_PAGE_UP);
Keyboard.release(KEY_PAGE_UP);
break;
case up_arrow_1: // Page up - Skip to next queued video or next chapter if no videos are queued
lastCode = results.value, HEX;
Serial.print("^");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_PAGE_UP);
Keyboard.release(KEY_PAGE_UP);
break;
case down_arrow: // Page down - Skip to previous queued video or previous chapter if no videos are queued
lastCode = results.value, HEX;
Serial.print("v");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_PAGE_DOWN);
Keyboard.release(KEY_PAGE_DOWN);
break;
case down_arrow_1: // Page down - Skip to previous queued video or previous chapter if no videos are queued
lastCode = results.value, HEX;
Serial.print("v");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_PAGE_DOWN);
Keyboard.release(KEY_PAGE_DOWN);
break;
case st_rept: // Contextual menu - Playlist
lastCode = results.value, HEX;
Serial.print("ST/REPT");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('c');
Keyboard.release('c');
break;
case st_rept_1: // Contextual menu - Playlist
lastCode = results.value, HEX;
Serial.print("ST/REPT");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press('c');
Keyboard.release('c');
break;
case eq: // MUTE
lastCode = results.value, HEX;
Serial.print("EQ");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_F8);
Keyboard.release(KEY_F8);
break;
case eq_1: // MUTE
lastCode = results.value, HEX;
Serial.print("EQ");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_F8);
Keyboard.release(KEY_F8);
break;
case button_0: // Back
lastCode = results.value, HEX;
Serial.print("0");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_BACKSPACE);
Keyboard.release(KEY_BACKSPACE);
break;
case button_0_1: // Back
lastCode = results.value, HEX;
Serial.print("0");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_BACKSPACE);
Keyboard.release(KEY_BACKSPACE);
break;
case button_1: // None
lastCode = results.value, HEX;
Serial.print("1");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('1');
//Keyboard.release('1');
break;
case button_1_1: // None
lastCode = results.value, HEX;
Serial.print("1");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('1');
//Keyboard.release('1');
break;
case button_2: // Up - Seek step forward 10min OR Next chapter (videos)-Channel up (live TV)
lastCode = results.value, HEX;
Serial.print("2");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_UP_ARROW);
Keyboard.release(KEY_UP_ARROW);
break;
case button_2_1: // Up - Seek step forward 10min OR Next chapter (videos)-Channel up (live TV)
lastCode = results.value, HEX;
Serial.print("2");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_UP_ARROW);
Keyboard.release(KEY_UP_ARROW);
break;
case button_3: // None
lastCode = results.value, HEX;
Serial.print("3");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('3');
//Keyboard.release('3');
break;
case button_3_1: // None
lastCode = results.value, HEX;
Serial.print("3");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('3');
//Keyboard.release('3');
break;
case button_4: // Left - Seek step backward - Prev channel group (live TV)
lastCode = results.value, HEX;
Serial.print("4");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_LEFT_ARROW);
Keyboard.release(KEY_LEFT_ARROW);
break;
case button_4_1: // Left - Seek step backward - Prev channel group (live TV)
lastCode = results.value, HEX;
Serial.print("4");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_LEFT_ARROW);
Keyboard.release(KEY_LEFT_ARROW);
break;
case button_5: // Select(Enter) - Player controls (OSD)
lastCode = results.value, HEX;
Serial.print("5");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_RETURN);
Keyboard.release(KEY_RETURN);
break;
case button_5_1: // Select(Enter) - Player controls (OSD)
lastCode = results.value, HEX;
Serial.print("5");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_RETURN);
Keyboard.release(KEY_RETURN);
break;
case button_6: // Right - Seek step forward - Next channel group (live TV)
lastCode = results.value, HEX;
Serial.print("6");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_RIGHT_ARROW);
Keyboard.release(KEY_RIGHT_ARROW);
break;
case button_6_1: // Right - Seek step forward - Next channel group (live TV)
lastCode = results.value, HEX;
Serial.print("6");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_RIGHT_ARROW);
Keyboard.release(KEY_RIGHT_ARROW);
break;
case button_7: // None
lastCode = results.value, HEX;
Serial.print("7");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('7');
//Keyboard.release('7');
break;
case button_7_1: // None
lastCode = results.value, HEX;
Serial.print("7");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('7');
//Keyboard.release('7');
break;
case button_8: // Down - Step back 10min OR Prev chapter (videos) - Channel down (live TV)
lastCode = results.value, HEX;
Serial.print("8");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_DOWN_ARROW);
Keyboard.release(KEY_DOWN_ARROW);
break;
case button_8_1: // Down - Step back 10min OR Prev chapter (videos) - Channel down (live TV)
lastCode = results.value, HEX;
Serial.print("8");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
Keyboard.press(KEY_DOWN_ARROW);
Keyboard.release(KEY_DOWN_ARROW);
break;
case button_9: // None
lastCode = results.value, HEX;
Serial.print("9");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('9');
//Keyboard.release('9');
break;
case button_9_1: // None
lastCode = results.value, HEX;
Serial.print("9");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
//Keyboard.press('9');
//Keyboard.release('9');
break;
default:
Serial.print("UNREGISTERED CODE");
Serial.print("\t");
Serial.print("Code:0x");
Serial.println(results.value, HEX);
}// END CASE SWITCH
delay(250); // Do not get immediate repeat
}
/*-----( END FUNCTIONS )-----*/
HARDWARE
IR remote & IR receiver for Arduino:
Gravity: IR Kit for Arduino: https://www.dfrobot.com/product-366.html
IR receiver connection:
*Note: I am not responsible for damages caused by an incorrect connection.
The receiver have 3 pins/cables: Black is GND - Red is 5v - Green is Signal
- For the first version of the LattePanda SBC just connect to the 3 Pin header "D11" IR_Receiver_LattePanda.jpg (150.32 KiB) Viewed 8006 times - For the LattePanda Alpha you need to modify the cable in order to change it for male jumper terminations.
IR Remote Keymap:
Remote buttons - Kodi keys/actions
POWER = KODI Shutdown menu - Show preset(Music Visualisation)
FUNC/STOP = Stop
>|| = Pause/Play - Current playlist window (video & music listings)-Highlight (File manager)
>>| = Fast forward
|<< = Rewind - Rename (File manager)
VOL+ = Volume up
VOL- = Volume down
EQ = MUTE
UP_ARROW = Page up - Skip to next queued video or next chapter if no videos are queued
DOWN ARROW = Page down - Skip to previous queued video or previous chapter if no videos are queued
ST_REPT = Contextual menu - Playlist
0 = Back
1 = None
2 = Up - Seek step forward 10min OR Next chapter (videos)-Channel up (live TV)
3 = None
4 = Left - Seek step backward - Prev channel group (live TV)
5 = Select(Enter) - Player controls (OSD)
6 = Right - Seek step forward - Next channel group (live TV)
7 = None
8 = Down - Step back 10min OR Prev chapter (videos) - Channel down (live TV)
9 = None