Problem controlling servo with remote

hey. im trying to run this code.
whenever i start the program, for some reason the servo automatically starts slightly moving.
whenever i press forward or back, it just starts moving faster in the same direction. and i cant make it go the other direction. help??

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

const int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;
Servo myservo;
int pos = 0; 

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  irrecv.blink13(true);
  myservo.attach(9);
}

void loop() {
  if (irrecv.decode(&results)) {
    if (results.decode_type == NEC) {
      Serial.print("NEC: ");
    } else if (results.decode_type == SONY) {
      Serial.print("SONY: ");
    } else if (results.decode_type == RC5) {
      Serial.print("RC5: ");
    } else if (results.decode_type == RC6) {
      Serial.print("RC6: ");
    } else if (results.decode_type == UNKNOWN) {
      Serial.print("UNKNOWN: ");
    }
    Serial.println(results.value, HEX);
    
    switch (results.value)
    {
      case 0xC1AA0DF2:
        Serial.println("forward");
        pos++;
        myservo.write(pos);
        delay(15);
      break;
      
      case 0xC1AA4DB2:
        Serial.println("back");
        pos--;
        myservo.write(pos);
        delay(15);
       break;
      
      default:
        Serial.println("unknown");
    }
    
    irrecv.resume(); // Receive the next value
  }
}

Hi, Get serial print to print the value of pos. See if you have control of it. You didn't say what the monitor displayed when misbehaving? Start pos off with a value of 90, not 0. Do this in your setup, then servo,write(pos) all before you attach. 90 should be about zero movement of the servo. (I assume they are 360 continuos servos.) What type/model servo. You cannot power the servo off the 5V of the arduino, the terminal cannot supply enough current and will cause the arduino to malfunction, possibly damage the regulator. What arduino are you using, UNO, Due, Mega, Nano?

Tom.... :)

Below is a servo control function i normally used in my code to control the servo direction and speed. Hopes this helps.

servoTurn(Servo servo, int angle, int rate) parameters:

  • servo: name of the servo object you want to change
  • angle: new angle you want to turn too
  • rate: milli second delay between each degree of turn
void servoTurn(Servo servo, int angle, int rate) {
  if (servo.read() <= angle) {
    for (int i = servo.read(); i <= angle; i++) { // turn the servo forward
      servo.write(i);            // turn 1 degree per rate(ms)
      delay(rate);              // delay time control turning speed
    }
  }
  else {
    for (int i = servo.read(); i >= angle; i--) { // turn the servo backwards
      servo.write(i);
      delay(rate);            // control turning speed
    }
  }
}// End of function

example of use:

case 0xC1AA0DF2:
        Serial.println("forward");
        pos++;
        servoTurn(myservo,pos,10);
        delay(15);
      break;

Hi, I just noticed, first coffee of the day. TurtleKing, you have not got your increase or decrease loops programmed to stop at 0 and 180, your counts ill go negative or >180.

Tom.... :)

whenever i start the program, for some reason the servo automatically starts slightly moving.

When you attach the servo, the library writes a 1500us pulse. (The fact that you’ve initialized pos=0 before that doesn’t do anything, since it’s not written to the servo; if you had , it would have made it worse since it’s full speed in one direction.)

The 1500us pulse, or 90* as a normal servo would understand it (yours are continuous?) is nominally 0 speed. But it’s not necessarily 0 speed and you might need to experiment with that value. You may find you need to servo.write(89) or servo.write(91) before the attach, to make it stay still.

Using servo.writeMicroseconds() gives you finer control on that.

I believe (some?) continuous servos have an adjusting screw so that you send a 90* or 1500us pulse and turn the screw till it actually stops.

also add a break; in default case :slight_smile: