Arduino Uno Controlling Servo with IR Remote Code Help

Hello, I am trying to control a mini servo motor with my Arduino Uno and IR Remote. Parts List: Arduino Uno, Breadboard, 38KHz TSOP4838 IR Receiver, Flat IR Remote and misc. I have everything working but I can't find a good code to work off of and I am a begginer at Arduino Code. The best I could get the servo working but the motor would be jumpy and fluctuating.

Phase 1 I would like to be able to control the servo using the Up and Down Buttons on my remote. Remote Codes are Up: 1FE58A7 & Down - 1FEA05F and some way to edit the speed of rotation travel.

Phase 2 (optional) Program the servo to rotate automatically based on time of day or schedule with manual override.

I have been trying to figure this out and seem to have hit a wall. I was able to set everything up to read the IR Remote Codes but seem to be having trouble finding a good code to get the servo working properly for phase one of the project.

Any help with this would be greatly appreciated. Thanks in advance

Hi dvseliteus, Firstly are you powering the servo from a separate power supply? or batteries? never power servos or motors from the Arduino, it's trouble.. the Arduino can't supply that much current and will reset itself or brownout, etc.

If you convert the IR code with byte(IRcode) you then have a smaller 8 bit variable, or 255 different codes more then enough.. and easier to deal with.

The servo works like this: Myservo.write(XX);

so you could code:

if(IRcode=XX) {Myservo.write(AA); } if(IRcode=YY) {Myservo.write(BB);

AA/BB to move the servo in the required direction.

We all began somewhere! just give it your best, we all make mistakes, but hopefully learn from them.

Lets see your code and how you have this all wired up.

Hope it helps, Regards.

Mel.

I don't know how to make the Arduio recognize codes from proprietary remote controls but there is a library (by ken Shriff?) which apparently deal with very many of them.

Once you have code that can detect the valid code the rest of the program is simple - as illustrated by @Cactusface

...R

Hi Guys,
Thanks for the replies.
I am really enjoying working with Arduino and Code.
Here is the code that I got working:

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

unsigned long Value1 = 0x1FE58A7; // where XXXXXXXX is on our your remote's values
unsigned long Value2 = 0x1FEA05F; // where XXXXXXXX is another button on your remote

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

Servo servo1;

// the setup routine runs once when you press reset:
void setup() {              

Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver

  // initialize the digital pin as an output.

servo1.attach(10); // attack servo to digital pin 10
}

// the loop routine runs over and over again forever:
void loop() {

if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }

if(results.value == Value1) {
servo1.write(160);
}
else if  (results.value == Value2){
servo1.write(75);
} 
}

Good to know I need isolated power for the servo. That makes sense.

So with the above code the servo moves to position 160 and 75. I am looking for something that will move dynamically with the remote button presses. I hope that made sense.

Thanks again for your help and support!

dvseliteus: I am looking for something that will move dynamically with the remote button presses. I hope that made sense.

Sorry - I have no idea what that means.

...R

I am looking for something that will move dynamically with the remote button presses. I hope that made sense.

You could have a variable called, say, position that is the current position of the servo. Using the codes for volume up and down. Set up a function that will increment the position variable when volume up is received (position++) or decrement on down (position--). Each time through loop() read the remote, if a button was pressed, use an if else or switch to find which button was pressed, operate on the position variable and update the servo. When a button is held down some remotes send the code for a button over and over and some send the button code once and then send a "repeat code" like 0xffffffff, so you will need to deal with that.

Thanks all for the Replys!

Robin2 to clarify my jibberish, I would like the servo to move slowly as I hold the up or down button to adjust the position as desired.

groundfungus thank you for the info. I'm a beginner, I understand the concept of what your saying but I am new to code and I'm not sure where to insert the function and what code to remove. Would you be able to send me an example?

Happy New Year!

I would like the servo to move slowly as I hold the up or down button to adjust the position as desired.

There has been code posted in the past that is a variant of the "sweep" servo code in the IDE servo examples that use millis instead of delays. The below might also be of interest for slowing servo movement.

http://forum.arduino.cc/index.php?topic=61586.0

Try this out. You will need to replace my key codes with the ones for your remote and make sure the pin assignments are correct for your setup. This does not deal with the repeat as I don’t know your remote.
Tested and works with my Uno.

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

const byte RECV_PIN = 8;

IRrecv irrecv(RECV_PIN);
Servo myservo; 

byte position = 90; // range 0-180
boolean newIRdata = false;
unsigned long IRinput;

decode_results results;

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

void loop() {
  if (irrecv.decode(&results))
  {
    IRinput = results.value;
    irrecv.resume(); // Receive the next value
    newIRdata = true;
  }
  if(newIRdata == true)
  {
   Serial.println(IRinput, HEX);
      switch(IRinput)
    {
     // move right 1 degree per button push
     case(0x4eb338c7): // right arrow
     position--;
     Serial.println(position);
     break;
     // move left 1 degree per button push
     case(0x4EB312ED): // left arrow
     position++;
     Serial.println(position);
     break;
     // go to 160
     case(0x4EB322DD): // up arrow
     position = 160;
     Serial.println(position);
     break;
     // go to 70
     case(0x4EB3B847): // down arrow
     position = 75;
     Serial.println(position);
     break;     
    }
     IRinput = 0;
     newIRdata = false;   
  }
  myservo.write(position);
}

Thank you groundfungus
This worked great! Is there a way I can change the degree when the left and right buttons are pushed, say to 5 degrees per push?

zoomkat
Thanks for the link. This info was a little too advanced for me. Since the servo only moves once per button push even if I hold it down I don’t think I need to mess with the speed just the degree per push.

Here’s what I have so far:

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

const byte RECV_PIN = 8;

IRrecv irrecv(RECV_PIN);
Servo myservo; 

byte position = 90; // range 0-180
boolean newIRdata = false;
unsigned long IRinput;

decode_results results;

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

void loop() {
  if (irrecv.decode(&results))
  {
    IRinput = results.value;
    irrecv.resume(); // Receive the next value
    newIRdata = true;
  }
  if(newIRdata == true)
  {
   Serial.println(IRinput, HEX);
      switch(IRinput)
    {
     // move right 1 degree per button push
     case(0x1FEC03F): // right arrow
     position--;
     Serial.println(position);
     break;
     // move left 1 degree per button push
     case(0x1FE807F): // left arrow
     position++;
     Serial.println(position);
     break;
     // go to 160
     case(0x1FE58A7): // up arrow
     position = 160;
     Serial.println(position);
     break;
     // go to 75
     case(0x1FEA05F): // down arrow
     position = 75;
     Serial.println(position);
     break;     
    }
     IRinput = 0;
     newIRdata = false;   
  }
  myservo.write(position);
}

My next challenge is to try to change the degree to move automatically at set times each day? Any ideas on how to add that to this code?

Thanks everyone for your help!

Instead of position++ use position = position + 5; or position += 5; (they both mean the same). Same with the other direction position = position -5; or position -= 5;

groundfungus!
Thanks so much for your help!
It’s working perfectly!

Now I just need to learn how to program it to change degrees automatically at set times each day.

Here’s the code so far:

/* Version 1.0  Jan 2015 - Credit to groundfungus
 * "IR_Servo" Control a servo using an IR remote
 */
#include <IRremote.h>
#include <Servo.h> 

const byte RECV_PIN = 8;

IRrecv irrecv(RECV_PIN);
Servo myservo; 

byte position = 90; // range 0-180
boolean newIRdata = false;
unsigned long IRinput;

decode_results results;

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

void loop() {
  if (irrecv.decode(&results))
  {
    IRinput = results.value;
    irrecv.resume(); // Receive the next value
    newIRdata = true;
  }
  if(newIRdata == true)
  {
   Serial.println(IRinput, HEX);
      switch(IRinput)
    {
     // move right 5 degrees per button push
     case(0x1FEC03F): // right arrow
     position-=5;
     Serial.println(position);
     break;
     // move left 5 degrees per button push
     case(0x1FE807F): // left arrow
     position+=5;
     Serial.println(position);
     break;
     // go to 160
     case(0x1FE58A7): // up arrow
     position = 160;
     Serial.println(position);
     break;
     // go to 75
     case(0x1FEA05F): // down arrow
     position = 75;
     Serial.println(position);
     break;     
    }
     IRinput = 0;
     newIRdata = false;   
  }
  myservo.write(position);
}

I'm not sure what the easiest code would be to add here for the automatic movement.

I only need the servo to move 2 to 4 times a day to the (2) set dergress in the above code 160 and 75.

Any ideas?

I found this but am not sure if I can use it? http://blog.shoguniphicus.com/2014/03/arduino-auto-fish-feeding-project-with.html

That dude is using delay() for timing. Not how I would do it. I would use a real time clock and trigger feedings with data from alarms or set up timing using the blink without delay method (see several things at the same time sticky). That way you can monitor other stuff while you wait for the feeding time.

For the RTC Method would I need an additional Module like this one: https://www.sparkfun.com/products/12708? Or is this something that can be coded directly?

I read the Arduino Tutorial on the blink without delay and I get the principal but to integrate the code with what I have so far is a bit over my head.

Thanks again for your help!

If you want to actuate the servo at specific times of day the RTC is the best choice. If you want to actuate, say, every 6 hours then a timer using millis() would be fine. Please try to learn and use the blink without delay methods. It is one of the most important concepts to learn IMO (along with state machine programming).

It is not really hard once you figure it out. Note that you can still control the servo with the remote between feedings (no delay() or while loops). Add this to your list of variables above setup():

// added blink without delay feeder
unsigned long feederTimer; //  holds the last feeding time
unsigned long feederInterval = 10000; // how many millis between feedings. 10 second but could be hours
unsigned long feedingTimer;  // holds the start of feeding time
unsigned long feederPause = 2000;//  holds how long to wait for servo motion
boolean feeding = false;

Put this in your loop() function:

void loop() {  // get rid of this line.  Just to show that the code goes in the "root" of loop()
    if(millis() - feederTimer > feederInterval)  // time to feed?
    {
        position = 20;  
        feedingTimer = millis();  // feeding start time
        feederTimer = millis();
        feeding = true;  // we are feeding
    }

    if(millis() - feedingTimer > feederPause && feeding == true)
    {
        position = 140;
        feeding = false;  // feeding all done
    }

Thanks again groundfungus your really helping accelerate this project. I'm going to try some tutorials with blink without delay methods and try to understand it better. I think the RTC is the best method to actuate the servo at specific times of day. Do I need a clock module for that or can it be just straight code?

The RTC is hardware: I've used the DS1302 (bought as loose chip with a crystal, not as a module) with Henning Karlsen's library as well as DS1307s bought loose and as modules. There's a good 1307 library here. Whack a watch battery on it and it's got backup to keep the clock going when the Arduino power is off.

Hi, Yes that's just what you need, but I prefer something cheaper from China via eBay. But that's perhaps because I'm here in the UK.. We can get most Sparkfun stuff, but seems pricey to me!!

Then it's just a matter of:

if(hour=X && mins=Y) { myservo.write(positionOPEN); } else { myservo.write(positionCLOSED); }

Regards

Mel.