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);
}
}
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.
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.
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;
}
}
}
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.
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. :)