I need to create a timing/delay for 2 outputs.
The first output would comes to HIGH at 0 seconds and stays HIGH for 20 seconds, then goes to LOW and remains LOW
The second output is LOW at 0 seconds and goes HIGH at 15 seconds and remains HIGH.
I would like accomplish this with using "millis", however I do not know if it is possible and how to do it.
Any guidance will be appreciated.
Thank You !
Show us your attempts at doing this.
BTW
Always show us a good schematic of your proposed circuit.
Show us a good image of your ‘actual’ wiring.
Great tutorial on how to do what you want: https://www.gammon.com.au/blink
this is programming question, I have no issue with anything schematic /circuit/wiring
so far I started with this....2 leds, and mixing millis and delay
int led2 = 11;
int led1 = 8;
unsigned long delayStart = 0; // the time the delay started
bool delayRunning = false; // true if still waiting for delay to finish
void setup() {
pinMode(led1, OUTPUT); // initialize the digital pin as an output.
pinMode(led2, OUTPUT); // initialize the digital pin as an output.
digitalWrite(led1, 0); // turn led on
digitalWrite(led2, 1); //turn led2 off
delayStart = millis(); // start delay
delayRunning = true; // not finished yet
}
void loop() {
// check if delay has timed out after 20sec == 20000mS
if (delayRunning && ((millis() - delayStart) >= 20000)) {
delayRunning = false; // prevent this code being run more then once
digitalWrite(led1, 1); // turn led off
Serial.println("Turned LED Off");
}
// Other loop code here . . .
delay(5000);
digitalWrite(led2,0);
Serial.println("Run Other Code");
}
Please edit your post to add code tags.
Hint: in the Arduino editor, use CTRL-T to indent the code before copy/paste to the forum. The indenting helps with readability and to catch errors in program structure.
(post deleted by author)
(post deleted by author)
int led2 = 11;
int led1 = 8;
unsigned long delayStart = 0; // the time the delay started
bool delayRunning = false; // true if still waiting for delay to finish
void setup() {
pinMode(led1, OUTPUT); // initialize the digital pin as an output.
pinMode(led2, OUTPUT); // initialize the digital pin as an output.
digitalWrite(led1, 0); // turn led on
digitalWrite(led2, 1); //turn led2 off
delayStart = millis(); // start delay
delayRunning = true; // not finished yet
}
void loop() {
// check if delay has timed out after 20sec == 20000mS
if (delayRunning && ((millis() - delayStart) >= 20000)) {
delayRunning = false; // prevent this code being run more then once
digitalWrite(led1, 1); // turn led off
Serial.println("Turned LED Off");
}
// Other loop code here . . .
delay(5000);
digitalWrite(led2, 0);
Serial.println("Run Other Code");
}
Using delay() defeats the purpose of using millis() for timing.
If you want to solve the problem, please take a look at the tutorial I linked earlier.
Are you really need a delayRunning
flag?
I think you can easily rid of the flag and use similar code for second led.
Well, it does "prevent this code being run more then once"
consider
struct Tmr {
byte pin;
byte startState;
unsigned long msec;
bool done;
};
Tmr tmrs [] = {
{ 8, HIGH, 20000 },
{ 11, LOW, 15000 },
};
#define Ntmr (sizeof(tmrs)/sizeof(Tmr))
unsigned msecLst;
// -----------------------------------------------------------------------------
void loop ()
{
unsigned long msec = millis ();
Tmr *t = tmrs;
for (unsigned n = 0; n < Ntmr; n++, t++) {
if (! t->done && msec - msecLst >= t->msec) {
digitalWrite (t->pin, ! t->startState);
t->done = true;
}
}
}
void setup ()
{
Tmr *t = tmrs;
for (unsigned n = 0; n < Ntmr; n++, t++) {
pinMode (t->pin, OUTPUT);
digitalWrite (t->pin, t->startState);
}
msecLst = millis ();
}
Demo-Code that shows how to execute 3 parts of code at 3 different periods
unsigned long DemoTimerA = 0; // variables that are used to store timeInformation
unsigned long DemoTimerB = 0;
unsigned long DemoTimerC = 0;
unsigned long DoDelayTimer = 0;
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
void setup() {
Serial.begin(115200);
Serial.println("Program started activate Show timestamp in serial monitor");
}
void loop() {
if ( TimePeriodIsOver(DemoTimerA,1000) ){
Serial.println(" TimerA overDue");
}
if ( TimePeriodIsOver(DemoTimerB,2000) ){
Serial.println(" TimerB overDue");
}
if ( TimePeriodIsOver(DemoTimerC,3000) ) {
Serial.println(" TimerC overDue");
}
if ( TimePeriodIsOver(DoDelayTimer,20000) ){
Serial.println("every 20 seconds execute delay(3500)... to make all other timers overdue");
delay(3500);
}
}
taken from this tutorial
shall this be a behaviour that shall happen only once and then never again
or
shall this be a behaviour that will be repeated?
This makes a great difference how to code it.
This is a common question, try this: Flashing 2 or more LEDs at the same time
Hello jenom
Keep it simple and stupid.
Try, check and modify this C++ sketch to you needs.
/* BLOCK COMMENT
- https://forum.arduino.cc/t/using-millis-to-create-2-different-delays-at-the-same-time/1063664
- Using “millis” to create 2 different delays at the same time
- This sketch may contain traces of C++.
- In case of indisposition:
- https://www.learncpp.com/
- Hardware:
- Thanks to LarryD
- https://aws1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
- Tested @ Arduino: Mega[X] - UNO [ ] - Nano [ ]
*/
enum LedColour{Red, Green};
enum TimerControl {Off,On};
constexpr byte LedPins[] {9,10};
struct MYDELAY {
int identifier;
const byte Pin;
const unsigned long Duration;
unsigned long stamp;
int onOffControl;
};
MYDELAY myDelays[] {
{Red,LedPins[Red], 20000, 0, On},
{Green,LedPins[Green], 15000, 0, On},
};
void setup()
{
for (auto myDelay:myDelays) pinMode(myDelay.Pin,OUTPUT);
digitalWrite(myDelays[Red].Pin,HIGH);
}
void loop()
{
unsigned long currentTime=millis();
for (auto &myDelay:myDelays)
{
if (currentTime-myDelay.stamp>=myDelay.Duration && myDelay.onOffControl)
{
switch (myDelay.identifier)
{
case Red:
digitalWrite(myDelay.Pin,LOW);
myDelay.onOffControl=Off;
break;
case Green:
digitalWrite(myDelay.Pin,HIGH);
myDelay.onOffControl=Off;
break;
}
}
}
}
Have a nice day and enjoy coding in C++.
thank you for all the replies and advises
created a short & simple sketch using only "millis" and "if" commands
--led1comes to HIGH at 0 seconds and stays HIGH for 20 seconds, then goes to LOW and remains LOW
--led2 is LOW at 0 seconds and goes HIGH at 15 seconds and remains HIGH.
int led2 = 11;
int led1 = 8;
unsigned long delayStart = 0; // the time the delay started
bool delayRunning = false; // true if still waiting for delay to finish
void setup()
{
pinMode(led1, OUTPUT); // initialize the digital pin as an output.
pinMode(led2, OUTPUT); // initialize the digital pin as an output.
digitalWrite(led1, 0); // turn led1 ON
digitalWrite(led2, 1); //turn led2 OFF
delayStart = millis(); // start delay
delayRunning = true; // not finished yet
}
void loop()
{
if (delayRunning && ((millis() - delayStart) >= 20000)) // delay has timed out after 20 sec
{
digitalWrite(led1, 1); // turn led off
}
if (delayRunning && ((millis() - delayStart) >= 15000)) //delay has timed out after 15 sec
{
digitalWrite(led2, 0); // turn led ON
}
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.