Problem controlling servo with irRemote

So im using the IRremote lib with the Servo Lib on my arduino uno.
The problem i am having is that when i press a button on my remote (code 7 for example) i get a bunch of code 0's (for holding down a button) for a little while after i've let go of the button. This does not happen if i do not have the Servo.write() function running when this button is being pressed.

My goal is simply to move a servo when holding down a button.

this is my code, if i need to give more info feel free to ask

#include <IRremote.hpp>
#include <Servo.h>
#include <millisDelay.h>

int receiverPin = 10;
int servoPin = 11;

int servoAngle = 90;
int lastButton;

Servo s1;

void setup() {
  pinMode(receiverPin, INPUT);
  s1.attach(servoPin);
  IrReceiver.begin(receiverPin, LED_BUILTIN);
  Serial.begin(9600);

  s1.write(servoAngle);
}

void loop() {
  if(IrReceiver.decode())
  {    
    Serial.println(IrReceiver.decodedIRData.command);
    IrReceiver.resume();

    switch (IrReceiver.decodedIRData.command)
    {
      case 21:
        RotateClockwise();
        lastButton = 21;
        break;
      case 7:
        RotateCounterclockwise();
        lastButton = 7;
        break;
      case 22:
        s1.write(0);
        servoAngle = 0;
        break;
      case 12:
        s1.write(180);
        servoAngle = 180;
        break;
      case 0:
        if(lastButton == 21)
        {
          RotateClockwise();
        }
        if(lastButton == 7)
        {
          RotateCounterclockwise();
        }
        break;
    }
  }
}

void RotateCounterclockwise()
{
  if(servoAngle >= 2) servoAngle -= 2;
  s1.write(servoAngle);
  Serial.println(servoAngle);
}

void RotateClockwise()
{
  if(servoAngle <= 178) servoAngle += 2;
  s1.write(servoAngle);
  Serial.println(servoAngle);
}


Welcome to the forum

What is the purpose of case 0 in your sketch ?

When pressing and holding down under "normal operation" i get a button code succeded with 0s to indicate a holding down action. So when holding down the button i want to keep rotating the servo.

But the problem is that when i introduce servo.write() the 0's keep rolling in after letting go of the button

some remote controllers do not send the same code when the user keeps the same button pressed down. So it's up to you to remember the last real command and when you receive the repeat code, treat that as if you had received the command instead. it seems to be what you do.

Are you still receiving 0 when the user let go? that's weird.

also try moving this

at the end of the if(IrReceiver.decode()) so that you don't run the risk of messing around with IrReceiver.decodedIRData.command in the background whilst you use it in the loop.

if you run this

#include <IRremote.hpp>
int receiverPin = 10;

void setup() {
  IrReceiver.begin(receiverPin, LED_BUILTIN);
  Serial.begin(115200);
}

void loop() {
  if (IrReceiver.decode()) {
    Serial.print("code = "); 
    Serial.println(IrReceiver.decodedIRData.command);
    IrReceiver.resume();
  }
}

and open the Serial monitor at 115200 bauds, what do you see when you press and hold and then release the button?

when running this

i get the code from the button while pressing and holding, no 0s. it also stops emediatly after letting go of the button. When i run this code it starts sending 0s, but still stops emediatly after letting go of the button.

#include <IRremote.hpp>
#include <Servo.h>

int receiverPin = 10;
int servoPin = 11;

int angle = 90;
Servo s1;

void setup() {
  IrReceiver.begin(receiverPin, LED_BUILTIN);
  s1.attach(servoPin);
  Serial.begin(115200);

  s1.write(angle);
}

void loop() {
  if (IrReceiver.decode()) {
    Serial.print("code = "); 
    Serial.println(IrReceiver.decodedIRData.command);

    if(IrReceiver.decodedIRData.command == 7)
    {
      angle++;
      s1.write(angle);
    }

    IrReceiver.resume();
  }

  //Serial.println(angle);
}

then if i also use the servo with the 0 command i get the weird behaviour i discribed earlier

The code above do not send nothing, it is a receiver only.
Please show your sender code too.

sorry for the confusion, i meant the code is giving me 0s, for sending i am using some remote i got with the arduino starter kit a while back

the sender is a remote control :slight_smile:

so if you don't get 0 when the key is long pressed and you get the repeated code, you should just get rid of

      case 0:
        if(lastButton == 21)
        {
          RotateClockwise();
        }
        if(lastButton == 7)
        {
          RotateCounterclockwise();
        }
        break;

the 0 there probably means the IR library got a wrong code or something

if i run this;

#include <IRremote.hpp>
#include <Servo.h>

int receiverPin = 10;
int servoPin = 11;

int angle = 90;
Servo s1;

void setup() {
  IrReceiver.begin(receiverPin, LED_BUILTIN);
  s1.attach(servoPin);
  Serial.begin(115200);

  s1.write(angle);
}

void loop() {
  if (IrReceiver.decode()) {
    Serial.print("code = "); 
    Serial.println(IrReceiver.decodedIRData.command);

    if(IrReceiver.decodedIRData.command == 7)
    {
      angle--;
    }
    if(IrReceiver.decodedIRData.command == 21)
    {
      angle++;
    }

    Serial.println(angle);
    IrReceiver.resume();
  }
}

that would work fine, the angle increases and decreased while you hold down the button. But when i use this;

#include <IRremote.hpp>
#include <Servo.h>

int receiverPin = 10;
int servoPin = 11;

int angle = 90;
Servo s1;

void setup() {
  IrReceiver.begin(receiverPin, LED_BUILTIN);
  s1.attach(servoPin);
  Serial.begin(115200);

  s1.write(angle);
}

void loop() {
  if (IrReceiver.decode()) {
    Serial.print("code = "); 
    Serial.println(IrReceiver.decodedIRData.command);

    if(IrReceiver.decodedIRData.command == 7)
    {
      angle--;
      s1.write(angle);
    }
    if(IrReceiver.decodedIRData.command == 21)
    {
      angle++;
      s1.write(angle);
    }

    Serial.println(angle);
    IrReceiver.resume();
  }
}

i get 0s while holding down instead of the normal button codes so it stops working

ah - just noticed the pins you used

if you go check the IR library documentation you'll see that some PWM pins can't be used because they depend on the timer used by the IR Library.

On the UNO the default is to use Timer2 which messes up PWM on pin 3 and 11(or if you mess up with PWM for pin 3 and 11, you mess up with Timer2)

➜ don't use pin 11

int servoPin = 11;

go for

const byte servoPin = 5; 

i've changed the servo pin to pin5 but nothings changed sadly :((

i still get 0s when using the servo, and still get 0s after releasing the button in my original code with the pin number adjusted

how are things wired / powered. can you draw your circuit and post it ?

image

Try with pin 2 for the IR receiver. this is also the default pin.

same thing sadly

are you really powering the servo from the Arduino?
if you don't plug it in (but leave the code for the servo) do you still have the issue?

the power is going through a breadboard but yes its coming from the arduino.

when i unplug the servo the problem disapears. when i plug it in, its there again

try powering your servo with a separate power supply then and don't go through the breadboard. You might have electromagnetic perturbations going on due to the motor or just noise created by the motor.