Hello, I am working on making a countdown timer using a rotary encoder and a 7 segment 4 digit led display.
The program works as follows:
Case 1: Set Time
- Rotate encoder to change seconds and minutes on display
- If the encoder is pressed in, switch to the Run Timer Case
Case 2: Run Timer - Counts down from the time set in Case 1
- If the encoder is pressed in, switch to the Pause Timer Case
Case 3: Pause Timer - Stop the timer from counting down.
- Rotate encoder to change seconds and minutes on display
- If the encoder is pressed in, switch to the Run Timer Case
Case 1 and 2 work perfectly. Pausing the timer allows me to change the values of the timer. When I press the encoder in again, however, the timer jumps to how many seconds have elapsed.
ie. If I pause the timer at 1:30 and wait 25 seconds before pressing the encoder again, the display quickly counts down from 1:30 to 1:05 and then continues to count as usual. If I wait more than 1:30, the timer speeds all the way down to 0.
I have tried to store my seconds and minutes values as new integers while the encoder is pressed, and then reassign the values when I press the encoder again. This does nothing though.
Below is the snippet of code that's not working. "mode = " is my switch case command.
void ReadEncoder() //Reads the State of the Encoder and adjust the Display accordingly. CW rotation = + "increment" seconds, CCW = - "increment" seconds
{
int Position, Press;
seconds = constrain (seconds, -1, 60); //constrains the seconds value between -1 and 60
_ResetPins();
_lowlevel_ReadEncoder(Position, Press);
int Position2, Press2;
do
{
_lowlevel_ReadEncoder(Position2, Press2);
}
while ((Position2 == Position) && (Press2 == Press));
if (Position2 != Position) //if there is a poisition change:
{
// "Forward" is shown by the position going from (0 to 1) or (1 to 3)
// or (3 to 2) or (2 to 0). Anything else indicates that the user is
// turning the device the other way. Remember: this is Gray code, not
// binary.
int isFwd = ((Position == 0) && (Position2 == 1)) ||
((Position == 1) && (Position2 == 3)) ||
((Position == 3) && (Position2 == 2)) ||
((Position == 2) && (Position2 == 0));
delay(Encoder_Sensitivity);
if (isFwd == 1) //if Encoder is moved forwards (CW), advance seconds by defined increment value
{
seconds= seconds + increment;
}
if (isFwd == 0) // if encoder is moved backwards(CCW):
{
if (seconds == 0)// if we are already at zero seconds, check to make sure we can reduce a minute
{
if (minutes > 0)// if the minutes can be reduced (i.e. not zero) then remove one minute and reset seconds to 59
{
minutes --;
seconds = 60-increment;
}
}
else
{
seconds = seconds - increment;//if seconds were not = 0, then decrease seconds value by the increment value
}
}
}
if (seconds>59) // When seconds = 60:
{
minutes++; // Add one minute
seconds -= 60; // Reset seconds
}
if (Press2 != Press) //if the encoder is pressed down:
{
delay(Press_Sensitivity);
mode = Run_Timer;
}
Position = Position2;
Press = Press2;
Serial7Segment.print('v');
sprintf(tempString, "%02d%02d", minutes, seconds);
Serial7Segment.print(tempString); //Send serial string out the soft serial port to the S7S
Serial.println(tempString);
}
//-------------------------------------------------------------------------------------------------
void countdownTimer() //this will start counting down from the time set using the encoder. This begins when the encoder button is pressed.
{
seconds = constrain (seconds, -1, 60);
if( (millis() - millisTimer) > 1000)
{
millisTimer += 1000; //Adjust the timer forward 1 second
if (seconds == 0)// if we are already at zero seconds, check to make sure we can reduce a minute
{
if (minutes > 0)// if the minutes can be reduced (i.e. not zero) then remove one minute and reset seconds to 59
{
minutes --;
seconds = 59;
}
}
else{
seconds--;//if seconds were not = 0, then decrease seconds value by the increment value
}
sprintf(tempString, "%02d%02d", minutes, seconds);
Serial7Segment.write(0x77); // Decimal, colon, apostrophe control command
Serial7Segment.write(1<<COLON); // Turns on colon, apostrophoe, and far-right decimal
Serial7Segment.print(tempString); //Send serial string out the soft serial port to the S7S
Serial.println(tempString);
}
if (minutes == 0 & seconds == 0)
{
digitalWrite(Relay, LOW);
Serial7Segment.print("0000"); //Send the hour and minutes to the display
mode = Set_Timer;
}
if (digitalRead(Encoder_Press)== LOW)
{
delay(Press_Sensitivity);
mode = Pause_Timer;
}
}
//-----------------------------------------------------------------------------------------
void PauseTimer()
{
seconds_hold = seconds;
minutes_hold = minutes;
sprintf(tempString, "%02d%02d", minutes_hold, seconds_hold);
Serial7Segment.write(0x77); // Decimal, colon, apostrophe control command
Serial7Segment.write(1<<COLON); // Turns on colon, apostrophoe, and far-right decimal
Serial7Segment.print(tempString); //Send serial string out the soft serial port to the S7S
if (digitalRead(Encoder_Press) == LOW)
{
delay(Press_Sensitivity);
seconds = seconds_hold;
minutes = minutes_hold;
mode = Run_Timer;
}
mode = Set_Timer;
}
Any thoughts?
Thanks!