Change State or Count functions using an IR remote to drive a DC motor

I have read several articles, threads and watched some videos on change state and count functions. I have gotten some of them to work independent of my code (below) but none of them satisfy my needs completely- or I have yet to fully understand them. Here is what I am trying to do :

  1. Press the “one” button on the IR remote and have it turn a motor for a period of time and then stop.
  2. Press the “one” button again on the IR remote and have it turn the motor (reverse) for a period of time and stop.

The code I have below works - Pressing “one” on the IR remote moves the motor and stops. Now I need to add a count (or change state) so it will preform the second part/second press. Right now I can press the “two” button to reverse the motor.

In the future there could be a 3rd and 4th stage to the “one” button and will want to replicate these same functions for other buttons on the IR remote.

#include <IRremote.h>

#define Zero_button 0xFF6897    // code received from zero button
#define One_button 0xFF30CF     // code received from one button
#define Two_button 0xFF18E7     // code received from two button
#define Three_button 0xFF7A85   // code received from three button
#define Four_button 0xFF10EF    // code received from four button
#define Five_button 0xFF38C7    // code received from five button
#define Six_button 0xFF5AA5     // code received from six button
#define Seven_button 0xFF42BD   // code received from seven button
#define Eight_button 0xFF4AB5   // code received from eight button
#define Nine_button 0xFF52AD    // code received from nine button

// Define sensor pin
int RECV_PIN = 2;               //output pin of IR receiver to pin 2 of arduino

//initializing the pins for motors
int rear_elevation_motor1 = 6;           //pin 6 of arduino to pin 2 of L293D
int rear_elevation_motor2 = 5;           //pin 5 of arduino to pin 7 of L293D

// Define IR Receiver and Results Objects
IRrecv irrecv(RECV_PIN);  //Arduino will take output of IR receiver from pin 4
decode_results output;


void setup(){
  // Serial Monitor @ 9600 baud
  Serial.begin(9600);
  
  // Enable the IR Receiver
  irrecv.enableIRIn();
 
//initializing all the pins where we have connected the motors as output pins
  pinMode(rear_elevation_motor1, OUTPUT);
  pinMode(rear_elevation_motor2, OUTPUT);
  
}

void loop(){
      {
      if (irrecv.decode(&output)){
    unsigned long value = output.value;
    switch(value) {
      case One_button:
            digitalWrite(rear_elevation_motor1,LOW);
            digitalWrite(rear_elevation_motor2,HIGH);
            delay(500);
            digitalWrite(rear_elevation_motor1,LOW);
            digitalWrite(rear_elevation_motor2,LOW);
            break;
     case Two_button:
           digitalWrite(rear_elevation_motor1,HIGH);
           digitalWrite(rear_elevation_motor2,LOW);
           delay(500);
           digitalWrite(rear_elevation_motor1,LOW);
           digitalWrite(rear_elevation_motor2,LOW);
           break;
        }
    irrecv.resume();
  }
    }}

If someone could point me in the right direction I’d be much appreciative!

I would recommend not using delay(). While the delay is happening all processing halts. If you time your rotations using millis() then you can respond immediately to button presses. Essentially you need to utilize a state machine and millis() for timing.

Look at the following tutorials:

State Machine
BlinkWithoutDelay
Arduino Multiple Things
Several Things at a Time

2) Press the "one" button again on the IR remote and have it turn the motor (reverse) for a period of time and stop.

Example code on how to toggle the motor direction with the ‘1’ key. You will need to change the IR key code to match your remote.

#include <IRremote.h>

const byte IR_RECEIVE_PIN = 2;

IRrecv irrecv(IR_RECEIVE_PIN);
decode_results results;

boolean motorDir = HIGH;

void setup()
{
   Serial.begin(115200);
   irrecv.enableIRIn();
}

void loop()
{
   if (irrecv.decode(&results))
   {
      unsigned long key = results.value;
      if(key == 0x4EB3C837)  // *************** change to match your remote
      {
         motorDir = !motorDir;
         Serial.print("Motor direction = ");
         Serial.println(motorDir);
      }
      irrecv.resume();
   }
}

ToddL1962:
I would recommend not using delay().

thanks for that info.... let me do some reading on millis()

groundFungus:
Example code on how to toggle the motor direction with the ‘1’ key. #include <IRremote.h>

Thanks again @groundFungus. I’ll try this along with incorporating the millis()

Just wanted to report back… I have the millis () function working on the motors to run for 500ms.

Now to see if I can incorporate the boolean motorDir to combine it into one button.

#include <IRremote.h>

#define One_button 0xFF30CF     // code received from one button
#define Two_button 0xFF18E7     // code received from two button

int RECV_PIN = 2;               //output pin of IR receiver to pin 2 of arduino

//initializing the pins for motors
int rear_elevation_motor1 = 6;              //pin 6 of arduino to pin 2 of L293D
int rear_elevation_motor2 = 5;              //pin 5 of arduino to pin 7 of L293D


// Define IR Receiver and Results Objects
IRrecv irrecv(RECV_PIN);  //Arduino will take output of IR receiver from pin 2
decode_results output;

unsigned long currentTime;
int onTime = 500;

void setup()
{
  // Serial Monitor @ 9600 baud
  Serial.begin(9600);

  // Enable the IR Receiver
  irrecv.enableIRIn();



  //initializing all the pins where we have connected the motors as output pins
  pinMode(rear_elevation_motor1, OUTPUT);
  pinMode(rear_elevation_motor2, OUTPUT);


}

void loop()
{
  {
    if (irrecv.decode(&output)) {
      unsigned long value = output.value;
      switch (value) {
        case One_button:
          digitalWrite(rear_elevation_motor1, LOW);
          digitalWrite(rear_elevation_motor2, HIGH);
          currentTime = millis();
          break;
      }
      irrecv.resume();
    }
    if ((millis() - currentTime) >= onTime)
    {
      digitalWrite(rear_elevation_motor1, LOW);
      digitalWrite(rear_elevation_motor2, LOW);
    }
    {
      if (irrecv.decode(&output)) {
        unsigned long value = output.value;
        switch (value) {
          case Two_button:
            digitalWrite(rear_elevation_motor1, HIGH);
            digitalWrite(rear_elevation_motor2, LOW);
            currentTime = millis();
            break;
        }
        irrecv.resume();
      }
      if ((millis() - currentTime) >= onTime)
      {
        digitalWrite(rear_elevation_motor1, LOW);
        digitalWrite(rear_elevation_motor2, LOW);
      }
    }
  }
}

Sorry I am coming back to an old thread… Between the holidays and other life events my projects have taken the back burner for a few months. If I don’t get any hits with this post, I create a new thread in a day or so…

@groundFungus I tried your code from a few post up and must be missing something. I have the code loaded with my IR code for the “One” button, and the serial monitor show the direction change, but how do I translate that so my motor will change directions? I have the motor connected to an L293D - I’d assume I need to specify the pins in the code as well?

#include <IRremote.h>

const byte IR_RECEIVE_PIN = 2;

IRrecv irrecv(IR_RECEIVE_PIN);
decode_results results;

boolean motorDir = HIGH;

void setup()
{
   Serial.begin(115200);
   irrecv.enableIRIn();
}

void loop()
{
   if (irrecv.decode(&results))
   {
      unsigned long key = results.value;
      if(key == 0xFF30CF)  // *************** change to match your remote
      {
         motorDir = !motorDir;
         Serial.print("Motor direction = ");
         Serial.println(motorDir);
      }
      irrecv.resume();
   }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.