Kitchen Timer with Relay and Magnetic Switch

Still can't see your code.

It's posted above.... Not sure what's going on there.

However, your functions are doing too much. ReadEncoder() should do exactly that and NOTHING more.
ReadEncoderAndDoABunchOfOtherCrap() would read the encoder and do a bunch of other crap.

So you can see my code? Not sure what you mean here either. Does it matter? Is this causing problems with my program?

Of course, if you really had a function like that, I'd just hit the back button and move onto the next post.

What does this mean?

Besides, it's hard to see the function of an encoder in a post titled "Kitchen Timer with Relay and Magnetic Switch", so some comments in the code would be helpful.

There are comments all over my code... Read the first post for some background information. The encoder is used as an input device for incrementing the seconds on a kitchen timer. When the button on the encoder is pressed in, the timer starts and the relay turns on. My problem is that the timer sometimes counts down way faster than 1 second each second. Some times it races down 45 seconds and resumes counting normally. Sometimes is races all the way down to zero. I think this has to do with the millis() command, as I wrote above.

You have very few Serial.print() statements to learn what the code is really doing.

I removed them after I set up my code and got it working, thinking that it could be the reason why the numbers are counting so fast sometimes. The only issue right now is the counter, and a serial.println of that mirrors what the 7 segment display is showing me.

Here's the updated code:

#include <SoftwareSerial.h>

//CONFIGURATION:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Connect 7 Segment LED with RX at Pin 7 and SS at Pin 8
SoftwareSerial Serial7Segment(8, 7); 

//Configures the pins for the Encoder:
//Connect Pin A of encoder to Pin 14 (A0) and Pin C of encoder to Pin 15 (A1), Pin B goes to ground
//Connect Button to either encoder pins, other goes to ground
enum enDigitalPins
{
  dpInEncoderA=14,
  dpInEncoderB=15,
  dpInEncoderPress=12,
};

#define MagSwitch  13
#define Relay       2

// this value determines how many seconds are incremented each time the encoder is rotated
int increment = 10; 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
long millisTimer;
byte seconds = 00;
byte minutes = 00;
byte hours = 00;

int mode = 0;
char tempString[100]; //Used for sprintf

#define COLON       4
#define Set_Timer   0
#define Run_Timer   1
#define Pause_Timer 2

boolean colonOn = false;

static void _ResetPins()
{
  // Rotary encoder input lines
  // Configure as input, turn on pullup resistors
  pinMode(dpInEncoderA, INPUT);
  digitalWrite(dpInEncoderA, HIGH);

  pinMode(dpInEncoderB, INPUT);
  digitalWrite(dpInEncoderB, HIGH);

  pinMode(dpInEncoderPress, INPUT);
  digitalWrite(dpInEncoderPress, HIGH);

  digitalWrite(MagSwitch, INPUT);
  pinMode(MagSwitch, LOW);

  pinMode(Relay, OUTPUT);

  Serial7Segment.write(0x77);  // Decimal, colon, apostrophe control command
  Serial7Segment.write(1<<COLON);
}


void _lowlevel_ReadEncoder(int &rotate, int& press)
{
  rotate = (digitalRead(dpInEncoderB) * 2) + digitalRead(dpInEncoderA);
  press = digitalRead(dpInEncoderPress);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ReadEncoder() //Reads the State of the Encoder and adjust the Display accordingly. CW rotation = + "increment" seconds, CCW = - "increment" seconds
{
  int Position, Press;
  int isForward = 0;
  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(100);
    if (isFwd == 1) //if Encoder is moved forwards (CW), advance seconds by defined increment value
    {
      //      delay(200); // prevents bad readings
      seconds= seconds + increment;
    }
    if (isFwd == 0) // if encoder is moved backwards(CCW):
    {
      //      delay(200);
      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 = 50;
        }
      }
      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(250);
    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(dpInEncoderPress)== LOW)
  {
    delay(250);
    mode = Pause_Timer;
  }
}

void PauseTimer()
{
  int seconds_hold;
  int minutes_hold;
  seconds_hold = seconds;
  minutes_hold = minutes;

  minutes = minutes_hold;
  seconds = seconds_hold;
  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

  if (digitalRead(dpInEncoderPress)== LOW)
  {
    delay(75);
    mode = Run_Timer;
  }

  mode = Set_Timer;
}

void setup()
{
  // configure the pins
  _ResetPins();
  
  Serial.begin(9600);

  Serial7Segment.begin(9600); //Talk to the Serial7Segment at 9600 bps
  Serial7Segment.write('v'); //Reset the display - this forces the cursor to return to the beginning of the display
  Serial7Segment.print("0000"); //Send the hour and minutes to the display
}

void loop()
{
  if (digitalRead(MagSwitch) == LOW) //if magnetic switch is detected
    // switches modes depending on button press
  {
    switch(mode){
      digitalWrite(Relay, LOW); //Relay off
      case (Set_Timer): //reads encoder and sets time
      ReadEncoder();
      break;

      case (Run_Timer): //counts down timer
      digitalWrite(Relay, HIGH); //relay on
      countdownTimer(); //run countdown script (above)
      break;

      case (Pause_Timer): 
      digitalWrite(Relay, LOW);
      PauseTimer();
      break;      
    }
  }

  else if (digitalRead(MagSwitch) == HIGH) //if no magnetic switch detected
  {
    digitalWrite (Relay, LOW);
    minutes = 0;
    seconds = 0;
    Serial7Segment.print("OFF "); //Send the hour and minutes to the display
    mode = Set_Timer;
  }  
}

Hope this solves any issues you may have...