Pro Micro as IR HID controller for pc periodically stops working properly.

Hello!

So I have this random issue with my DIY "Flirc" built one pro micro clone. It consits of IR Reciver and a an external diode so nothing complicated. When connect to the PC it can work fine for few hours to suddenly stop receiving IR messages from the remote. I have to walk up the receiver and press a button on my remote for a few times to get a reaction.

What tried to do is:

  1. unplug and plug the usb - no change
  2. restarting pc - no change
  3. trying different USB port (all 2.0 but i had it plugged to a 3.0 for a while in the beginning it would have the same problem sometimes)
  4. different remote sending the same ir singlas - no change
  5. moving the receiver to a different spot (0.5m every direction)
  6. connecting to a different pc - works fine on pc no.2, but plugged back to pc no.1 and issue still persists.

What works is simply wait (few minutes) and it starts working properly again.

Of course during the "fritz time" pc works fine, other usb devices work properly.

ANY suggestion would be much appreciated

and of course the code:

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>
#include <Keyboard.h>


int RECV_PIN = 10;
unsigned long recv_tmp;
bool tv = 1;
int ctrlLed = 9;
int repeat = 0;
bool repeatCont = false;
//unsigned long time;
//int timeDif;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  // In case the interrupt driver crashes on setup, give a clue
  // to the user what's going on.
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
  pinMode(ctrlLed, OUTPUT);
  Keyboard.begin();
}

void button() {
  
}

void loop() {

  
  
  if (tv)
    {
        digitalWrite(ctrlLed, LOW);
       // Serial.println("TV Mode");
    } else 
      {
        digitalWrite(ctrlLed, HIGH);
       // Serial.println("PC Mode");
       
      }
      
  if (irrecv.decode(&results)) {

    if (results.value != 0xFFFFFFFF){
      recv_tmp = results.value;
      repeat = 0;                         //repetition countr (acts as debouncer also)
      repeatCont = false;                 //continues press of a button
      }
      else {
       repeat++; 
       if (repeat > 4) {
        repeatCont = true;
        }
       
       
      } 
      //Serial.println(results.value, HEX);
      
    
    
    
    
    if (repeat == 0 or repeatCont){
      
    if (recv_tmp == 0x20DF4EB1){
      if (tv) {
        tv=false;
        } else {
          tv=true;
        }
           
     }
        
     else if (tv == false)
     {
      switch (recv_tmp) 
         {
        case 0x20DF10EF: //power 
        case 0x20DFD02F: //input
        case 0x20DF807F: //channel-
        case 0x20DF00FF: //channel+
        
            Serial.println("TV");
            digitalWrite(ctrlLed, LOW);
            tv = true;
            break;     
                 
         case 0x20DF02FD:
            Serial.println("gora");
            Keyboard.write(218);
            break;
                       
         case 0x20DF827D:
            Serial.println("dol");
            Keyboard.write(217);
            break;
                    
         case 0x20DFE01F:
            Serial.println("lewo");
            Keyboard.write(216);
            break;   
                
         case 0x20DF609F:
            Serial.println("prawo");
            Keyboard.write(215);
            break;
        
         case 0x20DF22DD:
            Serial.println("ok");
            Keyboard.write(176);
            break;

         case 0x20DF14EB:
            Serial.println("back");
            Keyboard.write(178);
            break; 
         case 0x20DF40BF:
            Serial.println("+");
            Keyboard.write(43);
            break;
            
         case 0x20DFC03F:
            Serial.println("-");
            Keyboard.write(45);
            break;

         case 0x20DF0DF2:
            Serial.println("play");
            Keyboard.write(112);
            break;

         case 0x20DF8D72:
            Serial.println("stop");
            Keyboard.write(120);
            break;

        case 0x20DFDA25:
            Serial.println("exit");
            Keyboard.press(KEY_ESC);
            delay(20);
            Keyboard.releaseAll();
            break;
        
        case 0x20DF8679:
            Serial.println("blue");
            Keyboard.write(99);
            break;
        
        case 0x20DF9C63:
            Serial.println("subtitle");
            Keyboard.write(108);
            break;

        case 0x20DF8976:
            Serial.println("AD");
            Keyboard.write(119);
            break;
     
        case 0x20DF906F:
            Serial.println("MUTE");
            Keyboard.press(KEY_F8);
            delay(20);
            Keyboard.releaseAll();
            break;
      /*
        case 0x20DF8976:
            Serial.println("AD");
            Keyboard.write(119);
            break;
      
        case 0x20DF8976:
            Serial.println("AD");
            Keyboard.write(119);
            break;                                    
      */
         default:
            Serial.println(results.value, HEX);
            break;
         
         
       }
     }
    }
     
    irrecv.resume(); // Receive the next value
    
         
    
  }
  delay(150);
}

What do you see on the serial console while and before you have that problem?

  1. unplug and plug the usb - no change

Do I get that right, if the reception is tuck you can unplug the Micro and re-plug it in and the still don't get any signal? Or does it work again for a few hours and then start to make problems again?

If you can unplug it and it doesn't reset to a working state, you probably have a hardware problem. Post schematics/wiring diagram of your setup!

Why do you think you need the delay() call?

pylon:
What do you see on the serial console while and before you have that problem?

First of all the pro micro blinks it's TX/RX built in diode when the receiver receives any ir signal. While having issue:
if I move my remote about 10cm from the receiver it recognizes about 1 in every 5 key presses (it blinks an RX/TX diode). When it does, it usually prints the right message according to the button pressed, but once in a while it prints out a hex that definitely does not match my LG remote's signals.

If you ask about this part of the code:

void setup()
{
  Serial.begin(9600);
  // In case the interrupt driver crashes on setup, give a clue
  // to the user what's going on.
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
  pinMode(ctrlLed, OUTPUT);
  Keyboard.begin();
}

it doesn't print out any of these messages (it never did). It's a leftover from example code from the llibrary. Neve actually noticed it until now..

pylon:
Do I get that right, if the reception is tuck you can unplug the Micro and re-plug it in and the still don't get any signal? Or does it work again for a few hours and then start to make problems again?

Yes. Plugging and unplugging usually does nothing to change the situation. One time it did fixed problem though..

Why do you think you need the delay() call?

Once again - leftover code from example from IR library. I assumed it's there to avoid fake double presses. It still didn't work 100% and I had to devise a workaround.

I've attached a photo of the whole "system".

Just a quick thought - is it possible that USB voltage on PC I'm experiencing the error, drops below 5 Volts and it causes the IR receiver to akt all funky?

Just a quick thought - is it possible that USB voltage on PC I'm experiencing the error, drops below 5 Volts and it causes the IR receiver to akt all funky?

Although not impossible, I actually doubt that this is the reason for that problem.

it doesn't print out any of these messages (it never did). It's a leftover from example code from the llibrary. Neve actually noticed it until now..

Insert this line in your setup():

  while (! Serial);

This waits until the USB serial code becomes active.

Yes. Plugging and unplugging usually does nothing to change the situation. One time it did fixed problem though..

This means it's not a problem of your code or your Arduino hardware. Check your LG remote!

First of all thank you for the input. I really appreciate it.

Second I will try try to wait for the serial and see what's going on there.

The remote is fine. I've tried two other (all Lg TV's in the house :))

Got rid of the delay() and everything works fine (even better responsiveness).

I've also got my hands on datasheet for the IR receiver and the producer says that I should use a 200 Ohm resistor on VCC pin and 4,7uF capacitor between the VCC and GND pin for current stabilization.

I'll try those and get back to You.

P.S. I've stumbled on this topic:
URL

There's something about overfilling the buffers of MCU. Can it apply in my case?

There's something about overfilling the buffers of MCU. Can it apply in my case?

That's even wrong for the question asked.

It might be that the serial buffer overflows because the questioner prints every code received over a slow serial interface in HEX. If the code is repeated quite quickly this fills up the sending serial buffer and once that's full, the Arduino blocks untill it gets cleared.

In your description of the problem you didnt' write about that happening only if you have a high repeating rate.
And the USB serial interface gets cleared much faster than a hardware serial interface (which is fixed to the baudrate).

Update and bump.

I've tried to use resistor and capacitor to stabilize the voltage going to IR sensor. As expected no change. Same thing keep happening. I'm of out ideas. If you guys have any other suggestion please let me know.

pylon:
...
It might be that the serial buffer overflows because the questioner prints every code received over a slow serial interface in HEX. If the code is repeated quite quickly this fills up the sending serial buffer and once that's full, the Arduino blocks untill it gets cleared.
..

Thank you for clarifying.

SOLUTION:

So I finally found the source of my problems. It was really stupid mistake, so I'm little embarrassed, but here it goes:

Pay attention to the frequency of your remote. LG (and, from what I gather, majority of TV manufacturers) uses 38 kHZ IR transmitters. Mine was 36 kHZ (suitable for RC5 remotes i.e.)

Switching receiver for TSOP 2238 (38 kHZ) solved the problem.

Thanks for every input!

here's something that helped me a lot:

I consider case closed :smiley:

WodzBorsuk:
So I finally found the source of my problems. It was really stupid mistake, so I'm little embarrassed, but here it goes:

Usually is. :grinning:

pert:
Mine was 36 kHZ (suitable for RC5 remotes i.e.)

Well, that one really is subtle!

pert:
I consider case closed :smiley:

Fair enough!