Arduino - To begin a timer when a button is pressed - arduino

I would like to start a timer once a button is pressed. The timer will light up an LED for five minutes. After the five minutes has expired I would like it to wait two minutes before registering another button press.

I have figured out how to do this.
I will use the Delay command for a period of time whilst LED is on high
then after the period of time I will set LED to low
and so on and so forth.
I have all the code that I have used here.
const int LED2 = 12;
const int LED = 13;
const int BUTTON = 7;
int var = 0;
int val = 0;
int old_val = 0;
int state = 0;
void setup(){ //telling the computer what the LED and the button are
pinMode (LED2,OUTPUT);
pinMode (LED,OUTPUT);
pinMode (BUTTON,INPUT);
}
void loop(){
val = digitalRead(BUTTON);
if ((val == HIGH) && (old_val == LOW)){
digitalWrite(LED,HIGH);
delay(240000); //The period of time to wait before turning on the LED2
digitalWrite(LED2,HIGH);
delay (1000);
digitalWrite(LED2,LOW);
delay (490000);
var = 0;
while(var < 10){ //A while loop to flash the LED2 on and off
digitalWrite(LED2,HIGH);
delay (500);
digitalWrite(LED2,LOW);
delay (500);
var++;
}
digitalWrite(LED,LOW);
delay(120000); //A two minute delay before the button can be pressed again
}
}

Use the built-in example program "Blink without Delay" and combine it with "Button". Both programs are available as tutorials at http://arduino.cc/en/Tutorial/HomePage Try to avoid the delay() function because it wastes the processors time and has timing inaccuracies if there are interrupts.

Related

Changing blinking duration of LED by using 2 pushbuttons and arduino

I'm trying to make an arduino UNO circuit that allows me to set the blinking duration of an LED with two pushbuttons, but I'm having trouble with the program. First of all, the default blinking duration is 0,5 s. And I want to program the first pushbutton to be able to extend the blinking duration by 0,1 seconds, whereas the second one is for speeding up the duration by 0,1 seconds.
So in my current code, I use if statements to check whether the two buttons are pressed or not. If the inc button is pressed, the program should increase the duration by 100 ms, whereas when dec button is pressed, the program should decrease the duration by 100 ms.
However when I run it on the arduino circuit, the duration is stuck in 600 and 500. So in every loop, the program adds 100 ms to the duration time and then decreases it again by 100, even when I do nothing to the buttons.
Here's my code so far:
const int led = 7;
const int buttonUp = 6;
const int buttonDown = 5;
int duration = 500;
void setup(){
pinMode(led, OUTPUT);
pinMode(buttonUp, INPUT);
pinMode(buttonDown, INPUT);
Serial.begin(9600);
}
void loop(){
int inc = digitalRead(buttonUp);
int dec = digitalRead(buttonDown);
if(inc == HIGH){
duration += 100;
Serial.println(duration);
}
if(dec == HIGH){
duration -= 100;
if(duration < 0){
duration = 100;
}
Serial.println(duration);
}
digitalWrite(led, HIGH);
delay(duration);
digitalWrite(led, LOW);
delay(duration);
}
the code and circuit
serial monitor
Will be extremely grateful if anyone can point out any mistakes!! Thank you!
duration is 500ms. So you basically poll your button states once every second. The time window where you can detect a button click is very short compared to the time you cannot detect it. So chances that you register a click are very little. You need to push the button for at least a second to capture the signal every time.
If you push both buttons you add and subtract 100. That's a total change of 0. What do you expect?
This can be avoided by checking your button state more frequently or by using interrupts.
Find out how to use non-blocking delays and interrupts. The internet is full of tutorials.
bool blink(unsigned int duration) {
// demo code only
// (usable only once per sketch, due to static variables)
static unsigned long last;
static bool state;
if (millis() - last >= duration) {
last = millis();
state = ! state;
}
return state;
}
This is the BlinkWithoutDelay pattern. Usage:
digitalWrite(led,blink(duration));
Button handling is trickier than a beginner thinks: often you want to detect a state change between pressed and released, and you want to ignore the bouncing of a mechanical switch happening during a state change. Or you want to repeat some action, when the button is pressed for a long time.
Easiest you do a little delay(10); after detecting a state change to pass the bouncing time. Or look for libraries doing all that button handling.
Or do such a lazy delay anyway, to slow down your fast microcontroller below button bouncing speed.
const int led = 7;
const int buttonUp = 6;
const int buttonDown = 5;
void setup(){
pinMode(led, OUTPUT);
pinMode(buttonUp, INPUT);
pinMode(buttonDown, INPUT);
Serial.begin(9600);
}
unsigned int duration = 500;
int lastbutton = 0; // 0 / -100 / +100 to detect button changes
void loop(){
bool inc = digitalRead(buttonUp);
bool dec = digitalRead(buttonDown);
delay(5); // debounce
if( (inc || dec) && lastbutton == 0){
lastbutton = (inc - dec) * 100;
duration += lastbutton;
if (duration == 0) duration = 100; // Minimum
Serial.println(duration);
}
if (lastbutton != 0 && !inc && !dec) lastbutton = 0;
digitalWrite(led, blink(duration) );
}

AC dimmer Code bulb does not glow before blinking

I Am having problems in my code... i am using a ac dimmer module with arduino and i want to make the light glow for 5sec and then blink twice then repeat
int AC_LOAD = 3; // Output to Opto Triac pin
int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF
void setup()
{
pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
attachInterrupt(0, zero_crosss_int, RISING); // Choose the zero cross interrupt # from the table above
}
//the interrupt function must take no parameters and return nothing
void zero_crosss_int() //function to be fired at the zero crossing to dim the light
{
// Firing angle calculation : 1 full 50Hz wave =1/50=20ms
// Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle)
// For 60Hz => 8.33ms (10.000/120)
// 10ms=10000us
// (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65
int dimtime = (75*dimming); // For 60Hz =>65
delayMicroseconds(dimtime); // Wait till firing the TRIAC
digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC
delayMicroseconds(10); // triac On propogation delay
// (for 60Hz use 8.33) Some Triacs need a longer period
digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}
void loop()
{
{
int e = 5;
dimming = e;
delay(200);
}
{
for (int i=128; i >= 5; i--){
dimming=i;
delay(2);
}
for (int j=5; j <= 128; j++){
dimming=j;
delay(2); // this value is the light delay timing
}
//delay(3); // this value is the gap timing
for (int i=128; i >= 5; i--){
dimming=i;
delay(2);
}
for (int j=5; j <= 128; j++){
dimming=j;
delay(2); // this value is the light delay timing
}
//delay(3); // this value is the gap timing
}}
when i use this code the light doesnt glow for 5 sec and then blink . it gets a 5 sec delay and then blinks
{
int e = 5;
dimming = e;
delay(200);
}
but if i use only this part of the code with the codes below it. it glows
i am really new to programming please help me out
The 5 second delay you're observing is the boot time of the Arduino. Arduinos bootloader will wait for new firmeware befor your sketch is executed.
If you want to have your light on for 5 seconds, replace delay(200); by delay(5000);.

Arduino LED control sleep

I want to implement a simple LED controller with an Arduino Uno, that goes to sleep and has different buttons.
Functions of buttons are:
Digital 2: Button for ON OFF
Digital 3: Button for Wake up
Everything works ok, but when it goes to sleep, the LEDs also turn off. I want that after 30 seconds, when Arduino goes to sleep, lights stays on.
Here is my code:
#include <avr/sleep.h>
#define REDPIN 10
#define GREENPIN 11
#define BLUEPIN 9
#define delayTime 20 //za fading cas
unsigned long interval= 30000;
unsigned long previousMillis = 0;
const int ledPin = 12; // the pin that the LED is attached to
const int buttonPin1 = 2; //on off
bool vklop = false;
int bela = 10;
int barva;
int prejsnja_barva = 0;
int buttonPushCounter1 = 0; // counter for the number of button presses
int buttonState1 = 0; // current state of the button
int lastButtonState1 = 0; // previous state of the button
/////////////////////////////////////*SETUP*/////////////////////////////////////////
void setup()
{
pinMode(buttonPin1, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
pinMode(3,INPUT); //because of interrupts PIN digital 3
digitalWrite(3,HIGH);
}
/////////////////////////////////////*LOOP*/////////////////////////////////////////
void loop()
{
unsigned long currentMillis = millis();
if ((currentMillis-previousMillis) > interval) //15s timer
{
previousMillis = currentMillis;
Serial.println("SLEEP!"); // kaj delaj po preteku 5s
delay(50);
sleepSetup(); //sleep mode
}
else
{
buttonState1 = digitalRead(buttonPin1);
/////////////////////////////////////ON/OFF/////////////////////////////////////////
/////////////////////////////////////ON/OFF/////////////////////////////////////////
if (buttonState1 != lastButtonState1) // compare the buttonState to its previous state
{
if (buttonState1 == HIGH) // if the state has changed, increment the counter
{
buttonPushCounter1++; // if the current state is HIGH then the button went from off to on:
Serial.println("on");
Serial.print("number of BUTTON1 pushes: ");
Serial.println(buttonPushCounter1);
digitalWrite(ledPin, HIGH);
if(buttonPushCounter1 % 2 == 0)
{
setColor(bela, bela, bela);
vklop = true;
barva = 13;
}
else
{
setColor(0, 0, 0);
vklop = false;
}
}
else // if the current state is LOW then the button went from on to off:
{
Serial.println("off");
digitalWrite(ledPin, LOW);
}
delay(50); // Delay a little bit to avoid bouncing
}
lastButtonState1 = buttonState1; // save the current state as the last state, for next time through the loop
}
}
/////////////////////////////////functions/////////////////////////////////////////////
/////////////////////////////////functions/////////////////////////////////////////////
/////////////////////////////////functions/////////////////////////////////////////////
void setColor(int red, int green, int blue)
{
analogWrite(REDPIN, red);
analogWrite(GREENPIN, green);
analogWrite(BLUEPIN, blue);
}
void sleepSetup(void)
{
sleep_enable(); // Set sleep enable (SE) bit:
attachInterrupt(1, pinInterrupt, LOW); // Set pin 2 as interrupt and attach handler:
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // define our preferred sleep mode:
digitalWrite(13,LOW);
sleep_cpu();
Serial.println("Just woke up!"); //OD TU SE NADALJUJE PO PRITISKU TIPKE
digitalWrite(13,HIGH);
}
void pinInterrupt() //ISR
{
sleep_disable();
detachInterrupt(0);
}
You're using AVR's Power Down sleep mode. In this mode all timers are turned off to save power.
No timers -> no PWM -> no analogue output -> no PWM driven LEDs
To keep the LED on use another sleep mode.
See
http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf for details.
But to be honest I am not quite sure if this makes any sense. If you're driving an LED through 3 outputs the power you can save by putting the MCU into sleep is maybe a few percent.
And as sleep stops the CPU and hence your program you won't be able to have the LEDs turn off after 30s.
Why not just wait 30s befor going to sleep? The alternative would be some external timing circuitry that would also consume power. So I guess having a few milliamps more for 30 seconds is still a better alternative.

Motion controlled light

I'm trying to create an motion controlled light that doesn't turn on unless it's dark.
I want the light to turn on and off slowly with pwm when motion is detected. Right now my code works and does almost everything I want it to.
The problem is that I'm using the delay function to keep the light on after it reaches full brightness. And because of this if motion is detected while the light is on it doesn't reset the timer. Once the delay timer runs out and motion is detected the brightness will go down and then back up.
I would like to have the motion detector reset the timer that keeps the led on but haven't been able to get it working.
I have looked at these:
http://playground.arduino.cc/Code/AvoidDelay
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
But because of my somewhat limited understanding of arduino code I haven't been able to get it working. I would really appreciate any help.
SOLVED
The working code below:
const byte MotionPin = 4; // Motionsensor
int LightSensorPin = 2; // Lightsensor
const byte LedPin = 11; // LED
unsigned long MotionDetectedMillis; // When motion was detected
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 50; // wait to turn on LED
unsigned long turnOffDelay = 5000; // turn off LED after this time
bool ledReady = false; // Has motion been detected
bool ledState = false; // Led on or off
int LightSensorState = 0;
int fadeAmount = 5; // How much to fade in a loop
byte brightness = 0;
void setup() {
pinMode(MotionPin, INPUT);
pinMode(LightSensorPin, INPUT);
pinMode(LedPin, OUTPUT);
digitalWrite(LedPin, LOW);
}
void loop() {
// get the time at the start of this loop()
unsigned long currentMillis = millis();
if (digitalRead(MotionPin) == HIGH && digitalRead(LightSensorPin)== HIGH)
{
MotionDetectedMillis = millis();
ledReady = true;
}
if (ledReady)
{
if ((unsigned long)(currentMillis - MotionDetectedMillis) >= turnOnDelay)
{
while (brightness < 255)
{
brightness = brightness + fadeAmount;
analogWrite(LedPin, brightness);
delay(30);
}
// setup our next "state"
ledState = true;
// save when the LED turned on
ledTurnedOnAt = currentMillis;
ledReady = false;
}
}
// see if we are watching for the time to turn off LED
if (ledState)
{
if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay)
{
while (brightness >0)
{
brightness = brightness - fadeAmount;
analogWrite(LedPin, brightness);
delay(30);
}
ledState = false;
}
}
}
what you want is a state machine; you have to keep track in the loop of which state you currently are and what is the condition to trigger next state; because your loop will execute an action only if something happen to trigger a new state, instead of using delay() you will use a 'waiting for timeout' state (remember to keep a way to know what is the next state).
If this confuses you, imagine each state as step in the instruction manual;
turn on led 1, wait x, turn on led 1 a bit more, wait y, etc..
And because you have no more delay, before or after manage the "normal flow" of the state, you can add some special case like "if input 2 is high and current state is X or Y then set current state to Z".
So, what you want could be easily archived with an interrupt, but with a simple project like this one, you can get the same result just by removing the delay(OnTime) function.
If you want more on the interrupts of the atmega328 which is the one the Arduino UNO uses, go here

Arduino Button with LED

I have put together an Arduino circuit that turns the led's off when the button is pressed. How do I code it so when I press it once it comes on and stays on and will only turn off once its pressed again? Any help would be appreciated
My Current code is:
int ledred = 12;
int ledgreen = 8;
int BUTTON = 4;
int speakerPin = 1;
void setup() {
// initialize the digital pin as an output.
Serial.begin(9600);
pinMode(ledgreen, OUTPUT);
pinMode(ledred, OUTPUT);
pinMode(BUTTON,INPUT);
}
void loop() {
if(digitalRead(BUTTON) == HIGH){
digitalWrite(ledred,HIGH);
digitalWrite(ledgreen,HIGH);
}else
{
digitalWrite(ledred,LOW);
digitalWrite(ledgreen,LOW);
}
}
If all you want is do this, you can use one of the interrupt pins and watch for the RISING (or FALLING) event.
Something similar to this example:
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
Mind that you may still need some debouncing strategy.
Also, you don't need to use an interrupt for that, but then you'd need some edge-detection algorithm. These are quite well explained in the debouncing article above. I personally prefer these, since interrupt pins in the UNO board are precious enough not to be used with humble button pressings... :o)
/*
Debounce
Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
minimum delay between toggles to debounce the circuit (i.e. to ignore noise).
The circuit:
- LED attached from pin 13 to ground
- pushbutton attached from pin 2 to +5V
- 10 kilohm resistor attached from pin 2 to ground
- Note: On most Arduino boards, there is already an LED on the board connected
to pin 13, so you don't need any extra components for this example.
created 21 Nov 2006
by David A. Mellis
modified 30 Aug 2011
by Limor Fried
modified 28 Dec 2012
by Mike Walters
modified 30 Aug 2016
by Arturo Guadalupi
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Debounce
*/
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = HIGH; // the current state of the output pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
}
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// set the LED:
digitalWrite(ledPin, ledState);
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastButtonState = reading;
}

Resources