LED must stop blinking after a given duration in seconds

Hi,

I am using a Arduino Mega.
I am trying to write a code that allows me to make a led blink with a certain on-off duration determined by a number entered on the serial monitor (for instance, 10 ms on- 10 ms off) that would automatically stop blinking after a given number of second (for instance after 3 seconds) until it receives a new number on the serial monitor, which would lead to a new blinking (possibly at a new frequency) for 3 seconds and so on..

I was able to write a short program code that allows me to use the serial monitor to determine the on-off duration of the led (see the code below). However, I could not figure out how to stop the loop after 3 seconds and, then, restart a new one when a new number if entered in the serial monitor. I wonder if someone could complete my code to achieve this?

Thanks in advance for your collaboration !

[code]

unsigned long blinkRate = 1000; //Default 1000 milliseconds between blinks

void setup() {
  pinMode(13, OUTPUT); 
  Serial.begin(9600);   
  Serial.println("Enter the blink delay length in milliseconds (try 100)");
}

void loop() {

  
  if (Serial.available() > 0) {
    
    blinkRate = Serial.parseInt();
    Serial.println(blinkRate);
  }

  analogWrite(13, 255);
  delay(blinkRate);
  analogWrite(13, 0);
  delay(blinkRate);
}

[/code]

I could not figure out how to stop the loop after 3 seconds

One way :

Write a function that changes the state of the LED and call it from loop() at the required interval. Only call the function when a boolean is true. Start with the boolean false

Set the boolean to true and save the value of millis() when you want to start the blinking, then each time through loop() test whether the current value of millis() minus the start value is greater than the required period. If so, then set the boolean to false to stop the blinking

Dear UKHeliBob,

I am very grateful for your answer. I am sure this is a great idea, but unfortunately I am not advanced enough to understand what this all means/imply. Would you mind adapting/updating my code directly (I hope this does not violate the rules of the forum) ? I am a psychologist trying to set up an experiment to test people's flicker fusion threshold and I am getting lost with all this. Thanks in advance for your collaboration!

A St Patrick Day present for you

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop()
{
  Serial.println("Enter the blink delay length in milliseconds (try 100)");
  while (Serial.available() == 0);
  int delayTime = Serial.parseInt();
  int numberOfBlinks = 3000 / delayTime;
  Serial.println("blinking");
  for (int blink = 0; blink < numberOfBlinks; blink++)
  {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    delay(delayTime);
  }
}

NOTE : this does not use the method that I first suggested, nor is it the best way way to do it, but it should be easy to understand

Dear UKHeliBob,

Thank you so much for your help ! Your code works almost perfectly and I am relieved to be "almost there".
There are still two minor issues:

(1) I need to led to be turned off at the end of the 3sec period. This is almost always the case with your code, but not always. By trial and error, it seems that when the duration of the delay (entered in the serial monitor) is a multiple of "8" (8, 16, 14, 32...), then, (1) the led stays on after the 3-sec period and (2) it stays on for all the next trials/durations until I close and open again the serial monitor.

(2) In my original code, the use of the "analogWrite" on the pin allowed me to set the intensity of the on and off phase on a scale from 0 to 255, which was very handy. It allowed to test participants' ability to detect flicker at different intensities. I tried to replace the digital to analog in your code but I can't make it work. Any help on this is welcome.

I hope you have an excellent St Patrick Day !
Gilles

In my original code, the use of the "analogWrite" on the pin allowed me to set the intensity of the on and off phase on a scale from 0 to 255,

You will need to change the LED blinking code in the for loop to something like you used so that each for loop step turns it on then off but, you will also need to divide the number of blinks by 2. Make the last digitalWrite() turn the LED off and you will solve the other problem at the same time

Dear UKHeliBob,

It seems that I managed to solve these two minor issues myself, thanks to your guidance and very clear example.
I can now control the on- and off- intensity of the led and make sure that the led turns off at the end of the blinking period. The only thing that I am not 100% sure about is that the blinking duration is exactly 3 sec. Do you confirm that this is the case? Once again thank you !
Gilles

[code]

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  pinMode(10, OUTPUT);
  analogWrite(10, 0);
}

void loop()
{
  Serial.println("Enter the blink delay length in milliseconds (try 100)");
  while (Serial.available() == 0);
  int delayTime = Serial.parseInt();
  int numberOfBlinks = 1500 / delayTime;
  Serial.println("blinking");
  for (int blink = 0; blink < numberOfBlinks; blink++)
  {
  analogWrite(10, 60);
  delay(delayTime);
  analogWrite(10, 30);
  delay(delayTime);
  }
  analogWrite(10, 0);
}

[/code]

const long DURATION = 3000; // in milliseconds
  int numberOfBlinks = DURATION / 2  / delayTime;

Now are you 100% sure?

If you just want it to work, this works. (using libraries)

Type in..

period 500 -- will give you period of 500 ms

pulse 20 -- will give you pulse width of 20 ms

blink -- restart the blinking without numbers changed

time 4000 -- Sets the blinking duration to 4 seconds.

You will need to install from the library manager, LC_baseTools and LC_lilParser to compile this.

#include <lilParser.h>
#include <blinker.h>

enum commands {   noCommand,     // ALWAYS start with noCommand. Or something simlar.
                  periodMS,    // The rest is up to you. help would be a good one. Have it list
                  pulseMS,       // What the other commands are, how they work and what they do.
                  blinkTime,     // Set the time we'll blink for.
                  blink          //
                  
                  };             // Our list of commands.

lilParser   ourParser;        // The parser object.
blinker     ourBlinker(13);
timeObj     blinkTimer(3000);

void setup(void) {

   Serial.begin(9600);
   ourBlinker.setOnOff(false);            // Make sure it's off.
   ourParser.addCmd(periodMS,"period"); // Add periodMS
   ourParser.addCmd(pulseMS,"pulse");     // Add pulseMS command
   ourParser.addCmd(blinkTime,"time");    // Add blink duration time command
   ourParser.addCmd(blink,"blink");       // Add blink command
}


void turnBlinkerOn(void) {

   ourBlinker.setOnOff(true);    // Turn it on.
   blinkTimer.start();           // Start our blink timer.
}


// Your loop where it parses out all your typings.
void loop(void) {

   char  inChar;
   int   command;

   idle();                                                  // Runs background stuff.
   if (Serial.available()) {                                // If serial has some data..
      inChar = Serial.read();                               // Read out a charactor.
      Serial.print(inChar);                                 // If using development machine, echo the charactor.
      command = ourParser.addChar(inChar);                  // Try parsing what we have.
      switch (command) {                                    // Check the results.
         case noCommand : break;                            // Nothing to report, move along.
         case periodMS  : setPeriod();             break;   // Set the period (duration)
         case pulseMS   : setPulse();              break;   // Set the pulse width.
         case blinkTime : setTime();               break;   // Set time duration for blinking.
         case blink     : turnBlinkerOn();         break;   // Just turn on the blinker.
         default        : Serial.println("What?"); break;   // No idea. Try again?
      }
   }
   if (blinkTimer.ding()) {                                 // If the blink timer has expired..
       ourBlinker.setOnOff(false);                          // Turn it off.
       blinkTimer.reset();                                  // Reset our blink timer.
   }
}



/************************************************************************************
*************************************************************************************

                     Now the list of command handlers you call from
                     your main loop() when commands are parsed.   
                                        
*************************************************************************************
*************************************************************************************/



// Grab a number and set period.
void setPeriod(void) {

   char* param;
   int   numMs;
     
   if (ourParser.numParams()) {           // If they typed in somethng past the command.
      param = ourParser.getParamBuff();   // We get the first parameter, assume its the new folder's name.
      numMs = atoi(param);                // Read this as an integer.
      free(param);                        // Dump the parameter buffer ASAP.
      ourBlinker.setPeriod(numMs);        // Set the blinker.
      turnBlinkerOn();                    // Fire ujp the blinkings.
   }
}


// Grab a number and set pulse..
void setPulse(void) {

   char* param;
   int   numMs;
     
   if (ourParser.numParams()) {           // If they typed in somethng past the command.
      param = ourParser.getParamBuff();   // We get the first parameter, assume its the new folder's name.
      numMs = atoi(param);                // Read this as an integer.
      free(param);                        // Dump the parameter buffer ASAP.
      ourBlinker.setPulse(numMs);         // Set the blinker.
      turnBlinkerOn();                    // Fire ujp the blinkings.
   }
}


// Grab a number and set pulse..
void setTime(void) {

   char* param;
   int   numMs;
     
   if (ourParser.numParams()) {           // If they typed in somethng past the command.
      param = ourParser.getParamBuff();   // We get the first parameter, assume its the new folder's name.
      numMs = atoi(param);                // Read this as an integer.
      free(param);                        // Dump the parameter buffer ASAP.
      blinkTimer.setTime(numMs);          // Set the blinker.
      turnBlinkerOn();                    // Fire ujp the blinkings.
   }
}

-jim lee

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.