I’ve been knocking my head against the wall for a few days trying to get my Arduino Uno to receive IR signals from a 2nd gen Apple remote, and then control a standard Futaba servo with the received codes. It is a BoeBot application, so I am using the Board of Education shield with an IR receiver from Parallax running to pin 4 and the servo to pin 12. The problem I am having is that whenever I load Ken Shirriff’s IRremote.h library and the Servo.h library, I encounter a servo twitch.
Here’s a simple instance of the code that is giving me the issue:
It is powered by a 6V supply (4, 1.5V alkalines), and there is a common ground between the servo and the board.
Here are some things I’ve tried:
Using a different servo
Using different pins, for both the servo and IR receiver
Change the IRreceive.h library to interrupt with timer0, instead of timer2. (My thinking here is that there may have been a priority of operation, and I wanted to give the servo priority over the IR pin. This didn’t change anything though, and I’m pretty sure timer0 has higher priority anyhow…)
Wrap the IRremote.h timer ISR in a “detach.servo();” and “attach.servo();” command somehow, but I can’t seem to get the coding correct, and I’m not sure if this approach would work.
I should mention that the IR receive demo sketch and a basic servo sweep sketch work just fine when they’re independent of one another.
I’ve seen some postings online where people have gotten the same code to work on the same type of application, so I feel like I’m really missing something big here. I’ve copied their approach exactly, but am still stuck with a twitchy servo. Any help would be great…I really do appreciate the support.
A twitch would imply that the signal to the servo is not regular. Since the control signal is based on the width of a positive pulse, I would hazard to guess the pulse at times gets extended. A twitch would not be apparent is the off time of the pulse were extended. If you had a scope you could prove this assertion.
Since the pulse is getting stretched, I will assume that the IR remote code is somehow responsible. I would have guessed an interaction with a timer (do the two functions share the same timer?) or an interrupt issue (does the IR remote code turn off interrupts for any extended amount of time?).
Why others have not complained is interesting. Perhaps it is just more apparent in your application if the servo is mostly still?
fll-freak:
I would have guessed an interaction with a timer (do the two functions share the same timer?) or an interrupt issue (does the IR remote code turn off interrupts for any extended amount of time?).
Thank you fil, my thoughts also. As it turns out, the timer in the IRremote library is by default timer2, but has a convenient option in the header file of switching to timer1 by uncommenting a line of code. I was under the impression, after some searching, that the SerialServo library utilized timer1, however, upon checking SerialServo.cpp, the only mention of a timer is in reference to TCNT0, which is timer0, correct? So I tried using both the timer1 and timer2 option for the IR library, but there is no improvement. I also tried changing Servo.h to read TCNT1, and used the default timer2 option for the IR receiver, but this too did nothing.
As far as the IR remote code turning off interrupts, it does indeed do this. However, this only occurs during the initialization of the receiver in “irrecv.enableIRIn();”. Either way, I have commented out the “cli();/sei();” commands from the .cpp and the problem still persists.
Do you (or does anyone) know of a way to tell the IR timer to not run its ISR if the Servo timer is busy? (Or something to that effect) Or perhaps to detach and then attach the servo at the beginning and end of the IRreceive ISR?
waltr:
Try commenting it out and see if the servo twitch goes away.
As for this approach, waltr, that was indeed one of my initial guesses, but it has no effect on the issue. In fact, the entire loop() { } portion of the code can be omitted without any change in the chattering. I should have posted a more simplified code, I’ll edit the original. Thanks.
Have you found a fix for this problem? I’ve encountered it and have yet to find a solution. I want to us a remote control to override two servos in a pan tilt mount.
Wow… I know this thread is old, but since I know several people had this issue, I wanted to post my results.
Modifying the IRRemote.cpp code as Mlu suggested worked wonders!!! My servo twitch dropped to almost nothing. There is just barely a 'itck sound every now an then. I chalk this up to just crappy servos maybe drifting back and forth a bit. I did notice that when I commanded one of my servos to go 180 it would sit there and bounce. I told it to hit 179 instead and the issue was resolved. I have not idea what enabling the global interrupt did code wise (unblocked the servo timer that had a higher priority and allowed it to interrupt the IR timer?), but it seems to have worked a treat!
Thank you sir!! You saved my son’s school Leprechaun Trap!