Code for Arduino Micro/Leonardo/Yun

Here is the source code for Arduino Micro and other ATmega32u4 based boards.

/* Example program for from IRLib 2 – an Arduino library for infrared encoding and decoding
 * Version 2.0  April 2017 by Chris Young http://tech.cyborg5.com
 * "IRmouse" Control a PCs mouse or arrow keys using an IR remote
 */
#include <Mouse.h>
#include <Keyboard.h>
#include <IRLibAll.h>
#include <Adafruit_NeoPixel.h>
//The IR codes shown below are for the Adafruit mini remote
//which uses an easy protocol. The comments after each code refer to the buttons
//on that remote and not to their actual function on this device.
 
//Codes used by both mouse and arrow modes
#define CodeAlt   0xfd00ff //Vol-
#define CodeCtrl 0xfd807f //Play/Pause
#define CodeShift 0xfd40bf //Vol+
#define CodeRls   0xfda857 //5
#define CodeMode 0xfd9867 //8
 
//Used by mouse and arrow but have different meanings
#define CodeUp 0xfda05f //Up arrow
#define CodeDown 0xfdb04f //Down arrow
#define CodeLeft 0xfd10ef //Left arrow
#define CodeRight 0xfd50af //Right arrow
 
//Used only in mouse mode
#define CodeUpLf 0xfd20df //Set up
#define CodeUpRt 0xfd609f //Stop/mode
#define CodeLfClk 0xfd906f //Enter/save
#define CodeDnLf 0xfd30cf //0 10+
#define CodeDnRt 0xfd708f //Repeat
#define CodeLfDrag 0xfd08f7 //1
#define CodeRtDrag 0xfd8877 //2
#define CodeRtClk 0xfd48b7 //3
#define CodeFaster  0xfd28d7 //4
#define CodeScrUp 0xfd6897 //6
#define CodeSlower 0xfd18e7 //7
#define CodeScrDn 0xfd58a7 //9
 
//Arrow mode only
#define CodeHome 0xfd20df //Set up
#define CodePgUp 0xfd609f //Stop/mode
#define CodeEnter 0xfd906f //Enter/save
#define CodeEnd 0xfd30cf //0 10+
#define CodePgDn 0xfd708f //Repeat
#define CodeGUI 0xfd08f7 //1
#define CodeInsert 0xfd8877 //2
#define CodeDelete 0xfd48b7 //3
#define CodeBkSp 0xfd28d7 //4
#define CodeSpace 0xfd6897 //6
#define CodeEsc 0xfd18e7 //7
#define CodeTab 0xfd58a7 //9
 
#define Bright  16  //brightness of pixels
 
#define MOUSE_MODE 0
#define ARROW_MODE 1
#define MAX_MODE (ARROW_MODE+1)
 
#define MOUSE_LED 0
#define SHIFT_LED 1
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(2, 6, NEO_GRB + NEO_KHZ800);//Output pin 6
IRrecv myReceiver(11);  //Input pin 11
IRdecodeNEC myDecoder;
 
int Speed;
int Current_Mode;
char Control_State;
char Shift_State;
char Alt_State;
long Previous;
uint32_t Shift_Status, Mouse_Status;
 
void UpdateStatus () {
  Mouse_Status=0;
  Shift_Status=0;
  strip.setPixelColor(MOUSE_LED,Bright*Mouse.isPressed(MOUSE_LEFT),Bright*Current_Mode,Bright*Mouse.isPressed(MOUSE_RIGHT));
  strip.setPixelColor(SHIFT_LED,Bright*Alt_State,Bright*Control_State,Bright*Shift_State);
  strip.show();
};
//This Change_Mode routine is overly complex but it's a holdover from earlier code
//where I had three modes instead of two. Note we do not want to repeat feature
//on this function or on the toggle functions so we set Previous=0
void Change_Mode () {
  Current_Mode=(++Current_Mode) % MAX_MODE;
  Previous=0;   UpdateStatus(); delay(500);
};
 
void setup() {
  strip.begin();    strip.show(); 
  Shift_Status=0;   Mouse_Status=0;
  myReceiver.enableIRIn(); // Start the receiver
  Current_Mode=0;
  Control_State=0; Shift_State=0; Alt_State=0;
  Speed=8;  Previous=0;   UpdateStatus();
  Mouse.begin();
}
 
void Toggle_Mouse(int Button) {
  if(Mouse.isPressed(Button)) Mouse.release(Button); 
  else Mouse.press(Button);
  Previous=0; UpdateStatus();  delay(500);  
}
 
void Mouse_Mode() {
  switch (myDecoder.value) {
  case CodeLeft:       Mouse.move(-Speed,0,0);     break;
  case CodeRight:      Mouse.move( Speed,0,0);     break;
  case CodeUp:         Mouse.move(0,-Speed,0);     break;
  case CodeDown:       Mouse.move(0, Speed,0);     break;
  case CodeUpRt:       Mouse.move( Speed,-Speed,0);     break;
  case CodeUpLf:       Mouse.move(-Speed,-Speed,0);     break;
  case CodeDnLf:       Mouse.move(-Speed, Speed,0);     break;
  case CodeDnRt:       Mouse.move( Speed, Speed,0);     break;
  case CodeLfClk:      Mouse.release(MOUSE_LEFT);  Mouse.click(MOUSE_LEFT); delay(400);break;
  case CodeRtClk:      Mouse.release(MOUSE_RIGHT);  Mouse.click(MOUSE_RIGHT); delay(400);break;
  case CodeLfDrag:     Toggle_Mouse(MOUSE_LEFT);     break;
  case CodeRtDrag:     Toggle_Mouse(MOUSE_RIGHT);     break;
  case CodeFaster:     Speed=min(30,++Speed); delay(100); break;
  case CodeSlower:     Speed=max(1,--Speed); delay(100); break;
  case CodeScrUp:      Mouse.move(0,0,1); delay(100);    break;
  case CodeScrDn:      Mouse.move(0,0,-1); delay(100);     break;
  };
};
 
void Toggle_Key(char *Toggle,char Key) {
  if(*Toggle){
    Keyboard.release(Key);  *Toggle=0;
  }
  else{
    Keyboard.press(Key);    *Toggle=1;
  };
  Previous=0; UpdateStatus(); delay(500);
};
//Releases all held mouse buttons and toggle keys
void Release_All() {
  Keyboard.releaseAll();
  Mouse.release(MOUSE_LEFT);   Mouse.release(MOUSE_RIGHT);   Mouse.release(MOUSE_MIDDLE);
  Alt_State=0;   Control_State=0;   Shift_State=0;  
  UpdateStatus();
};
//In my experience some keys work better if you put a little extra delay.
void Key_Press (char Key,int D) {
  Keyboard.write(Key);   delay(150+D);
}
 
void Arrow_Mode() {
  switch (myDecoder.value) {
    case CodeLeft:   Key_Press(KEY_LEFT_ARROW,0); break;
    case CodeRight:  Key_Press(KEY_RIGHT_ARROW,0); break;
    case CodeUp:     Key_Press(KEY_UP_ARROW,0); break;
    case CodeDown:   Key_Press(KEY_DOWN_ARROW,0); break;
    case CodeInsert: Key_Press(KEY_INSERT,100); break;   
    case CodeDelete: Key_Press(KEY_DELETE,100); break;
    case CodeEnter:  Key_Press(KEY_RETURN,100); break;
    case CodeBkSp:   Key_Press(KEY_BACKSPACE,100); break;
    case CodePgUp:   Key_Press(KEY_PAGE_UP,200); break;
    case CodePgDn:   Key_Press(KEY_PAGE_DOWN,200); break;
    case CodeHome:   Key_Press(KEY_HOME,0); break;
    case CodeEnd:    Key_Press(KEY_END,0); break;
    case CodeGUI:    Key_Press(KEY_LEFT_GUI, 100); break;
    case CodeSpace:  Key_Press(32, 100); break;//ASCII space
    case CodeEsc:    Key_Press(KEY_ESC, 100); break;
    case CodeTab:    Key_Press(KEY_TAB, 100); break;
  };
};
/*
//You can uncomment and use this routine to send control characters such as
//control-z for an undo button or control-c for copy etc.
void Send_Control(char Key,int D) {
 Release_All(); Keyboard.press(KEY_LEFT_CTRL); 
 Keyboard.write(Key); Release_All();delay(150+D); Update ();
}
 */
void loop() {
  if (myReceiver.getResults()) {
    myDecoder.decode();
    //Adafruit remote uses NEC protocol which sends a special repeat code
    //if you are holding down the same button. We store each received code
    //in "Previous" so that we can properly handle repeat codes.
    if(myDecoder.value==0xffffffff)
       myDecoder.value=Previous;
    else
       Previous=myDecoder.value;
    switch(Current_Mode) {
      case MOUSE_MODE: Mouse_Mode(); break; 
      case ARROW_MODE: Arrow_Mode(); break; 
    }
    switch (myDecoder.value) {
      case CodeMode:  Change_Mode(); break;
      case CodeAlt:   Toggle_Key(&Alt_State,KEY_LEFT_ALT); break;
      case CodeShift: Toggle_Key(&Shift_State,KEY_LEFT_SHIFT); break;
      case CodeCtrl:  Toggle_Key(&Control_State,KEY_LEFT_CTRL); break;
      case CodeRls:   Release_All(); break;
    };
    myReceiver.enableIRIn(); // Re-Start the receiver
  }
}

This guide was first published on Apr 14, 2015. It was last updated on Apr 14, 2015.

This page (Source Code Listings) was last updated on Oct 13, 2021.

Text editor powered by tinymce.