How to Make Standard function for Leds ON and OFF

'byte led1=13;
byte led2=6;

void setup(){
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led1, HIGH);
pinMode(led2, HIGH);
Serial.begin(9600);
}

void loop(){
LedOnOff(led2, 500, 1000);
LedOnOff(led1, 1000, 1000);

}
void LedOnOff(byte ledpin,unsigned long OnDuration, unsigned long OffDuration){
bool ledState=HIGH;
unsigned long CurrentTime1=0;
// unsigned long CurrentTime2=0;
while (1) {
if(ledState==HIGH){
if((millis()-CurrentTime1)>=OnDuration){
ledState=LOW;
CurrentTime1=millis();

  }

}else{
if((millis()-CurrentTime1)>=OffDuration){
ledState=HIGH;
CurrentTime1=millis();
}
Serial.println("LED OFF");
}
digitalWrite(ledpin, ledState);

}
}'

How can i make function like that, i think it should work but only one Led blinks at a time, please guide me how can i do like that.

Welcome to the forum

Your topic was MOVED to its current forum category which is more appropriate than the original as it has nothing to do with Installation and Troubleshooting of the IDE

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

1 Like

I am having a hard time reading the code, please post properly. Explain what it is to do and what it is doing.

The reason only one LED at a time blinks is that you have invented a complicated delay in your while loop. This will halt everything until it is done.
[edit]
Sorry it is worse than that - the loop is infinite so the function never returns.

@saleemjee maybe you have done programming where something like that would actually work as one might imagine you hope.

What kind of Arduino are you using?

What other computers or boards have you written programs for?

What kind of programs?

a7

actually i am doing multitasks using millis() function in void loop() , i thought why don't i make a function for any led to blink so I made it, but program does not work. if I write the code like below it works fine. Two leds blinking in their own time and not effecting each other by time.

const int LED1pin = 13;
unsigned int LED1onDuration = 1000;// OFF time for LED
unsigned int LED1offDuration = 1000;// ON time for LED
const int LED2pin = 6;
unsigned int LED2onDuration = 500;// OFF time for LED
unsigned int LED2offDuration = 500;// ON time for LED

bool LED1State =HIGH;// initial state of LED
bool LED2State =HIGH;// initial state of LED

long rememberTime1=0;
long rememberTime2=0;// this is used by the code

void setup() {
pinMode(LED1pin,OUTPUT);// define LEDpin as output
// digitalWrite(LED1pin,LED1State);// set initial state
pinMode(LED2pin,OUTPUT);// define LEDpin as output
// digitalWrite(LED2pin,LED2State);// set initial state
}

void loop() {
// Robojax LED blink with millis()

if( LED1State ==HIGH )
{
if( (millis()- rememberTime1) >= LED1onDuration){
LED1State = LOW;// change the state of LED
rememberTime1=millis();// remember Current millis() time
}
}
else
{
if( (millis()- rememberTime1) >= LED1offDuration){
LED1State =HIGH;// change the state of LED
rememberTime1=millis();// remember Current millis() time
}
}

// Robojax LED blink with millis()
digitalWrite(LED1pin,LED1State);// turn the LED ON or OFF

if( LED2State ==HIGH )
{
if( (millis()- rememberTime2) >= LED2onDuration){
LED2State = LOW;// change the state of LED
rememberTime2=millis();// remember Current millis() time
}
}
else
{
if( (millis()- rememberTime2) >= LED2offDuration){
LED2State =HIGH;// change the state of LED
rememberTime2=millis();// remember Current millis() time
}
}

// Robojax LED blink with millis()
digitalWrite(LED2pin,LED2State);// turn the LED ON or OFF

}// loop ends

I am using arduino Nano and basically a beginner and I have a task in my mind by using millis() function, is to make a function that blinks in their own time but not effecting each other.

Please read post#2 and edit your message, inserting the code to the code tags.

Your question is unlikely to interest anyone if you disrespect the rules

Click edit :pencil2: down here :point_down: then highlight your code and click the code tag button <|> up here :point_up_2:

Slow down, read replies and read the forum guidelines

Your function uses a while loop and therefore can do nothing else while in that loop!

You can use or refer to source code of this LED library
It has all functions you need

Because your "LED Blinking Function" used one copy of "rememberTime" for both LEDs. You can fix that by passing a separate static "rememberTime" to each function:

const byte led1Pin = 13;
const byte led2Pin = 6;
unsigned long rememberTime1 = 0;
unsigned long rememberTime2 = 0;

void setup()
{
  Serial.begin(9600);

  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led1Pin, HIGH);
  pinMode(led2Pin, HIGH);
}

void loop()
{
  LedOnOff(led2Pin, 500, 1000, rememberTime2);
  LedOnOff(led1Pin, 1000, 1000, rememberTime1);
}

void LedOnOff(byte ledpin, unsigned long OnDuration, unsigned long OffDuration, unsigned long &rememberTime)
{
  bool ledState = digitalRead(ledpin);
  unsigned long CurrentTime = millis();

  if (ledState == HIGH)
  {
    if (CurrentTime - rememberTime >= OnDuration)
    {
      ledState = LOW;
      Serial.println("LED OFF");
      digitalWrite(ledpin, ledState);
      rememberTime = CurrentTime;
    }
  }
  else // ledState == LOW
  {
    if (CurrentTime - rememberTime >= OffDuration)
    {
      ledState = HIGH;
      Serial.println("LED ON");
      digitalWrite(ledpin, ledState);
      rememberTime = CurrentTime;
    }
  }
}

A while back I wrote a tutorial for writing a library to blink an LED, sort of like your "LedOnOff()" function but with several functions. This part explains why you will want to write an object class instead of one function:

All-together you have:
Main Sketch:

#include "BlinkLib.h"

void setup()
{
  setPin(LED_BUILTIN);
}

void loop()
{
  blink(1000);
}

Library header:

void blink(unsigned long);
void setPin(int);

Library source:

#include <Arduino.h>
#include "BlinkLib.h"

int ledState = LOW;
unsigned long previousMillis = 0;
int ledPin =  LED_BUILTIN;

void setPin(int pin)
{
  ledPin = pin;
  pinMode(ledPin, OUTPUT);
}

void blink(unsigned long interval)
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Ah, but there is one small problem. Now you want to blink multiple LEDs at different rates! There is only one global "ledPin" variable so if you call "setPin()" a second time, the first pin number is replaced by the second pin number, and blink() will only blink the second pin. Also, the "ledState" and "previousMillis" globals are shared among the functions.

To fix that, we are going to 'encapsulate' the functionality of the library into an 'object'. You can then make multiple 'instances' of the object, each with its own variables.

Let's create an object class named 'Blinker'. This goes into BlinkLib.h in place of the shared function prototypes.

class Blinker
{
  public:
    Blinker(const byte pin);  // "Constructor" called when the object is defined
    
    void blink(const unsigned long interval);

  private:
    const byte ledPin;
    int ledState;
    unsigned long previousMillis;
};

Now we can change the test sketch to blink two LEDs:

#include "BlinkLib.h"

Blinker blinker(LED_BUILTIN);  // Blink the built-in LED
Blinker blinker2(9);  // Blink the LED on Pin 9

void setup()
{
}

void loop()
{
  blinker.blink(1000);
  blinker2.blink(750);
}

We can try to Verify the test sketch but we have not defined the functions ("member functions" or "methods") declared in the class yet. We get undefined reference errors for Blinker::Blinker() (the constructor) and Blinker::blink() (the function that does stuff!). The second one is easy to fix because we just have to change the declaration of 'blink' from:
void blink(unsigned long interval)
to
void Blinker::blink(unsigned long interval)
That tells the compiler that we are not defining just a function, but a function that is a member ("member function" or "method") of the object class "Blinker". Nothing else about 'blink()' has to be changed because the blink() "method" is perfectly happy to use the "member variables" of its class in place of the old globals. We can remove the globals and the setPin() function from BlinkLib.cpp because they are no longer used:

#include <Arduino.h>
#include "BlinkLib.h"

void Blinker::blink(unsigned long interval)
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Now that "Blinker::blink()" is taken care of, we need to define Blinker::Blinker(). This is the "constructor": the function automatically called when an object of this class (an "instance") is created ("instantiated"). It is a good place to do some initialization. We can put this function in BlinkLib.cpp:

Blinker::Blinker(const byte pin)
{
  ledPin = pin;
  ledState = LOW; 
  previousMillis = 0;
  
  pinMode(ledPin, OUTPUT);
  previousMillis = millis();
}

The only problem is, "ledPin" is declared with the keyword 'const' so it can't be assigned a value inside the constructor. It has to be given a value BEFORE the body of the constructor so we have to use some special syntax:

Blinker::Blinker(const byte pin) : ledPin(pin)
{
  ledState = LOW; 
  previousMillis = 0;
  
  pinMode(ledPin, OUTPUT);
  previousMillis = millis();
}

Yay! The sketch compiles without any errors or warnings!

Except for one thing. A thing the compiler can't warn you about because it doesn't know. The Arduino library isn't initialized until just before your setup() function is called. That is AFTER all of the global variables are initialized. That includes calling the constructor of every global object instance. In other words, your object class can't safely call any Arduino functions (like "pinMode()" or "millis()") in the constructor! You may have wondered why some Arduino library objects have a 'begin()' method that you have to call from setup(). That's why.

To make our object safe to use we add a 'begin()' method (the name is just an Arduino convention) and call the Arduino functions from there.

void Blinker::begin()
{
  pinMode(ledPin, OUTPUT);
  previousMillis = millis();
}

That goes in BlinkLib.cpp and we call it in setup().

We have to add the "void begin();" declaration to the class (in BlinkLib.h) and we're ready to go!

All-together you have:
Main Sketch:

#include "BlinkLib.h"

Blinker blinker(LED_BUILTIN);  // Blink the built-in LED
Blinker blinker2(9);  // Blink the LED on Pin 9

void setup()
{
  blinker.begin();
  blinker2.begin();
}

void loop()
{
  blinker.blink(1000);
  blinker2.blink(750);
}

Library header:

class Blinker
{
  public:
    Blinker(const byte pin);  // "Constructor" called when the object is defined
    void begin(); // A function to call to do initialization

    void blink(const unsigned long interval);

  private:
    const byte ledPin;
    int ledState;
    unsigned long previousMillis;
};

Library source:

#include <Arduino.h>
#include "BlinkLib.h"

Blinker::Blinker(const byte pin) : ledPin(pin)
{
  ledState = LOW;
  previousMillis = 0;
}

void Blinker::begin()
{
  pinMode(ledPin, OUTPUT);
  previousMillis = millis();
}

void Blinker::blink(unsigned long interval)
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

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