I'm new to Arduino and with pretty poor coding skills so please be gentle
I'm trying to control a relay with a single push button (ON/OFF) and present the status in the LCD.
I succeed on doing that (WOOWWWW) but now I'm trying to add a StopWatch that will start to run when it's "ON"(after pushing the button) and when I'll push the button again it will freeze and so on.
code that seems to do exactly what I need but I don't know how to combine between this code and my code (below)... Can someone help me please???
// include the library code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
// Using a push button switch for stay-on/stay-off push button .
// beating a dead horse, again. Most of the real work is from other people.
int switch1 = 12; // connect a push button switch between this pin and ground
int ledpin = 13; // internal led, external LED, relay, trigger for other function, some other device, whatever.
boolean flag = true;
void setup()
{
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight
pinMode(ledpin,OUTPUT); // this pin controlled by flipflop() function
pinMode (switch1,INPUT_PULLUP); // keeps pin HIGH via internal pullup resistor unless brought LOW with switch
Serial.begin(9600); // just for debugging, not needed.
lcd.clear();
}
void loop()
{
if (digitalRead(switch1)==LOW){ // check the state of switch1 every time we run through the main loop
delay(5); // I don't REALLY know why this delay helps, but it does.
flipflop(); // hops out of main loop and runs the flipflop function
}// end of check for button press.
// other sketch code here
} // end of main loop.
void flipflop(){ //funtion flipflop
flag = !flag; // since we are here, the switch was pressed So FLIP the boolian "flag" state (we don't even care if switch was released yet)
Serial.print("flag = " ); Serial.println(flag); // not needed, but may help to see what's happening.
if (flag == HIGH){ // Use the value of the flag var to change the state of the pin
digitalWrite(ledpin,HIGH ); // if the flag var is HIGH turn the pin on
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>ON ");
Serial.print("ON");
}
if (flag == LOW) {
digitalWrite(ledpin,LOW); // if the flag var is LOW turn the pin off
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>OFF");
Serial.print("OFF");
}
while(digitalRead(switch1)==LOW); // for "slow" button release, keeps us in the function until button is UN-pressed
// If you take out this "while" the function becomes a flipflop oscillator if the button is held down.
delay(50); // OPTIONAL - play with this value. It is probably short enough to not cause problems. deals with very quick switch press.
}
if (digitalRead(switch1)==LOW){ // check the state of switch1 every time we run through the main loop
delay(5); // I don't REALLY know why this delay helps, but it does.
flipflop(); // hops out of main loop and runs the flipflop function
}// end of check for button press.
The delay is for debouncing purpose. If you don't know what it means, just google for "arduino button debouncing' and you'll find lots of explaination.
In this piece of code, when the button in pressed, you run a function (called flipflop) that displays a message on your LCD. You just need to take what you want from the code you found and put it in another function that you can call just after 'flipflop();'
I see this is about controlling a heater. If what you want is to display the time during which the heater is on, then you can also add your new code into the flipflop function. Or you can return the value of the flag variable to use it in your new function.
The notes in the code are not mine but thanks for the explanation mate.
This is exactly what I'm trying to do
I though about calling the function that start and freeze the StopWatch somewhere here.
But the problem is that the StopWatch code has so many functions and I couldn't figure out what start the StopWatch and what freezing it. I don't know what I should keep and what should I remove from the StopWatch code...
if (flag == HIGH){ // Use the value of the flag var to change the state of the pin
digitalWrite(ledpin,HIGH ); // if the flag var is HIGH turn the pin on
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>ON ");
Serial.print("ON");
lcd.setCursor(0,1);
>>>>>>Start the StopWatch from 0 here
}
if (flag == LOW) {
digitalWrite(ledpin,LOW); // if the flag var is LOW turn the pin off
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>OFF");
Serial.print("OFF");
lcd.setCursor(0,1);
>>>>>>>Freeze the StopWatch here
}
It depends on what you mean by "freeze". When you restart the SW, does it start from zero again or from the time it stopped?
Anyways, the basic principle is the same : you have to use the millis() function. This function provides the number of milliseconds since the moment the code began to run.
So, you need to use a variable to store the SW value, let's call it stopWatch. Declare it global before the setup:
unsigned long stopWatch = 0;
Then, whenever you want to start the SW, you store in that variable the millis value
stopWatch = millis();
Anytime you want to know the time since the SW was launched, just compute
millis() - stopWatch
and change it to hours - minutes - seconds using the code in your link
If you want to stop the SW, store this millis() - stopWatch value in another (unsigned long) variable. You'll use it to display the time or to restart from this moment.
If you want to start the SW from zero, just initialize the stopWatch variable with millis() again.
I hope it's clear, if not just ask and I'll help...
OK. I tried to use your instructions, I combined the 2 codes and I have some progress! wowww
But, I think I did something wrong because now I'm facing 2 problems:
The time doesn't run on the LCD screen when I click ON, it does run in the back (because I see the time added when I'm clicking OFF).
When I'm clicking "ON" it doesn't start from zero, it starts from the time presenting on the screen in OFF mode.
Any idea?
// include the library code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
// Using a push button switch for stay-on/stay-off push button .
// beating a dead horse, again. Most of the real work is from other people.
int switch1 = 12; // connect a push button switch between this pin and ground
int ledpin = 13; // internal led, external LED, relay, trigger for other function, some other device, whatever.
boolean flag = true;
//StopWatch
int blinking; // condition for blinking - timer is timing
int frameRate = 100; // the frame rate (frames per second) at which the stopwatch runs - Change to suit
long interval = (1000/frameRate); // blink interval
long previousMillis = 0; // variable to store last time LED was updated
unsigned long startTime = 0; // start time for stop watch
unsigned long elapsedTime = 0; // elapsed time for stop watch
int fractional; // variable used to store fractional part of Frames
int fractionalSecs; // variable used to store fractional part of Seconds
int fractionalMins; // variable used to store fractional part of Minutes
int elapsedFrames; // elapsed frames for stop watch
int elapsedSeconds; // elapsed seconds for stop watch
int elapsedMinutes; // elapsed Minutes for stop watch
char buf[10]; // string buffer for itoa function
void setup()
{
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight
pinMode(ledpin,OUTPUT); // this pin controlled by flipflop() function
pinMode (switch1,INPUT_PULLUP); // keeps pin HIGH via internal pullup resistor unless brought LOW with switch
Serial.begin(9600); // just for debugging, not needed.
lcd.clear();
}
void loop()
{
if (digitalRead(switch1)==LOW){ // check the state of switch1 every time we run through the main loop
delay(200); // I don't REALLY know why this delay helps, but it does.
flipflop(); // hops out of main loop and runs the flipflop function
}// end of check for button press.
// other sketch code here
} // end of main loop.
void flipflop(){ //funtion flipflop
flag = !flag; // since we are here, the switch was pressed So FLIP the boolian "flag" state (we don't even care if switch was released yet)
Serial.print("flag = " ); Serial.println(flag); // not needed, but may help to see what's happening.
if (flag == HIGH){ // Use the value of the flag var to change the state of the pin
digitalWrite(ledpin,HIGH ); // if the flag var is HIGH turn the pin on
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>ON ");
Serial.print("ON");
millis() - elapsedTime; // store elapsed time
blinking = true; // turn on timing
delay(10); // short delay to debounce switch
lcd.setCursor(0,1);
// Routine to report elapsed time
elapsedMinutes = (elapsedTime / 60000L); // divide by 60000 to convert to minutes - then cast to an int to print
elapsedSeconds = (elapsedTime / 1000L); // divide by 1000 to convert to seconds - then cast to an int to print
elapsedFrames = (elapsedTime / interval); // divide by 40 to convert to 1/25 of a second - then cast to an int to print
fractional = (int)(elapsedFrames % frameRate);// use modulo operator to get fractional part of 25 Frames
fractionalSecs = (int)(elapsedSeconds % 60L); // use modulo operator to get fractional part of 60 Seconds
fractionalMins = (int)(elapsedMinutes % 60L); // use modulo operator to get fractional part of 60 Minutes
if (fractionalMins < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalMins, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
lcd.print(":"); //print a colan.
if (fractionalSecs < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalSecs, buf, 10)); // convert the int to a string and print a fractional part of 60 Seconds to the LCD
lcd.print(":"); //print a colan.
if (fractional < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa((fractional), buf, 10)); // convert the int to a string and print a fractional part of 25 Frames to the LCD
}
if (flag == LOW) {
digitalWrite(ledpin,LOW); // if the flag var is LOW turn the pin off
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>OFF");
Serial.print("OFF");
elapsedTime = millis();
blinking = false; // turn off timing
delay(10); // short delay to debounce switch
lcd.setCursor(0,1);
// Routine to report elapsed time
elapsedMinutes = (elapsedTime / 60000L);
elapsedSeconds = (elapsedTime / 1000L); // divide by 1000 to convert to seconds - then cast to an int to print
elapsedFrames = (elapsedTime / interval); // divide by 100 to convert to 1/100 of a second - then cast to an int to print
fractional = (int)(elapsedFrames % frameRate); // use modulo operator to get fractional part of 100 Seconds
fractionalSecs = (int)(elapsedSeconds % 60L); // use modulo operator to get fractional part of 60 Seconds
fractionalMins = (int)(elapsedMinutes % 60L); // use modulo operator to get fractional part of 60 Minutes
if (fractionalMins < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalMins, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
lcd.print(":"); //print a colan.
if (fractionalSecs < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalSecs, buf, 10)); // convert the int to a string and print a fractional part of 60 Seconds to the LCD
lcd.print(":"); //print a colan.
if (fractional < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractional, buf, 10)); // convert the int to a string and print a fractional part of 25 Frames to the LCD
}
}
// include the library code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
// Using a push button switch for stay-on/stay-off push button .
// beating a dead horse, again. Most of the real work is from other people.
int switch1 = 12; // connect a push button switch between this pin and ground
int ledpin = 13; // internal led, external LED, relay, trigger for other function, some other device, whatever.
boolean flag = false;
//StopWatch
int blinking; // condition for blinking - timer is timing
int buttonState;
int lastButtonState;
int frameRate = 5; // the frame rate (frames per second) at which the stopwatch runs - Change to suit
long interval = (1000/frameRate); // blink interval
long previousMillis = 0; // variable to store last time LED was updated
long startTime; // start time for stop watch
long elapsedTime; // elapsed time for stop watch
int fractional; // variable used to store fractional part of Frames
int fractionalSecs; // variable used to store fractional part of Seconds
int fractionalMins; // variable used to store fractional part of Minutes
int fractionalHrs;
int elapsedFrames; // elapsed frames for stop watch
int elapsedSeconds; // elapsed seconds for stop watch
int elapsedMinutes; // elapsed Minutes for stop watch
int elapsedHrs;
char buf[10]; // string buffer for itoa function
void setup()
{
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight
pinMode(ledpin,OUTPUT); // this pin controlled by flipflop() function
pinMode (switch1,INPUT_PULLUP); // keeps pin HIGH via internal pullup resistor unless brought LOW with switch
Serial.begin(9600); // just for debugging, not needed.
lcd.clear();
}
/*void loop()
{
buttonState = digitalRead(switch1);
if (buttonState==LOW){ // check the state of switch1 every time we run through the main loop
#delay(200); // I don't REALLY know why this delay helps, but it does.
flipflop(); // hops out of main loop and runs the flipflop function
}// end of check for button press.
// other sketch code here
} // end of main loop.*/
void loop(){
buttonState = digitalRead(switch1);
if (buttonState == LOW && lastButtonState == HIGH && flag == false){
startTime = millis(); // store the start time
flag = true; // turn on blinking while timing
delay(10); // short delay to debounce switch
lastButtonState = buttonState; // store buttonState in lastButtonState, to compare next time
}
else if (buttonState == LOW && lastButtonState == HIGH && flag == true){
flag = false; // turn off blinking, all done timing
lastButtonState = buttonState; // store buttonState in lastButtonState, to compare next time
// Routine to report elapsed time
elapsedTime = millis() - startTime; // store elapsed time
elapsedMinutes = (elapsedTime / 60000L);
elapsedSeconds = (elapsedTime / 1000L); // divide by 1000 to convert to seconds - then cast to an int to print
elapsedHrs = (elapsedTime / 3600000L);
elapsedFrames = (elapsedTime / interval); // divide by 100 to convert to 1/100 of a second - then cast to an int to print
fractional = (int)(elapsedFrames % frameRate); // use modulo operator to get fractional part of 100 Seconds
fractionalSecs = (int)(elapsedSeconds % 60L); // use modulo operator to get fractional part of 60 Seconds
fractionalMins = (int)(elapsedMinutes % 60L); // use modulo operator to get fractional part of 60 Minutes
fractionalHrs = (int)(elapsedHrs % 60L);
digitalWrite(ledpin,LOW); // if the flag var is LOW turn the pin off
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>OFF ");
lcd.setCursor(0,1);
if (fractionalHrs < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalHrs, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
lcd.print(":");
if (fractionalMins < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalMins, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
lcd.print(":"); //print a colan.
if (fractionalSecs < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalSecs, buf, 10)); // convert the int to a string and print a fractional part of 60 Seconds to the LCD
/*if (fractional < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractional, buf, 10)); // convert the int to a string and print a fractional part of 25 Frames to the LCD
*/}
else{
lastButtonState = buttonState; // store buttonState in lastButtonState, to compare next time
}
if ( (millis() - previousMillis > interval) ) {
if (flag == true){
previousMillis = millis(); // remember the last time we blinked the LED
elapsedTime = millis() - startTime; // store elapsed time
elapsedMinutes = (elapsedTime / 60000L); // divide by 60000 to convert to minutes - then cast to an int to print
elapsedSeconds = (elapsedTime / 1000L); // divide by 1000 to convert to seconds - then cast to an int to print
elapsedFrames = (elapsedTime / interval); // divide by 40 to convert to 1/25 of a second - then cast to an int to print
fractional = (int)(elapsedFrames % frameRate);// use modulo operator to get fractional part of 25 Frames
fractionalSecs = (int)(elapsedSeconds % 60L); // use modulo operator to get fractional part of 60 Seconds
fractionalMins = (int)(elapsedMinutes % 60L); // use modulo operator to get fractional part of 60 Minutes
elapsedHrs = (elapsedTime / 3600000L);
fractionalHrs = (int)(elapsedHrs % 60L);
digitalWrite(ledpin,HIGH ); // if the flag var is HIGH turn the pin on
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Water Heater>ON ");
lcd.setCursor(0,1); // clear the LDC
if (fractionalHrs < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalHrs, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
lcd.print(":");
if (fractionalMins < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalMins, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
lcd.print(":"); //print a colan.
if (fractionalSecs < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa(fractionalSecs, buf, 10)); // convert the int to a string and print a fractional part of 60 Seconds to the LCD
/* if (fractional < 10){ // pad in leading zeros
lcd.print("0"); // add a zero
}
lcd.print(itoa((fractional), buf, 10)); // convert the int to a string and print a fractional part of 25 Frames to the LCD
*/}
}
}