Using IR remote to turn uninterrupted motion of a SERVO on and off

Dear all,

Apologies for the very basic question I am new to programming and arduino.

I am trying to write some code to effectively use a single button, on an IR remote, to trigger uninterrupted clockwise and counterclockwise rotation of a servo motor on and off. I have been able to piece together code to understand how to decode the IR remote buttons and have been able to use this to move the servo motor to specific positions using different buttons on the remote but cannot find a way to perform the task I am trying to complete.

I am trying to conceptually understand how I should structure my main loop to allow me to complete this task - can this be done?

All the best

What servo do you have?

A normal servo will only move to specified positions generally over a range of about 180 degrees in total. It cannot spin continuously over many complete rotations if that's what you mean by "uninterrupted motion". For that you need either a standard DC motor or a specific type of servo called a continuous rotation or sometimes a 360 degree servo.

Steve

Hey Steve - thank you for your quick response. That is precisely what I mean when I refer to uninterrupted motion and I realize servos are usually used to move to specific positions. I can bypass this problem by effectively using this code in the main loop so that the servo runs uninterrupted:

#include <Servo.h>

int servoPin = 9;
Servo servo1;

int pos = 0;

void setup() {
Serial.begin(9600);
servo1.attach(servoPin);
}

void loop() {

for (pos=0;pos<=180;pos+=1){
servo1.write(pos);
delay(5);
}
for (pos=180;pos>=0;pos-=1){
servo1.write(pos);
delay(5);
}
}

I am wondering If I can somehow find a way to turn the routine within the main loop on and off when receiving an input from a single button on an IR remote.

Thanks again for your help

The approach you have to take is to get rid of those for() loops inside of loop() and just let loop() repeat as fast as possible. This allows you to check for an IR button, and if one is received, set some sort of flag or variable.

After that part of the code, you then check the state of that variable and decide to do nothing (off) or do the next step of the servo. If you are truly moving back and forth, you also check to see if you are at either limit and reverse direction.

Thanks for your contribution - I have been able to resolve this by using two separate buttons on the IR remote to break in and out of an infinite loop. The HEX code for the IR buttons needs to be obtained using an IR decode script which are easily found elsewhere. I am sure there is a more efficient way to do this… This is what I have so far and it is working:

// Written by: Tommaso Giovannini
// This code is for controlling the uninterrupted clockwise and counterclockwise rotation of a servo using two buttons on an IR remote

#include <IRremote.h> // Copy IRremote library to arduino libraries
#include <Servo.h>
#define on 0xFFA25D //Define IR on button HEX code
#define off 0xFF629D // Define IR off button HEX code

int RECV_PIN = 11; //IR receiver pin
Servo servo1;
int pos; //Declare pos variable

IRrecv irrecv(RECV_PIN);
decode_results results;

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

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

if (results.value == on)
{
for(;:wink:
{
for (pos=0;pos<=180;pos+=1)
{
servo1.write(pos);
delay(5);
}
for (pos=180;pos>=0;pos-=1)
{
servo1.write(pos);
delay(5);
}
if (irrecv.decode(&results))
{
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
}
if (results.value == off)
{
break;
}
}
}
}
}

Ok last post I have found a way to use a single button on the IR remote by using a cursor vaue which is evaluated as an odd or even number to determine whether to exit the nested infinite loop. Final version:

// Written by: Tommaso Giovannini
// This code is for controlling the uninterrupted clockwise and counterclockwise rotation of a servo using one button on an IR remote
// When clicking the single button the motor is toggling between the uninterrupted rotation and stop

#include <IRremote.h> //must copy IRremote library to arduino libraries
#include <Servo.h>
#define button 0xFFA25D //Define IR button HEX code

int RECV_PIN = 11; //IR receiver pin
Servo servo1;
int pos; //rotation angle
int i = 3;

IRrecv irrecv(RECV_PIN);
decode_results results;

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

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

if (results.value == button)
{
i = i + 1;
}

if ( (i % 2) == 0)
{
for(;:wink:
{
for (pos=0;pos<=180;pos+=1)
{
servo1.write(pos);
delay(5);
}
for (pos=180;pos>=0;pos-=1)
{
servo1.write(pos);
delay(5);
}
if (irrecv.decode(&results))
{
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
}
if (results.value == button)
{
i = i + 1;
}
if ( (i % 2) == 1)
{
break;
}
}
}
}
}

This is a very funny way to implement a simple Boolean flag...

int i = 3;
i = i + 1;
if ( (i % 2) == 0)
if ( (i % 2) == 1)

Not to mention “i” is usually reserved for a loop variable, and perhaps the most unhelpful name for a state variable or flag.

Try replacing with...

bool running = false;
running = !running;
if (running)
if (!running)

Also please learn to use [​code][​/code] tags when posting on the forums. Unless your code is in italics or has smilies in it in the IDE?

This works in this example. You may still want to review the blink without delay and state machines examples. This coding pattern probably isn’t going to help you with future projects. The “correct” way to do this sort of thing (i.e. more than one thing at once) is completely remove delay and loops from your loop code and let the Arduino calling the loop() function do all the looping for you.

'i' is clearly a loop variable in this case as it is updated within the loop however your boolean flag approach is clearly better. I will edit the smileys out as this is just the result of the last two characters of the infinite loop notation. I will also add the code tags - apologies - as I mentioned I am new to arduino and have not posted on forums previously.

With regards to changing the coding pattern - if I were trying to run a DC motor or blink an LED light I would have used the approach you are suggesting, however, servo motors are meant to move to specific positions and not run uninterrupted which is why the approach you are describing is unfeasible.

Thank you for your suggestions.