Go Down

Topic: Kitchen Timer with Relay and Magnetic Switch (Read 1 time) previous topic - next topic

sholland91

So I have worked some more on this project and can control the Relay now by using pinMode(Relay, LOW) and HIGH.
I noticed that sometimes when I turn on the timer, it is much faster than 1 second between counting down seconds. It quickly drops to zero. This only happens after I disconnect the switch and reconnect it a couple of times... Any ideas why this is happening?

Thanks!

Code: [Select]

#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

boolean colonOn = false;
boolean Timer_Pause = false;
boolean Relay_On = 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);

  digitalWrite(Relay, OUTPUT);
  //  pinMode(Relay, LOW);

  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));

    if (isFwd == 1) //if Encoder is moved forwards (CW), advance seconds by defined increment value
    {
      delay(75); // prevents bad readings
      seconds= seconds + increment;
    }
    if (isFwd == 0) // if encoder is moved backwards(CCW):
    {
      delay(75);
      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:
  {
    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
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
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 (Timer_Pause == false)
  {
    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)
    {
      pinMode(Relay, LOW);
      Serial7Segment.print("----"); //Send the hour and minutes to the display
      mode = Set_Timer;
    }
  }
  else
  {
    mode = Set_Timer;
  }
}


void setup()
{
  // configure the pins
  _ResetPins();

  // init serial communication
  //  Serial.begin(9600);
  //  Serial.println("Ready to begin");
  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("----"); //Send the hour and minutes to the display
}


void loop()
{
  //    if (Relay_On == true)
  //  {
  //    pinMode(Relay, HIGH);
  //  }
  //  else
  //  {
  //    pinMode(Relay, LOW);
  //  }
  if (digitalRead(MagSwitch) == LOW){ //if magnetic switch is detected
    // switches modes depending on button press
    Relay_On = false;

    switch(mode){
      pinMode(Relay, LOW);
      case (Set_Timer): //reads encoder and sets time
      ReadEncoder();
      break;

      case (Run_Timer): //counts down timer
      delay(175);
      pinMode(Relay, HIGH);
      countdownTimer();
      break;
    }
  }
  else if (digitalRead(MagSwitch) == HIGH) //if no magnetic switch detected
  {
    pinMode (Relay, LOW);
    minutes = 0;
    seconds = 0;
    Serial7Segment.print("----"); //Send the hour and minutes to the display
    mode = Set_Timer;
  } 
}



PeterH

I don't know whether this is causing your problem, but you seem to be confusing pinMode and digitalWrite:

Code: [Select]

digitalWrite(Relay, OUTPUT);
pinMode(Relay, LOW);


Do you really mean to change the pin modes during the sketch?
I only provide help via the forum - please do not contact me for private consultancy.

sholland91


I don't know whether this is causing your problem, but you seem to be confusing pinMode and digitalWrite:

Code: [Select]

digitalWrite(Relay, OUTPUT);
pinMode(Relay, LOW);


Do you really mean to change the pin modes during the sketch?


I don't want to do it, but if I use digitalWrite(Relay, HIGH); or LOW, then the relay doesn't turn on or off at all. I'm using a Sparkfun Beefy Relay kit and can see the status LED quickly blink but that's it...

Is there a better way to do this? I tried making another if statement in my loop that uses a boolean Relay_On and would adjust the relay accordingly, but it doesn't work either.

PeterH


Is there a better way to do this?


I'm not familiar with that relay board, but I assume it takes a digital output and uses it to control the relay. In that case you would call pinMode(Relay, OUTPUT); once within setup(), and then call digitalWrite(Relay, HIGH); and digitalWrite(Relay, LOW); to turn the relay on and off as required.
I only provide help via the forum - please do not contact me for private consultancy.

sholland91



Is there a better way to do this?


I'm not familiar with that relay board, but I assume it takes a digital output and uses it to control the relay. In that case you would call pinMode(Relay, OUTPUT); once within setup(), and then call digitalWrite(Relay, HIGH); and digitalWrite(Relay, LOW); to turn the relay on and off as required.


So I was messing up and used pinMode(Relay, LOW) before and after fixing it, everything works out! There is still a problem though: when I start the timer, it quickly jumps a few seconds. Usually 3, but sometimes 15, and sometimes it counts really fast all the way down.

Go Up