Need help with programming - IR signal and Servo motors

Hi,
I am quite new with arduino and I am trying to code that when I point with my remote control at the IR receiver my two Servo motors will go to a specific point and repeat over and over again, but when I press the same button again they will stop moving. So I got 5 buttons on my small remote control and I want them to each play a different command. I already made something, but the problem with that is that the servo's won't stop moving until I press the reset button. Can someone please help me with this? :slight_smile:

#include <IRremote.h>
#include <Servo.h>
 
Servo motorA; //the name of the servo motor
Servo motorB;  
IRrecv irrecv(7); // the receiver connected with pin 7
decode_results results; 
 
void setup()
{
  Serial.begin(9600);  //serial communication
  irrecv.enableIRIn(); // start the receiver
  pinMode(GREEN_LED,OUTPUT);
  digitalWrite(GREEN_LED,HIGH);
  digitalWrite(RED_LED,HIGH);
  motorA.attach(13); // connect the servo with pin 13 and 10
  motorB.attach(10);
}
 
void loop() 
{
  if (irrecv.decode(&results)) { 
    Serial.print("IR code: ");
    Serial.println(results.value, HEX); 
 
    int key = results.value % 16;  
    Serial.print("key: "); 
    Serial.println(key); 
 
    switch (key)
    {
      case 2:
        doKey2();
        break;
      case 3:
        doKey3();
        break;
      case 4:
        doKey4();
        break;
      case 7:
        doKey7();
        break;
      case 8:
        doKey8();
        break;
  }
}
}
 
  void doKey2(){ //DOWN button on remote control
  digitalWrite(GREEN_LED,LOW); 
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(0);
    motorB.write(160);      
}  
 
void doKey3(){ //STROBE button on remote control
  digitalWrite(GREEN_LED,LOW);  
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(88);
    motorB.write(126);    
    delay(400);              
    motorA.write(10);
    motorB.write(120);          
}  
 
void doKey4(){ //SPEED button on remote control
  digitalWrite(RED_LED,LOW);  
    delay(300);           
    digitalWrite(RED_LED,HIGH); 
    motorA.write(49);
    motorB.write(160);    
    delay(1000);               
    motorA.write(13);
    motorB.write(93);  
}  
 
void doKey7(){ //SELECT button on remote control
  digitalWrite(GREEN_LED,LOW);  
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(90);
    motorB.write(179);  
    delay(800);              
    motorA.write(138);
    motorB.write(5);  
}  
 
void doKey8(){ //UP button on remote control
  digitalWrite(RED_LED,LOW);  
    delay(300);           
    digitalWrite(RED_LED,HIGH); 
    motorA.write(78);
    motorB.write(120);   
    delay(300);               
    motorA.write(130);
    motorB.write(12);    
}  
 
void flashLed(int nr)
{
  Serial.print("Flashled: "); 
}

You forgot to put "irrecv.resume();" at the bottom of your "if (irrecv.decode(&results)) {" block. Put it after "int key = results.value % 16;" since that is the last use you make of 'results'.

Are you getting the correct values from the IR receiver?

Try putting Serial.println("doKey2"); etc into each of the functions so you can see what is happening.

...R

johnwasser:
You forgot to put "irrecv.resume();" at the bottom of your "if (irrecv.decode(&results)) {" block. Put it after "int key = results.value % 16;" since that is the last use you make of 'results'.

Hi, Thanks for your reply!
So when I put "irrecv.resume();" after the "int key = results.value % 16;" the servo's will only play the command once, I'd like to have a loop in it but also that I can push the same button again and so it will stop.

Do you/someone know what I need to do so it repeats the command and I will be still available to push the same button to stop the command and then play another one?

Thanks,
Niels

nnielzz:
push the same button again and so it will stop.

The you need to record the state (whether running or stopped) so that when the code is received the Arduino knows what to do.

void dokey2() {
   if (isRunning2 == false) {
       isRunning2 = true;
       // switch on
   }
   else {
     isRunning2 = false;
      // switch off
   }
}

...R

Robin2:
The you need to record the state (whether running or stopped) so that when the code is received the Arduino knows what to do.

...R

I found in the examples (Digital>StateChangeDetection) that if I push a button, the light will go on and when I push it again, it'll go off. So I changed the "const int buttonPin = PUSH2; " to "const int buttonPin = 7; " the pin where my IR receiver is on. So what do I need to do now to give each button on my remote control a different command and will play in a loop?

// this constant won't change:
const int  buttonPin = PUSH2;    // the pin that the pushbutton is attached to (will be changed to pin7)
const int ledPin = RED_LED;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT_PULLUP);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  
  // turns on the LED every four button pushes by 
  // checking the modulo of the button push counter.
  // the modulo function gives you the remainder of 
  // the division of two numbers:
  if (buttonPushCounter % 4 == 0) {
    digitalWrite(ledPin, HIGH);
  } else {
   digitalWrite(ledPin, LOW);
  }
  
}

Thanks!

nnielzz:
I found in the examples (Digital>StateChangeDetection) that if I push a button, the light will go on and when I push it again, it'll go off. So I changed the "const int buttonPin = PUSH2; " to "const int buttonPin = 7; " the pin where my IR receiver is on. So what do I need to do now to give each button on my remote control a different command and will play in a loop?

In my earlier post I showed a modified version of your own dokey() function. Doesn't that work?

...R

Robin2:
In my earlier post I showed a modified version of your own dokey() function. Doesn't that work?

...R

Yes, it will probably work if I manage to put it in the code correctly.
Right now I did this:

#include <IRremote.h>
#include <Servo.h>
 
Servo motorA; //the name of the servo motor
Servo motorB;  
IRrecv irrecv(7); // the receiver connected with pin 7
decode_results results; 
 
void setup()
{
  Serial.begin(9600);  //serial communication
  irrecv.enableIRIn(); // start the receiver
  pinMode(GREEN_LED,OUTPUT);
  digitalWrite(GREEN_LED,HIGH);
  digitalWrite(RED_LED,HIGH);
  motorA.attach(13); // connect the servo with pin 13 and 10
  motorB.attach(10);
}
 
void loop() 
{
  if (irrecv.decode(&results)) { 
    Serial.print("IR code: ");
    Serial.println(results.value, HEX); 
 
    int key = results.value % 16;  
    Serial.print("key: "); 
    Serial.println(key); 
 
    switch (key)
    {
      case 2:
        doKey2();
        break;
      case 3:
        doKey3();
        break;
      case 4:
        doKey4();
        break;
      case 7:
        doKey7();
        break;
      case 8:
        doKey8();
        break;
  }
}
}
 
  void doKey2() {
   if (isRunning2 == false) {
       isRunning2 = true;
        // switch on
        digitalWrite(GREEN_LED,LOW);  
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(90);
    motorB.write(179);  
    delay(800);              
    motorA.write(138);
    motorB.write(5);  
   }
   else {
     isRunning2 = false;
      // switch off
}  
 
void doKey3() {
   if (isRunning2 == false) {
       isRunning2 = true;
        // switch on
        digitalWrite(GREEN_LED,LOW);  
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(90);
    motorB.write(179);  
    delay(800);              
    motorA.write(138);
    motorB.write(5);  
   }
   else {
     isRunning2 = false;
      // switch off         
}  
 
void doKey4() {
   if (isRunning2 == false) {
       isRunning2 = true;
        // switch on
        digitalWrite(GREEN_LED,LOW);  
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(90);
    motorB.write(179);  
    delay(800);              
    motorA.write(138);
    motorB.write(5);  
   }
   else {
     isRunning2 = false;
      // switch off
}  
 
void doKey7() {
   if (isRunning2 == false) {
       isRunning2 = true;
        // switch on
        digitalWrite(GREEN_LED,LOW);  
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(90);
    motorB.write(179);  
    delay(800);              
    motorA.write(138);
    motorB.write(5);  
   }
   else {
     isRunning2 = false;
      // switch off
}  
 
void doKey8() {
   if (isRunning2 == false) {
       isRunning2 = true;
        // switch on
        digitalWrite(GREEN_LED,LOW);  
    delay(300);           
    digitalWrite(GREEN_LED,HIGH); 
    motorA.write(90);
    motorB.write(179);  
    delay(800);              
    motorA.write(138);
    motorB.write(5);  
   }
   else {
     isRunning2 = false;
      // switch off
   }
}  
}  
 
void flashLed(int nr)
{
  Serial.print("Flashled: "); 
}

And I'm getting the error message:
StateChangeDetection.ino: In function 'void doKey2()':
StateChangeDetection.ino:52:8: error: 'isRunning2' was not declared in this scope
StateChangeDetection.ino:69:15: error: a function-definition is not allowed here before '{' token
StateChangeDetection.ino:146:1: error: expected '}' at end of input

I know I need to declare the "isRunning2" but where and what do I need to type?

Thanks!

nnielzz:
StateChangeDetection.ino:52:8: error: 'isRunning2' was not declared in this scope

I know I need to declare the "isRunning2" but where and what do I need to type?

boolean isRunning2 = false;

Put it above the line void setup() { so it is a global variable.

Sorry, I had assumed you know how to do that.

...R

Robin2:

boolean isRunning2 = false;

Put it above the line void setup() { so it is a global variable.

Sorry, I had assumed you know how to do that.

...R

Haha, I'm quite new to all of this, but you couldn't know that of course.

I placed everything correctly, but I don't see any difference in the results.
I start to get the feeling this is going to be really difficult to make...

Let's make this a little bit easier, if I send a IR signal to the IR receiver the servos will start moving repeatedly, but when I send a IR signal again it will stop moving.

If you/someone know how I can do that, any help is welcome!