Servo Twitch with IRremote Library
Moderators: adafruit_support_bill, adafruit

Servo Twitch with IRremote Library

by Hobart on Tue Nov 13, 2012 5:23 pm

Hello,

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:

Code: Select all | TOGGLE FULL SIZE
#include <IRremote.h>
#include <Servo.h>
 
int RECV_PIN = 4;
 
IRrecv irrecv(RECV_PIN);
 
Servo myservo;
 
void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  myservo.attach(12);
}
 
void loop()
{

}


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:


1. Using a different servo

2. Using different pins, for both the servo and IR receiver

3. 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..)

4. 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.


Ken Shirriff's IRremote library:
https://github.com/shirriff/Arduino-IRremote
Last edited by Hobart on Wed Nov 14, 2012 12:47 pm, edited 1 time in total.
Hobart
 
Posts: 7
Joined: Tue Nov 13, 2012 5:20 pm

Re: Servo Twitch with IRremote Library

by adafruit_support_bill on Tue Nov 13, 2012 5:47 pm

What is the nature of the twitch? Is it regular & periodic, or random? Does the servo move as commanded otherwise?
User avatar
adafruit_support_bill
 
Posts: 29814
Joined: Sat Feb 07, 2009 9:11 am

Re: Servo Twitch with IRremote Library

by Hobart on Tue Nov 13, 2012 6:48 pm

It seems very random. If I issue it a command, (such as the one below) I get a semi-regular response to the write command, but it is still very chattery throughout the movement and does not always respond as intended. Often it will keep repeating the 90-180-90 sweep until another button is pressed on the remote (any button), or it will just stay stuck at 180 with the same twitch, returning to 90 after several button presses or so. The nature of this behavior itself is very random too, and does not always response similarly to the previous instance, however, this is the general trend I've noticed. Thanks for the response, heres the code:

Code: Select all | TOGGLE FULL SIZE
void loop () {
if (results.value == "IR INPUT BIT VALUE") {
myservo.write(180);
delay(100);
mysevo.write(90);
}
}
Hobart
 
Posts: 7
Joined: Tue Nov 13, 2012 5:20 pm

Re: Servo Twitch with IRremote Library

by Hobart on Tue Nov 13, 2012 9:22 pm

Any ideas? Thanks.
Hobart
 
Posts: 7
Joined: Tue Nov 13, 2012 5:20 pm

Re: Servo Twitch with IRremote Library

by Hobart on Wed Nov 14, 2012 1:23 am

Sara, I'm not sure what you're trying to say with that response.

In fact, the glitch is occurring with just:

void loop() { }

Please clarify if you feel that you have a constructive answer, I would love to hear it. Thank you.
Hobart
 
Posts: 7
Joined: Tue Nov 13, 2012 5:20 pm

Re: Servo Twitch with IRremote Library

by adafruit_support_bill on Wed Nov 14, 2012 6:02 am

Sara appears to have been a spammer. She's gone now.

I'm don't have experience with the IR library you are using. But I don't see anything obvious in the library code that would disrupt servo operation. But if you are getting glitches with an empty loop, I'd guess something is messing up the PWM timing on the servo control pin. Does the glitch only happen when you are pressing buttons on the remote?
Do you have access to a scope to see what is getting sent to the servo?
User avatar
adafruit_support_bill
 
Posts: 29814
Joined: Sat Feb 07, 2009 9:11 am

Re: Servo Twitch with IRremote Library

by Hobart on Wed Nov 14, 2012 12:46 pm

adafruit_support wrote:She's gone now.

Thank you.

adafruit_support wrote:Does the glitch only happen when you are pressing buttons on the remote?

(Please see the original post. I updated the code to a more simplified version that still yields the same issue)

The glitch occurs whenever I attach a servo and initialize the receiver. Even without issuing any commands to act in the event of a button press, the servo will sit there in its initialized position and chatter irregularly. The motion of the chatter is barely noticeable besides the noise of the chatter and a slight axial movement. This in itself would be bothersome, but workable. The trouble is that when I issue a servo.write(); command based upon IR input, the chatter has an obvious interference with the motion. Thank you for working on this problem with me, I have posted to several Arduino forums and most everyone is as stumped as I am.
Hobart
 
Posts: 7
Joined: Tue Nov 13, 2012 5:20 pm

Re: Servo Twitch with IRremote Library

by adafruit_support_bill on Wed Nov 14, 2012 1:36 pm

Not seeing anything in the code :?
Sources of twitching like that are typically due to either: electrical noise picked up on the signal line or timing irregularities due to a software or interrupt handling issue. A scope would be helpful here. You could see if it were noise (random spikes or pulses) or a timing irregularity (pulse-width or frame-rate jitter).
User avatar
adafruit_support_bill
 
Posts: 29814
Joined: Sat Feb 07, 2009 9:11 am

Re: Servo Twitch with IRremote Library

by Hobart on Wed Nov 14, 2012 2:51 pm

adafruit_support wrote:A scope would be helpful here.

I wish I had one available..does it need to be a digital recording scope? I have access to a scope, but it is not digital.

Is there any way it could be a bad chip or Uno board? An irregularity within the hardware would explain why others are having success with the same code. I'd rather not buy another to try out if this is not a plausible cause of the issue though..

Also, perhaps there a command that I could write into the IRremote ISR that returns out of the ISR if the servo pulse is high? Or set the pulses of either so that they are not in conflict with each other?
Hobart
 
Posts: 7
Joined: Tue Nov 13, 2012 5:20 pm

Re: Servo Twitch with IRremote Library

by adafruit_support_bill on Wed Nov 14, 2012 4:53 pm

Servo waveforms are fairly simple and since the problem seems to be fairly constant, you should be able to observe the irregularities even without a storage scope.

Is there any way it could be a bad chip or Uno board? An irregularity within the hardware would explain why others are having success with the same code.

Some servos are more sensitive than others with respect to irregular signals. Since IR and servo function fine independently, I don't think it is a bad chip. It is possible that some revisions of the UNO board are noisier than others due to layout changes. But I would expect that boards from the same rev to behave similarly.

Also, perhaps there a command that I could write into the IRremote ISR that returns out of the ISR if the servo pulse is high?

That should be possible. Have you contacted Ken Sherriff regarding this problem? He may be aware of it, or at least have more insight into the cause.
User avatar
adafruit_support_bill
 
Posts: 29814
Joined: Sat Feb 07, 2009 9:11 am

Re: Servo Twitch with IRremote Library

by Hobart on Sat Nov 17, 2012 6:23 pm

Ok, So I haven't been able to get into contact with Ken Shirriff, but I think I've narrowed down the issue some more. At the beginning of the ISR in IRremote.cpp there is a digitalRead(); function that gathers the value of the IRreceiver pin, and then the rest of the raw data collection code is executed. I found that if I comment out this digitalRead(); segment, the twitching ceases. Could this be the issue? Or is it the same result I would have gotten from not running the ISR in the first place, since the rest of the ISR code depends on that digitalRead(); value? If this is a possible issue for correction, are there any thoughts on what is causing the trouble, and what approach I should take to fix it? My initial thought was that the digitalRead function was too slow and that this was interfering somehow with the servo control. I tried manipulating the ports manually, but the function of the ISR would not read back any IR values once I made the changes. Perhaps I had the coding incorrect, here is what I tried:

Code: Select all | TOGGLE FULL SIZE
ISR(TIMER_INTR_NAME)
{
  TIMER_RESET;

  int irdata = PINB;
    if (PINB == B00000000){
        irdata==0;}
    else {
        irdata==1;}

//...etc...

instead of:

Code: Select all | TOGGLE FULL SIZE
ISR(TIMER_INTR_NAME)
{
  TIMER_RESET;

  uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin);

//...etc...

Also, I should mention that I'm pretty certain this is not a timer conflict issue. I set up another timer2 ISR that performed a "blink LED 13" function and ran it within a servo test sketch and the servo functioned just fine. Since IRremote runs off of timer2 and the servo.h library runs off of timer1 (or timer0?), there shouldn't be a conflict anyhow.

Thank you for the consideration.
Hobart
 
Posts: 7
Joined: Tue Nov 13, 2012 5:20 pm

Re: Servo Twitch with IRremote Library

by adafruit_support_bill on Sun Nov 18, 2012 9:32 am

You are comparing the whole PINB instead of masking the single bit you are interested in.

Code: Select all | TOGGLE FULL SIZE
  int irdata = PINB;
    if (PINB == B00000000){
        irdata==0;}
    else {
        irdata==1;}


You need to 'AND' the PINB value with the mask for the IRreceiver pin.

Also, have you tried moving the servo to some pin that is not on port B?
User avatar
adafruit_support_bill
 
Posts: 29814
Joined: Sat Feb 07, 2009 9:11 am