Nano ir receiver controlled dc motor low power

using sleep mode and IRremote - Programming Questions - Arduino Forum original info from here

Hello

First time posting and a bit of a noob just getting into electronics and this is my first project so bear with me please.

I am using an Arduino NANO v3, with ir receiver on pcb, L298N motor driver fed by 18650 battery with step up voltage to cover both the dc motor and a feed going to the nano, 3v dc geared motor - generic remote.
I am trying to use the code posted but to just drive a dc motor from an ir receiver & remote, came across this and thought it would suit if I meddled with it a bit, I can get the signal to show within the serial monitor but it does not turn the motor etc, but it seems that the sleep function works correctly, it also wakes ok from the remote key presses (Not sure if I meddled too much with the code) The IR codes have been changed to the ones received from my remote so it should react to "<" = CW rotation, ">" = CCW Rotation & "OK" = STOP. as the project runs on battery power I would like it to sleep as to save batteries, once I have the code working correctly I will be removing the power led / resistor and also the 5v regulator etc to save more battery drain.

Please would one of you kind souls take a look and see if you can see where I am going wrong? any help or advice would be greatly received, many thanks in advance.

#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <IRremote.h>

const int RECV_PIN = 2;
const int EN12 = 3;
const int P1 = 5;
const int P2 = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
int state [3];
#define interruptPin 2
#define EN12 3


void clearflags(void)
{
  state[0] = 0;
  state[1] = 0;
  state[2] = 0;
}

void motorcw(void) {
  digitalWrite(P1, HIGH); //activate motor
    digitalWrite(P2, LOW); //activate motor
  for (int x = 1; x <= 2; x++) //slow flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(250);
    digitalWrite(13, LOW);
    delay(250);
  }
}

void motorccw(void) {
  digitalWrite(P1, LOW); //activate motor
    digitalWrite(P2, HIGH); //activate motor
  for (int x = 1; x <= 4; x++) //fast flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
}

void motorstop(void) {
  digitalWrite(P1, HIGH);
  digitalWrite(P2, HIGH);
  delay(1000);//to be consistent with cw/ccw timeout total
}

void sleepNow(void) {

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  // Set sleep enable (SE) bit:
  sleep_enable();

  // Do not interrupt before we go to sleep, or the
  // ISR will detach interrupts and we won't wake.
  noInterrupts ();
  // Set pin 2 as interrupt and attach handler:
  attachInterrupt(0, pinInterrupt, LOW);
  // Upon waking up, sketch continues from this point.
  sleep_disable();
  interrupts();
  sleep_mode();
}

void pinInterrupt(void) {
  detachInterrupt(0);
}

void checkirforkey (void)
{
  if (irrecv.decode(&results))
  {
    if (results.value == 0xFF5AA5)//Keypad button ">"
   
    {
      state[0] = 1;state[1] = 0;state[2] = 0;
       Serial.println(results.value, HEX);
    }
    if (results.value == 0xFF10EF)  //Keypad button "<"
    
   {
     state[0] = 0;state[1] = 1;state[2] = 0;
     Serial.println(results.value, HEX);
   }
   if (results.value == 0xFF38C7) //Keypad button "OK"
   
   {
    state[0] = 0;state[1] = 0;state[2] = 1;
    Serial.println(results.value, HEX);
  }
    if (results.value == 0x00)
    {
    return;
   }
    irrecv.resume();
  }
}

void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.begin(9600);// setup Serial Monitor to display information
  pinMode(P1, OUTPUT);// define pin as OUTPUT for P1
  pinMode(P2, OUTPUT);// define pin as OUTPUT for P2
  pinMode(EN12, OUTPUT);// define pin as OUTPUT for 1,2EN 
  pinMode(interruptPin, INPUT_PULLUP);
    irrecv.enableIRIn();
}

void loop()
{
  clearflags();
  state[0] = 1;

  for (int awake = 0; awake < 10; awake++)
  {

      checkirforkey();
    if (state[0] == 1) {

      motorcw();
    }
    if (state[1] == 1) {

      motorccw();
    }
    if (state[2] == 1) {

      motorstop();
    }
  }
  clearflags();
  motorstop();
  delay(1000);
  sleepNow();
}

EN12 is set up twice, once as a const int and once as a #define...very confusing. It sounds like it might be an enable pin for the L298 (better comments would have helped). So shouldn't you be writing something to it to enable the motor?

Steve

Hi [Slipstick],

Thanks for your reply, your right I needed to enable the motor.. I told you not done this before :slight_smile:

So the Motor works now but I am getting the following issue now:

  1. On Power up the motor starts on CW
  2. For some reason when changing direction it sometimes changes to the same direction even though the other direction is pressed..

Any pointers or help would be great as am lost now.

Stu

#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <IRremote.h>

int RECV_PIN = 2;
#define interruptPin 2
#define EN12 3
#define P1 6 // define pin 5 as for P1
#define P2 8 // define pin 6 as for P2
IRrecv irrecv(RECV_PIN);
decode_results results;
int state [3];//detected movement flags


void clearflags(void)
{
  state[0] = 0;
  state[1] = 0;
  state[2] = 0;
}

void motorcw(void) {
  Serial.println("Start CW Motor");
  digitalWrite(EN12,1);
  digitalWrite(6, HIGH); //activate motor
  digitalWrite(8, 0); //activate motor
  for (int x = 1; x <= 2; x++) //slow flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(250);
    digitalWrite(13, LOW);
    delay(250);
  }
}

void motorccw(void) {
  digitalWrite(EN12,1);
  digitalWrite(8, HIGH); //activate motor
  digitalWrite(6, 0); //activate motor
  Serial.println("Start CCW Motor");
  for (int x = 1; x <= 4; x++) //fast flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
}

void motorstop(void) {
  Serial.println("Stop Motor");
  digitalWrite(EN12,1);
  digitalWrite(6, 0);
  digitalWrite(8, 0);
  delay(1000);//to be consistent with cw/ccw timeout total
}

void sleepNow(void) {

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  // Set sleep enable (SE) bit:
  sleep_enable();

  // Do not interrupt before we go to sleep, or the
  // ISR will detach interrupts and we won't wake.
  noInterrupts ();
  // Set pin 2 as interrupt and attach handler:
  attachInterrupt(0, pinInterrupt, LOW);
  // Upon waking up, sketch continues from this point.
  sleep_disable();
  interrupts();
  sleep_mode();
}

void pinInterrupt(void) {
  detachInterrupt(0);
}

 void checkirforkey(void)
{
  if (irrecv.decode(&results))
  {
    if (results.value == 0xFF5AA5)//Keypad button ">"
    {
     state[0] = 0;state[1] = 1;state[2] = 0;
    Serial.println(results.value, HEX);//if ir code matches print hex to monitor
    }
    if (results.value == 0xFF10EF)  //Keypad button "<"
   {
     state[0] = 0;state[1] = 1;state[2] = 0;
     Serial.println(results.value, HEX);//if ir code matches print hex to monitor
   }
    if (results.value == 0xFF38C7) //Keypad button "OK"
   {
    state[0] = 0;state[1] = 0;state[2] = 1;
    Serial.println(results.value, HEX);//if ir code matches print hex to monitor
  }
    if (results.value == 0x00)
    {
    return;
   }
    irrecv.resume();
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  pinMode(P1, OUTPUT);// define pin as OUTPUT for P1
  pinMode(P2, OUTPUT);// define pin as OUTPUT for P2
  pinMode(EN12, OUTPUT);// define pin as OUTPUT for 1,2EN 
  pinMode(interruptPin, INPUT_PULLUP);
  pinMode(RECV_PIN, INPUT);
  //attachInterrupt(digitalPinToInterrupt(interruptPin), motorAction, CHANGE);
   Serial.println("Motor IR Control");
  irrecv.enableIRIn();
  
 
  //    irrecv.blink13(true);
  //

}

void loop()
{
  clearflags();
  state[0] = 1;

  for (int awake = 0; awake < 10; awake++)
  {

      checkirforkey();
    if (state[0] == 1) {
      //clearflags();
      motorcw();
    }
    if (state[1] == 1) {
      //clearflags();
      motorccw();
    }
    if (state[2] == 1) {
      //clearflags();
      motorstop();
    }
  }
  clearflags();
  //motorstop();
  delay(1000);
  sleepNow();
}

Hi,

Worked it out, put it away for a night and had a few drinks - once refreshed got back into it this morning and low and behold sussed it out. YAY! :slight_smile: :smiley:

So the motor works as expected using the 3 buttons of the remote to turn the motor CW / CCW / STOP
My next phase of the project is to cut down the power consumption on both the Arduino and the L298N driver board (if possible).

If anyone is interested in the code its below:

#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <IRremote.h>

int RECV_PIN = 2;
#define interruptPin 2
#define EN12 3
#define P1 6 // define pin 5 as for P1
#define P2 8 // define pin 6 as for P2
IRrecv irrecv(RECV_PIN);
decode_results results;
int state [3];//detected movement flags


void clearflags(void)
{
  state[0] = 0;
  state[1] = 0;
  state[2] = 0;
}

void motorcw(void) {
  Serial.println("Start CW Motor");
  digitalWrite(EN12,1);
  digitalWrite(6, HIGH); //activate motor
  digitalWrite(8, LOW); //activate motor
  for (int x = 1; x <= 2; x++) //slow flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(250);
    digitalWrite(13, LOW);
    delay(250);
  }
}

void motorccw(void) {
  digitalWrite(EN12,1);
  digitalWrite(8, HIGH); //activate motor
  digitalWrite(6, LOW); //activate motor
  Serial.println("Start CCW Motor");
  for (int x = 1; x <= 4; x++) //fast flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
}

void motorstop(void) {
  Serial.println("Stop Motor");
  digitalWrite(EN12,1);
  digitalWrite(6, HIGH);
  digitalWrite(8, HIGH);
  delay(500);//to be consistent with cw/ccw timeout total
}

void sleepNow(void) {

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  // Set sleep enable (SE) bit:
  sleep_enable();

  // Do not interrupt before we go to sleep, or the
  // ISR will detach interrupts and we won't wake.
  noInterrupts ();
  // Set pin 2 as interrupt and attach handler:
  attachInterrupt(0, pinInterrupt, LOW);
  // Upon waking up, sketch continues from this point.
  sleep_disable();
  interrupts();
  sleep_mode();
}

void pinInterrupt(void) {
  detachInterrupt(0);
}

 void checkirforkey(void)
{
  if (irrecv.decode(&results))
  {
    if (results.value == 0xFF5AA5)//Keypad button ">"
    {
     state[0] = 1;state[1] = 0;state[2] = 0;
    Serial.println(results.value, HEX);//if ir code matches print hex to monitor
    }
    if (results.value == 0xFF10EF)  //Keypad button "<"
   {
     state[0] = 0;state[1] = 1;state[2] = 0;
     Serial.println(results.value, HEX);//if ir code matches print hex to monitor
   }
    if (results.value == 0xFF38C7) //Keypad button "OK"
   {
    state[0] = 0;state[1] = 0;state[2] = 1;
    Serial.println(results.value, HEX);//if ir code matches print hex to monitor
  }
    if (results.value == 0x00)
    {
    return;
   }
    irrecv.resume();
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  pinMode(P1, OUTPUT);// define pin as OUTPUT for P1
  pinMode(P2, OUTPUT);// define pin as OUTPUT for P2
  pinMode(EN12, OUTPUT);// define pin as OUTPUT for 1,2EN 
  pinMode(interruptPin, INPUT_PULLUP);
  pinMode(RECV_PIN, INPUT);
  //attachInterrupt(digitalPinToInterrupt(interruptPin), motorAction, CHANGE);
   Serial.println("Motor IR Control");
  irrecv.enableIRIn();
  
 
  //    irrecv.blink13(true);
  //

}

void loop()
{
  clearflags();
  state[2] = 1 ;

  for (int awake = 0; awake < 10; awake++)
  {

      checkirforkey();
    if (state[0] == 1) {
      //clearflags();
      motorcw();
    }
    if (state[1] == 1) {
      //clearflags();
      motorccw();
    }
    if (state[2] == 1) {
      //clearflags();
      motorstop();
    }
  }
  clearflags();
  //motorstop();
  delay(1000);
  sleepNow();
}