IR Remote and IR Receiver for KODI (Arduino sketch)
![userHead](/forum/images/userhead.png)
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