Hello
i wanted to clear the written text on my LCD using 'external interrupt' , the external interrupt is triggered by a button when pressed , but no matter how many times i press the button the LCD wont be cleared . can Someone help me if i made a programming Mistake . Thankyou in Advance
Is this a theoretical exercise? Because in practise there is no need for an interrupt when reading a button; loop() can read that button hunderds of times in a second.
LCD.clear() might make use of interrupts; while you are in your ISR, all interrupts are disabled. The usual way to handle this is by setting a flag in the ISR and acting on it in loop().
After doing that, @lucaswilliam7868 will hopefully have an epiphany and realize there's no reason to have the interrupt / ISR at all. Just poll the button in loop().
I Wanted to make a Arduino countdown using LCD and IR receiver, 1 minute countdown begins when i press 1 on IR Remote, and if i want the countdown to stop I made a External interrupt with a button to make LCD clear when pressed, but LCD wont be cleared when i press button but LCD clear happens when countdown ends,
You don't need an interrupt if you get rid of the for-loop and the delay in your oneminute() function that you posted in Cant lcd.clear when lcd on countdown. As a rule of thumb, for-loops (and while-loops) have no place in Arduino code when it comes to timing or to waiting for something to happen; let loop() do the looping.
The below is a reworked version of your oneminute(). I've renamed i to counter and it's now local to the function. It's advisable not to use single letter variables as global variables; when code grows, it will be a mission to find them back. Because counter is declared as static, it will be remembered; this is similar to a global variable (that you declare before setup() but you don'thavethe risk to accidentally change them in other parts of the code).
The function also uses a static variable to keep track of the start of a 'delay'. Lastly the function controls a global variable countdownInProgress that indicates if countdown is in progress or not. It's initially set to false; if you call the function it will be set to true till the one minute has passed after which it will be set to false again.
// variable to indicate if countdown is in progress
bool countdownInProgress = false;
...
...
void setup()
{
...
...
}
void loop()
{
...
...
}
/*
one minute countdown timer
*/
void oneMinute()
{
static byte counter;
static uint32_t delayStarttime;
// if a new countdown needs to be started
if (countdownInProgress == false)
{
// set the timer
delayStarttime = millis();
// initialise the counter
counter = 60;
// indicate that countdown is in progress
countdownInProgress = true;
// show the countdown
lcd.setCursor(0, 0);
if (counter < 10)
{
lcd.print("0");
}
lcd.print(counter);
}
// if one second passed
if (millis() - delayStarttime >= 1000)
{
// reset the timer for next 1 second delay
delayStarttime = millis();
// decrement the counter
counter--;
// show the countdown
lcd.setCursor(0, 0);
if (counter < 10)
{
lcd.print("0");
}
lcd.print(counter);
}
// if the countdown is finished
if (counter == 0)
{
//indicate that the countdown is finished
countdownInProgress = false;
}
}
You will have to repeatedly call this function from loop(); the below will countdown from 60 to 0 and start again.
void loop()
{
oneMinute();
}
Now you can write the loop() code to do what you want it to do; the below code demonstrates using a start button and a stop button.
// sensible name for the button status when it is low
#define ISPRESSED LOW
// variable to indicate if countdown is in progress
bool countdownInProgress = false;
// start and stop button
const uint8_t pinStartButton = 3;
const uint8_t pinStopButton = 2;
...
...
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin();
pinMode(pinStartButton, INPUT_PULLUP);
pinMode(pinStopButton, INPUT_PULLUP);
}
void loop()
{
// read the start button
if (digitalRead(pinStartButton) == ISPRESSED)
{
// start the countdown
oneMinute();
}
// read the stop button
if (digitalRead(pinStopButton) == ISPRESSED)
{
// stop the countdown
countdownInProgress = false;
// clear the lcd
lcd.clear();
}
// if countdown is in progress
if (countdownInProgress == true)
// continue the countdown
oneMinute();
}
This should give you enough to get your project going. If you have questions about this, ask.
Code not tested but basically compiles if the missing pieces are filled in.
Thankyou my friend , The start button and stop button works and countdown also starts but i still face a problem , I tried to modify start button signal with the signal of My IR remote , its like when i press 1 on IR remote, IR receivers sends signal to start the countdown , problem is The countdown only decreases if I keep Pressing the 1 on IR remote or else it stops. My Apologies for taking your time but can you help me with this.
Thankyou in advance
// the code
// sensible name for the button status when it is low
#define ISPRESSED LOW
#include <IRremote.h>
#include <LiquidCrystal_I2C.h>
// start and stop button
// variable to indicate if countdown is in progress
bool countdownInProgress = false;
int receiver_pin = 9;
const uint8_t pinStopButton = 2;
LiquidCrystal_I2C lcd(0x20, 16, 2);
IRrecv receiver(receiver_pin);
decode_results output;
#define code1 41565 // to start 1 minute countdown
#define clear0 39015 // to clear lcd
void setup()
{
Serial.begin(9600);
// set up the LCD's number of columns and rows:
lcd.begin();
lcd.print("LCD TEST");
receiver.enableIRIn();
pinMode(pinStopButton, INPUT_PULLUP);
}
void loop()
{
while (receiver.decode(&output)) {
unsigned int value = output.value;
switch (value) {
case code1:
lcd.clear();
oneMinute();
break;
}
// read the stop button
if (digitalRead(pinStopButton) == ISPRESSED)
{
// stop the countdown
countdownInProgress = false;
// clear the lcd
lcd.clear();
}
// if countdown is in progress
if (countdownInProgress == true) {
// continue the countdown
oneMinute();
}
Serial.println(value);
receiver.resume();
}
}
void oneMinute()
{
static byte counter;
static uint32_t delayStarttime;
// if a new countdown needs to be started
if (countdownInProgress == false)
{
// set the timer
delayStarttime = millis();
// initialise the counter
counter = 60;
// indicate that countdown is in progress
countdownInProgress = true;
// show the countdown
lcd.setCursor(0, 0);
if (counter < 10)
{
lcd.print("0");
}
lcd.print(counter);
}
// if one second passed
if (millis() - delayStarttime >= 1000)
{
// reset the timer for next 1 second delay
delayStarttime = millis();
// decrement the counter
counter--;
// show the countdown
lcd.setCursor(0, 0);
if (counter < 10)
{
lcd.print("0");
}
lcd.print(counter);
}
// if the countdown is finished
if (counter == 0)
{
//indicate that the countdown is finished
countdownInProgress = false;
}
}