Hi everyone, I’ve been looking all over the net to get any information about my project but didn’t find much info about millis without making a led flashing..
I want to have a 8 sec timed output that run only one time when I flip a switch. If I turn on the switch, I want a output to be HIGH for 8 sec then goes off even if the switch is still on. If the switch is turned off at any time, I want the output to be LOW at anytime.
I have two other blinking leds using millis and I don’t want to use DELAY to make my leds stop blinking! Can someone help me please?
I want a output to be HIGH for 8 sec then goes off even if the switch is still on
Let's say that, when you read the switch in its normal position, it reads HIGH. What you want to detect is when it goes LOW, not that it is LOW. The state change detection example can show you how you can achieve something like that.
You also need to use a variable to remember that this action has been done.
If the switch is turned off at any time, I want the output to be LOW at anytime.
You need to clarify this specification. Is that even when the 8s is in progress or should the 8s be completed anyway?
Here's some code that compiles for a 2560 that should point you in the right direction.
I've tried to comment effusively. I made an assumption that when you said you need the timed output to "run only one time when I flip a switch" that you meant it. It's easy to change the code to work otherwise if you need (see instances of EVENT_FLAG.)
Note: I didn't try to run it so it very well may have bugs and errors that prevent proper operation. YMMV.
#define OUTPUT_PIN 8 //whatever pin your output is
#define SW_INPUT 9 //whatever pin your switch is tied to
#define LED_PIN 10 //your LED pin
#define LED_TIME 250 //LED toggle rate of 250mS
//bit flags
#define LED_FLAG 0x01 //bit 0 of flags
#define SW_FLAG 0x02 //bit 1
#define OUT_FLAG 0x04 //bit 2
//#define 0x08
//#define 0x10
//#define 0x20
//#define 0x40
#define EVENT_FLAG 0x80 //bit 7 only allow one 8-sec event
#define OUTPUT_TIME_DELAY ((unsigned long)8000) //8000mS == 8-sec
#define SW_READ_INTERVAL 20 //20mS intervals between sw reads
unsigned long
SwitchReadTimer,
OutputTimer,
LEDTimer;
uint8_t
state,
flags;
int
last_switch;
//prototypes
void ProcessOutput( void );
void CheckLED( void );
void ProcessSwitch( void );
void setup()
{
// put your setup code here, to run once:
pinMode( LED_PIN, OUTPUT );
pinMode( OUTPUT_PIN, OUTPUT );
pinMode( SW_INPUT, INPUT );
digitalWrite( LED_PIN, LOW );
digitalWrite( OUTPUT_PIN, LOW );
flags = 0x00;
LEDTimer = millis();
SwitchReadTimer = millis();
//read switch to establish initial reading
last_switch = digitalRead( SW_INPUT );
}//setup
void loop()
{
CheckLED();
ProcessSwitch();
ProcessOutput();
}//loop
void CheckLED( void )
{
unsigned long
timenow;
timenow = millis();
if( (timenow - LEDTimer) > LED_TIME )
{
flags ^= LED_FLAG; //toggle LED state
LEDTimer = timenow; //get time now for next toggle
//set LED output
digitalWrite( LED_PIN, (flags & LED_FLAG) ? HIGH:LOW );
}//if
}//CheckLED
void ProcessSwitch( void )
{
int
switch_now;
//read switch every 20mS (SW_READ_INTERVAL)
if( (millis() - SwitchReadTimer) < SW_READ_INTERVAL )
return;
//reset switch read timer
SwitchReadTimer = millis();
//read the switch input
switch_now = digitalRead( SW_INPUT );
//look for a change in switch state from the last read
if( switch_now != last_switch )
{
//what happened?
if( switch_now == HIGH )
{
//switch transitioned from low to high (assume this is the switch opening)
flags &= ~OUT_FLAG; //force off timed output flag
flags &= ~SW_FLAG; //indicate switch is open
}
else
{
//switch transitioned high to low (assume this is the switch closing)
flags |= SW_FLAG; //indicate switch is closed
//only process this change once "... that run only one time when I flip a switch..."
if( !(flags & EVENT_FLAG) )
{
OutputTimer = millis(); //get time now so we can turn it off in OUTPUT_TIME_DELAY mS
//set output flag to turn timed output on
//set event flag so we only do this once
flags |= ( OUT_FLAG | EVENT_FLAG );
}//if
}//else
//log the state of the switch this pass through
last_switch = switch_now;
}//if switch has changed state
}//ProcessSwitch
void ProcessOutput( void )
{
//if timed output is active, check the time
if( flags & OUT_FLAG )
{
if( (millis() - OutputTimer) >= OUTPUT_TIME_DELAY )
flags &= ~OUT_FLAG;
}//if
//switch has to be CLOSED and time delay timer has to be live
//for output to be on
//this assumes "on" == HIGH
digitalWrite( OUTPUT_PIN, ( (flags & SW_FLAG) && (flags & OUT_FLAG) ) ? HIGH:LOW );
}//ProcessOutput