Making an integer reset if no change happens

Hi, I'm a beginner who's trying to design a simple project for school. I wanted to use a rotary encoder so I used this code I found online to quickly get there and it works. What I want to do is I want the counter to reset if the value doesn't change for a certain amount of time. How can I do it?

/*     Arduino Rotary Encoder Tutorial
 *      
 *  by Dejan Nedelkovski, www.HowToMechatronics.com
 *  
 */
 
 #define outputA 6
 #define outputB 7

 int counter = 0; 
 int aState;
 int aLastState;  

 void setup() { 
   pinMode (outputA,INPUT);
   pinMode (outputB,INPUT);
   
   Serial.begin (9600);
   // Reads the initial state of the outputA
   aLastState = digitalRead(outputA);   
 } 

 void loop() { 
   aState = digitalRead(outputA); // Reads the "current" state of the outputA
   // If the previous and the current state of the outputA are different, that means a Pulse has occured
   if (aState != aLastState){     
     // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
     if (digitalRead(outputB) != aState) { 
       counter ++;
     } else {
       counter --;
     }
     Serial.print("Position: ");
     Serial.println(counter);
   } 
   aLastState = aState; // Updates the previous state of the outputA with the current state
 }

using millis()

Look at File|Examples|02.Digital|BlinkWithoutDelay to use millis() for timing instead of delay().

1 Like

Thanks for the help! What I understand from this is that it's used to do something every x amount of time. What I need is that the counter should reset when I stop rotating the encoder.

1 Like

the code that detect the stop roating of the encoder could set pastTime=millis() to begin the timing.

1 Like

Create a global timer variable:
unsigned long LastValueChangeTime = 0;

In loop(), reset your value if the timer reaches the timeout:

  if (millis() - LastValueChangeTime > TimeoutInterval)
  {
    counter = 0;
  }

Then you reset the timer each time the value changes:

     if (digitalRead(outputB) != aState) { 
       counter ++;
       LastValueChangeTime = millis();
     } else {
       counter --;
       LastValueChangeTime = millis();
     }
1 Like

Thank you! This is exactly it. It solved %99 percent of my problems. The only thing I need to fix is that when its reset, the first movement adds up and then its reset. For ex: The counter is at 33, I wait the Timeout Interval to reset it and I move the encoder again. It goes up to 34 or down to 32 depending on direction and then it goes back to zero.

/*     Arduino Rotary Encoder Tutorial
 *      
 *  by Dejan Nedelkovski, www.HowToMechatronics.com
 *  
 */
 
 #define outputA 6
 #define outputB 7

 int counter = 0; 
 int aState;
 int aLastState;  
 unsigned long LastValueChangeTime = 0;
 unsigned long TimeoutInterval = 1000;

 void setup() { 
   pinMode (outputA,INPUT);
   pinMode (outputB,INPUT);
   
   Serial.begin (9600);
   // Reads the initial state of the outputA
   aLastState = digitalRead(outputA);   
 } 

 void loop() { 
   aState = digitalRead(outputA); // Reads the "current" state of the outputA
   // If the previous and the current state of the outputA are different, that means a Pulse has occured
   if (millis() - LastValueChangeTime > TimeoutInterval)
  {
    counter = 0;
  }
   if (aState != aLastState){     
     // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
     if (digitalRead(outputB) != aState) { 
       counter ++;
       LastValueChangeTime = millis();
     } else {
       counter --;
       LastValueChangeTime = millis();
     }
      
     Serial.print("Position: ");
     Serial.println(counter);
   } 
   aLastState = aState; // Updates the previous state of the outputA with the current state
 }

once millis has timed out the if statement setting counter to 0 will always be true.

/*     Arduino Rotary Encoder Tutorial
 *      
 *  by Dejan Nedelkovski, www.HowToMechatronics.com
 *  
 */
 
 #define outputA 6
 #define outputB 7

 int counter = 0; 
 int aState;
 int aLastState;  
 unsigned long LastValueChangeTime = 0;
 unsigned long TimeoutInterval = 1000;
bool triggered = false;

 void setup() { 
   pinMode (outputA,INPUT);
   pinMode (outputB,INPUT);
   
   Serial.begin (9600);
   // Reads the initial state of the outputA
   aLastState = digitalRead(outputA);   
 } 

 void loop() { 
   aState = digitalRead(outputA); // Reads the "current" state of the outputA
   // If the previous and the current state of the outputA are different, that means a Pulse has occured
   if ( triggered && (millis() - LastValueChangeTime > TimeoutInterval))
  {
triggered = false; <<<<<< find a spot to turn tirgger to true.
    counter = 0;
  }
   if (aState != aLastState){     
     // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
     if (digitalRead(outputB) != aState) { 
       counter ++;
       LastValueChangeTime = millis();
triggered = true;
     } else {
       counter --;
       LastValueChangeTime = millis();
triggered = true;
     }
      
     Serial.print("Position: ");
     Serial.println(counter);
   } 
   aLastState = aState; // Updates the previous state of the outputA with the current state
 }
1 Like

If you want to see it being reset to 0 after the timeout:

   if (millis() - LastValueChangeTime > TimeoutInterval)
  {
    counter = 0;
    Serial.print("Position: ");
    Serial.println(counter);
    LastValueChangeTime = millis(); // To keep from spewing
  }
1 Like

Thanks a lot. This seems to do the trick.

Thank you for your time and help.

1 Like

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