After using millis() my loop is not working properly

Using this code

const unsigned long event = 10;
const unsigned long eventy = 1000;
const unsigned long eventu = 500;
unsigned long prevperiod = 0;
unsigned long prevperiodf = 0;
unsigned long prevperiodg = 0;

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

const int receiver = 8; // Infrared receiver output pin( TSOP4838 )

boolean backHandRun = false;  // NEW
boolean foreHandRun = false;  // NEW
boolean stopHandRun = false;  // NEW


int IRstate;
int lastIRstate;

IRrecv irrecv(receiver);
decode_results results;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  leftRightservo.attach(10);
  int position = 90;

}

void loop() {
  

  IRstate = digitalRead(receiver);

  if (IRstate != lastIRstate) {

    if (irrecv.decode(&results)) {
      switch (results.value) {

        case 0x1FE50AF: // MENU
          Serial.println("MENU button pressed");
          backHandRun = true; // NEW
          foreHandRun = false; // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FED827: // PLAY/PAUSE
          Serial.println("PLAY/PAUSE button pressed");
          backHandRun = false;  // NEW
          foreHandRun = true;  // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FEF807: // PLAY/PAUSE
          Serial.println("PLAY/1 button pressed");
          backHandRun = false;  // NEW
          foreHandRun = false;  // NEW
          stopHandRun = true; // NEW
          break;
      }
unsigned long currentTime = millis();
      if (currentTime - prevperiod >= event) {
        irrecv.resume();
         prevperiod= currentTime;
      }
    }

  }
  lastIRstate = IRstate;
  foreHand();
  backHand();
  stopHand();
}
void foreHand() { // I want this to loop until i press a button on the remote
  unsigned long currentTime = millis();
  if (foreHandRun == true) {
    // new

    if (currentTime - prevperiodf >= eventy) {
      leftRightservo.write(180);
    }
    prevperiodf = currentTime;
    if (currentTime - prevperiodf >= eventy) {
      leftRightservo.write(0);
    }
    prevperiodf = currentTime;

    leftRightservo.write(180);

  }

}
void backHand() { // I want this to loop until i press a button on the remote
  unsigned long currentTime = millis();
  if (backHandRun == true) { // new

    if (currentTime - prevperiodg >= eventu) {
      leftRightservo.write(45);
    }
    prevperiodg = currentTime;
    if (currentTime - prevperiodg >= eventu) {
      leftRightservo.write(90);
     prevperiodg = currentTime;
    }


  }
}
void stopHand() { // I want this to loop until i press a button on the remote
  unsigned long currentTime = millis();
  if (stopHandRun == true) { // new
    leftRightservo.write(90);

  }
}

When I press button only first command of a loop is executed and when i press second button then also only first command is executed.

Loop is not continuing.

Before using millis() i was using this code. but due to delay blocking problem i used millis

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

const int receiver = 8; // Infrared receiver output pin( TSOP4838 )

boolean backHandRun = false;  // NEW
boolean foreHandRun = false;  // NEW
boolean stopHandRun = false;  // NEW


int IRstate;
int lastIRstate;

IRrecv irrecv(receiver);
decode_results results;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  leftRightservo.attach(10);
  int position = 90;

}

void loop() {

  IRstate = digitalRead(receiver);

  if (IRstate != lastIRstate) {

    if (irrecv.decode(&results)) {
      switch (results.value) {

        case 0x1FE50AF: // MENU
          Serial.println("MENU button pressed");
          backHandRun = true; // NEW
          foreHandRun = false; // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FED827: // PLAY/PAUSE
          Serial.println("PLAY/PAUSE button pressed");
          backHandRun = false;  // NEW
          foreHandRun = true;  // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FEF807: // PLAY/PAUSE
          Serial.println("PLAY/1 button pressed");
          backHandRun = false;  // NEW
          foreHandRun = false;  // NEW
          stopHandRun = true; // NEW
          break;
      }
      delay(10);
      irrecv.resume();
    }

  }
  lastIRstate = IRstate;
  foreHand();
  backHand();
  stopHand();
}
void foreHand() { // I want this to loop until i press a button on the remote

  if (foreHandRun == true) { // new

    leftRightservo.write(180);
    delay(1000);
    leftRightservo.write(0);
    delay(1000);
    leftRightservo.write(180);
    delay(1000);
  }

}
void backHand() { // I want this to loop until i press a button on the remote

  if (backHandRun == true) { // new
    leftRightservo.write(45);
    delay(500);
    leftRightservo.write(90);
    delay(500);
  }
}
void stopHand() { // I want this to loop until i press a button on the remote

  if (stopHandRun == true) { // new
    leftRightservo.write(90);

  }
}

Please Help
where is the problem

Every time you run your foreHand function you reset the value of prevperiodf variable to the current time. This means the action in that function is never triggered.

Grumpy_Mike:
Every time you run your foreHand function you reset the value of prevperiodf variable to the current time. This means the action in that function is never triggered.

Please guide what should i do then
I new to programming and just learned millis() but not getting what should i do to correct
what should i write instead of that

void foreHand() { // I want this to loop until i press a button on the remote

  if (foreHandRun == true) { // new

    leftRightservo.write(180);
    delay(1000);
    leftRightservo.write(0);
    delay(1000);
    leftRightservo.write(180);
    delay(1000);
}
}

I am able to understand how to use millis on single action but could not apply millis on this loop.Please anybody can correctly apply millis to above code.

What is your question / problem?

Tell us in detail what your program actually does and what you want it to do that is different.

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

...R

Robin2:
What is your question / problem?

Tell us in detail what your program actually does and what you want it to do that is different.

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

…R

This is my code that starts a particular continous function (loop) on pressing a button on ir remote and loop continues till other button is pressed for another function. But it uses delay thats why command from ir remote is not immedietly taken that makes command slow due to blocking because of delay.

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

const int receiver = 8; // Infrared receiver output pin( TSOP4838 )

boolean backHandRun = false;  // NEW
boolean foreHandRun = false;  // NEW
boolean stopHandRun = false;  // NEW


int IRstate;
int lastIRstate;

IRrecv irrecv(receiver);
decode_results results;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  leftRightservo.attach(10);
  int position = 90;

}

void loop() {

  IRstate = digitalRead(receiver);

  if (IRstate != lastIRstate) {

    if (irrecv.decode(&results)) {
      switch (results.value) {

        case 0x1FE50AF: // MENU
          Serial.println("MENU button pressed");
          backHandRun = true; // NEW
          foreHandRun = false; // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FED827: // PLAY/PAUSE
          Serial.println("PLAY/PAUSE button pressed");
          backHandRun = false;  // NEW
          foreHandRun = true;  // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FEF807: // PLAY/PAUSE
          Serial.println("PLAY/1 button pressed");
          backHandRun = false;  // NEW
          foreHandRun = false;  // NEW
          stopHandRun = true; // NEW
          break;
      }
      delay(10);
      irrecv.resume();
    }

  }
  lastIRstate = IRstate;
  foreHand();
  backHand();
  stopHand();
}
void foreHand() { // I want this to loop until i press a button on the remote

  if (foreHandRun == true) { // new

    leftRightservo.write(180);
    delay(1000);
    leftRightservo.write(0);
    delay(1000);
    leftRightservo.write(180);
    delay(1000);
  }

}
void backHand() { // I want this to loop until i press a button on the remote

  if (backHandRun == true) { // new
    leftRightservo.write(45);
    delay(500);
    leftRightservo.write(90);
    delay(500);
  }
}
void stopHand() { // I want this to loop until i press a button on the remote

  if (stopHandRun == true) { // new
    leftRightservo.write(90);

  }
}

And below code is same code but with millis()

const unsigned long event = 10;
const unsigned long eventy = 1000;
const unsigned long eventu = 500;
unsigned long prevperiod = 0;
unsigned long prevperiodf = 0;
unsigned long prevperiodg = 0;

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

const int receiver = 8; // Infrared receiver output pin( TSOP4838 )

boolean backHandRun = false;  // NEW
boolean foreHandRun = false;  // NEW
boolean stopHandRun = false;  // NEW


int IRstate;
int lastIRstate;

IRrecv irrecv(receiver);
decode_results results;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  leftRightservo.attach(10);
  int position = 90;

}

void loop() {
 

  IRstate = digitalRead(receiver);

  if (IRstate != lastIRstate) {

    if (irrecv.decode(&results)) {
      switch (results.value) {

        case 0x1FE50AF: // MENU
          Serial.println("MENU button pressed");
          backHandRun = true; // NEW
          foreHandRun = false; // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FED827: // PLAY/PAUSE
          Serial.println("PLAY/PAUSE button pressed");
          backHandRun = false;  // NEW
          foreHandRun = true;  // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FEF807: // PLAY/PAUSE
          Serial.println("PLAY/1 button pressed");
          backHandRun = false;  // NEW
          foreHandRun = false;  // NEW
          stopHandRun = true; // NEW
          break;
      }
unsigned long currentTime = millis();
      if (currentTime - prevperiod >= event) {
        irrecv.resume();
         prevperiod= currentTime;
      }
    }

  }
  lastIRstate = IRstate;
  foreHand();
  backHand();
  stopHand();
}
void foreHand() { // I want this to loop until i press a button on the remote
  unsigned long currentTime = millis();
  if (foreHandRun == true) {
    // new

    if (currentTime - prevperiodf >= eventy) {
      leftRightservo.write(180);
    }
    prevperiodf = currentTime;
    if (currentTime - prevperiodf >= eventy) {
      leftRightservo.write(0);
    }
    prevperiodf = currentTime;

    leftRightservo.write(180);

  }

}
void backHand() { // I want this to loop until i press a button on the remote
  unsigned long currentTime = millis();
  if (backHandRun == true) { // new

    if (currentTime - prevperiodg >= eventu) {
      leftRightservo.write(45);
    }
    prevperiodg = currentTime;
    if (currentTime - prevperiodg >= eventu) {
      leftRightservo.write(90);
     prevperiodg = currentTime;
    }


  }
}
void stopHand() { // I want this to loop until i press a button on the remote
  unsigned long currentTime = millis();
  if (stopHandRun == true) { // new
    leftRightservo.write(90);

  }
}

Here using milis, my loop does not continue and only execute first command from loop.

I m stucked here

You still wrote all tasks sequential in all functions. But the thing is, you want to just do the correct thing and leave the function. So you need a state machine. And every time the period passed you do the next state.

So it becomes something like

void foreHand() { // I want this to loop until i press a button on the remote
  static byte state = 0;
  unsigned long currentTime = millis();
  
  if (foreHandRun == true) {
    if (currentTime - previousPeriod >= eventy) {
      previousPeriod = currentTime;
      
      switch(state){
        case 0:
          leftRightservo.write(180);
          break;
        case 1:
          leftRightservo.write(0);
          break;
      }
      
      state++;
      if(state == 2){
        state = 0;
      }
    }
  }
}

PS I would do the flag check in the loop(). Makes it more clear
PPS You can use 'results.value' to determine a new button is pressed. That way you don't need to also read the pin with digitalRead() and have an "event".

  if (irrecv.decode(&results)) {
    if(results.value != previousButton) {
      previousButton = results.value;
      
      switch (results.value) {
        case 0x1FE50AF: // MENU
          Serial.println("MENU button pressed");
          backHandRun = true; // NEW
          foreHandRun = false; // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FED827: // PLAY/PAUSE
          Serial.println("PLAY/PAUSE button pressed");
          backHandRun = false;  // NEW
          foreHandRun = true;  // NEW
          stopHandRun = false; // NEW
          break;

        case 0x1FEF807: // PLAY/PAUSE
          Serial.println("PLAY/1 button pressed");
          backHandRun = false;  // NEW
          foreHandRun = false;  // NEW
          stopHandRun = true; // NEW
          break;
      }
    }
  }

I think you're looking for somethy more like this

void backHand() { // I want this to loop until i press a button on the remote
  unsigned long currentTime = millis();
  if (backHandRun == true) { // new
      if(backhandNum == 90){
         backhandNum = 45;
      } else {
         backhandNum = 90;
      }
      if (currentTime - prevperiodg >= eventu){
         prevperiodg = currentTime;
         leftRightservo.write(backhandNum);
       }
}

This is not tested. Need to declare backhandNum. And rename it if you want.

EDIT:
I posted this on his other thread before it was merged with no idea folks were already helping him with this issue. I merely addressed what I saw as his issue using millis. You folks, as usual, are addressing issues with his entire code. Which is a good thing.

Didn't you like the answers in your other thread on this subject ?

@Raghavtango

TOPICS MERGED.
DO NOT CROSS POST !

Please read this before posting any further.
We aim to AVOID wasting peoples time in trying to help.

Bob.

septillion:
You still wrote all tasks sequential in all functions. But the thing is, you want to just do the correct thing and leave the function. So you need a state machine. And every time the period passed you do the next state.

So it becomes something like

void foreHand() { // I want this to loop until i press a button on the remote

static byte state = 0;
  unsigned long currentTime = millis();
 
  if (foreHandRun == true) {
    if (currentTime - previousPeriod >= eventy) {
      previousPeriod = currentTime;
     
      switch(state){
        case 0:
          leftRightservo.write(180);
          break;
        case 1:
          leftRightservo.write(0);
          break;
      }
     
      state++;
      if(state == 2){
        state = 0;
      }
    }
  }
}




PS I would do the flag check in the loop(). Makes it more clear
PPS You can use 'results.value' to determine a new button is pressed. That way you don't need to also read the pin with digitalRead() and have an "event".



if (irrecv.decode(&results)) {
    if(results.value != previousButton) {
      previousButton = results.value;
     
      switch (results.value) {
        case 0x1FE50AF: // MENU
          Serial.println("MENU button pressed");
          backHandRun = true; // NEW
          foreHandRun = false; // NEW
          stopHandRun = false; // NEW
          break;

case 0x1FED827: // PLAY/PAUSE
          Serial.println("PLAY/PAUSE button pressed");
          backHandRun = false;  // NEW
          foreHandRun = true;  // NEW
          stopHandRun = false; // NEW
          break;

case 0x1FEF807: // PLAY/PAUSE
          Serial.println("PLAY/1 button pressed");
          backHandRun = false;  // NEW
          foreHandRun = false;  // NEW
          stopHandRun = true; // NEW
          break;
      }
    }
  }





Thanks a ton to you.

its working perfectly.

Even i used switch in loop() but i could not think of using loop in function because i was struggling with using millis and now i know how to use millis accordingly. btw I just bought adruino uno 7 days back and people on this forum have helped to build up a program. :)