Stopwatch reset

Hi, I am doing a project that requires a timer. The timer will start once the switch is pressed and it will stop after 10 secs. If the switch is pressed again the timer will restart. I am only using one switch for this. A solenoid valve also closes/open when the switch is pressed. Here's my code:

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F);

byte Valve = 2;
byte Switch = 3;
byte LED = 4;

float i;
float a = millis();
float c;
int timerMode = 0;

// variable to hold the valve state
boolean valveState = LOW;

// variable to hold the switch state
boolean oldSwitchState = LOW;

// used for simple debouce
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(Valve, OUTPUT);
  pinMode(Switch, INPUT);
  digitalWrite(Valve, HIGH); // Valve is open
  digitalWrite(LED, LOW); // LED is OFF
  lcd.begin(20, 4);
  lcd.backlight();
  lcd.clear();
}

void loop()
{
  newSwitchState1 = digitalRead(Switch);     delay(1);
  newSwitchState2 = digitalRead(Switch);     delay(1);
  newSwitchState3 = digitalRead(Switch);
  // if all 3 values are the same we can continue
  if (  (newSwitchState1 == newSwitchState2) && (newSwitchState1 == newSwitchState3) )
  {

    if ( newSwitchState1 != oldSwitchState )
    {
      oldSwitchState = newSwitchState1;  // has the button switch been closed?

      if ( newSwitchState1 == HIGH )
      {
        if (valveState == LOW)
        {
          valveState = HIGH;
          digitalWrite(LED, HIGH);   // LED is ON
          digitalWrite(Valve, LOW);  // Valve is close
          a = millis();

          while (valveState == HIGH)
          {
            if (i <= 10)
            {
              c = millis();
              i = (c - a) / 1000;
              lcd.setCursor(7, 2);
              lcd.print(i);
            }
            else
            {
              valveState = LOW;
              digitalWrite(LED, LOW);   // LED is OFF
              digitalWrite(Valve, HIGH);  // Valve is open
            }
          }
        }
      }
    }
  }
  displayText();
}

void displayText()
{
  lcd.setCursor(0, 0);
  lcd.print("iWeight: ");
  lcd.setCursor(15, 0);
  lcd.print("kg");
  lcd.setCursor(0, 1);
  lcd.print("fWeight: ");
  lcd.setCursor(15, 1);
  lcd.print("kg");
  lcd.setCursor(0, 2);
  lcd.print("Timer: ");
  lcd.setCursor(13, 2);
  lcd.print("secs");
  lcd.setCursor(0, 3);
  lcd.print("FC: ");
  lcd.setCursor(10, 3);
  lcd.print("L/h");
}

Thank you.

Do you have a question ?

millis returns unsigned long.

Floats are almost never needed for most applications. Their principal use is where you need to display a non-integer value for human viewing.

Is this some sort of debounce accommodation? Never seen it done this way...

  newSwitchState1 = digitalRead(Switch);     delay(1);
  newSwitchState2 = digitalRead(Switch);     delay(1);
  newSwitchState3 = digitalRead(Switch);
  // if all 3 values are the same we can continue
  if (  (newSwitchState1 == newSwitchState2) && (newSwitchState1 == newSwitchState3) )

How is your switch wired? Your code implies it has a pull-down resistor.

If this while loop works it doesn't allow you to interrupt the 10 second solenoid period:

          while (valveState == HIGH)
          {
            if (i <= 10)
            {
              c = millis();
              i = (c - a) / 1000;
              lcd.setCursor(7, 2);
              lcd.print(i);
            }
            else
            {
              valveState = LOW;
              digitalWrite(LED, LOW);   // LED is OFF
              digitalWrite(Valve, HIGH);  // Valve is open
            }
          }

My suggestions:

  1. Do not use float for the time! It should be unsigned long for millis().
  2. Get rid of the while loop and use a simple state machine or boolean so you can interrupt the 10 second solenoid cycle with the switch
  3. Use a more conventional way of handling switch debounce.

The following tutorials should help:

StateChangeDetection
State Machine
BlinkWithoutDelay

1 Like

Thank you. i followed the State Machine tutorial and it's working the way I want it to be. However, when I print the timer (10 secs), I am getting '10027'. I simply tried dividing it by 1000.0 to get '10.02' but it did not work.

Got the timer working in decimal already. Thank you again for the tutorials you provided.

1 Like

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