// www.mekanizmalar.com
// 2019/03/29
const int ledRed = 9;
const int ledGreen = 10;
void setup() {
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
}
void loop() {
digitalWrite(ledRed,HIGH);
highLow(ledGreen);
digitalWrite(ledRed,LOW);
highLow(ledGreen);
}
void highLow(int led) {
digitalWrite(ledGreen,HIGH);
delay(250);
digitalWrite(ledGreen,LOW);
delay(250);
digitalWrite(ledGreen,HIGH);
delay(250);
digitalWrite(ledGreen,LOW);
delay(250);
}
We can write the previous program by using one millisecond delay time. The advantage of this program is that there
should be no relationship between light frequencies. Also, there is no need that the on and off times of the LEDs
to be equal. The disadvantage of this program is that it is hard to maintain.
// www.mekanizmalar.com
// 2019/03/29
const int ledRed = 9;
const int ledGreen = 10;
void setup() {
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
}
int countRed = 1;
int countGreen = 1;
void loop() {
// Red will be on 1000 milis and off 1000 milis
if (countRed <= 1000) {
digitalWrite(ledRed, HIGH);
} else if ( countRed <= 2000) {
digitalWrite(ledRed, LOW);
} else {
countRed = 0;
}
// Green will be on 250 milis and off 250 milis
if (countGreen <= 250) {
digitalWrite(ledGreen, HIGH);
} else if ( countGreen <= 500) {
digitalWrite(ledGreen, LOW);
} else {
countGreen = 0;
}
countRed++;
countGreen++;
delay(1);
}
The maintenance of the previous program can be reduced by defining randomBlink function.
// www.mekanizmalar.com
// 2019/03/29
const int ledRed = 9;
const int ledGreen = 10;
void setup() {
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
}
int countRed = 1;
int countGreen = 1;
void loop() {
// Red will be on 1000 ms and off 1000 ms
countRed = randomBlink(ledRed, countRed, 1000, 1000);
// Green will be on 250 ms and off 250 ms
countGreen = randomBlink(ledGreen, countGreen, 250, 250);
delay(1);
}
int randomBlink(int led, int count, int onTime, int offTime) {
if (count <= onTime) {
digitalWrite(led, HIGH);
} else if ( count <= onTime + offTime) {
digitalWrite(led, LOW);
} else {
count = 0;
}
return ++count;
}
We can further reduce the complexity of the program by putting randomBlink function into a class file.
We call this class FlasherWithDelay.
// www.mekanizmalar.com
// 2019/03/29
class FlasherWithDelay
{
// Class Member Variables
// These are initialized at startup
byte ledPin; // the pin number of the LED pin
int OnTime; // milliseconds on time
int OffTime; // milliseconds off time
int timeCount;
// These maintain the current state
int ledState; // ledState used to set the LED
public:
// Constructor - creates a Flasher
// and initializes the member variables and state
FlasherWithDelay(byte pin, int on, int off)
{
ledPin = pin;
timeCount = 0;
OnTime = on;
OffTime = off;
ledState = HIGH;
}
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
if (timeCount <= (OnTime + OffTime))
{
ledState = (timeCount <= OnTime) ? HIGH : LOW;
digitalWrite(ledPin, ledState);//Update the actual LED
++timeCount;
delay(1);
} else {
timeCount = 0; // reset the timer
}
}
};
const int ledRed = 9;
const int ledGreen = 10;
FlasherWithDelay redLed(ledRed, 337, 889);
FlasherWithDelay greenLed(ledGreen, 231, 421);
void setup() {
redLed.setup();
greenLed.setup();
}
void loop()
{
redLed.loop();
greenLed.loop();
}
Below is a program which uses millis() function, which eliminates delay function from the blinking
programs completly. By using this class, we wrote an Arduino program which blinks five LEDs randomly.
// Original Flasher Code by Bill Earl
// https://learn.adafruit.com/multi-tasking-the-arduino-part-1/a-classy-solution
// www.mekanizmalar.com
// 2019/03/29
class Flasher
{
// Class Member Variables
// These are initialized at startup
int ledPin; // the number of the LED pin
long OnTime; // milliseconds of on-time
long OffTime; // milliseconds of off-time
// These maintain the current state
int ledState; // ledState used to set the LED
// will store last time LED was updated
unsigned long previousMs;
// will store last time LED was updated
unsigned long currentMs;
// Constructor - creates a Flasher
// and initializes the member variables and state
public:
Flasher(int pin, long on, long off)
{
ledPin = pin;
//pinMode(ledPin, OUTPUT);
OnTime = on;
OffTime = off;
ledState = HIGH;
previousMs = 0;
}
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop()
{
//check to see if it's time to change the state of the LED
currentMs = millis();
if (currentMs - previousMs <= (OnTime + OffTime))
{
if (currentMs - previousMs >= OnTime)
{
ledState = LOW; // Turn it off
}
else
{
ledState = HIGH; // turn it on
}
digitalWrite(ledPin, ledState);// Update the actual LED
} else {
previousMs = currentMs; // Remember the time
}
}
};
const int led1 = 8;
const int led2 = 9;
const int led3 = 10;
const int led4 = 11;
const int led5 = 12;
/*
Flasher flasher1(led1, 20, 20);
Flasher flasher2(led2, 40, 40);
Flasher flasher3(led3, 80, 80);
Flasher flasher4(led4, 160, 160);
Flasher flasher5(led5, 320, 320);
*/
/*
Flasher flasher1(led1, 200, 1000);
Flasher flasher2(led2, 400, 800);
Flasher flasher3(led3, 600, 600);
Flasher flasher4(led4, 800, 400);
Flasher flasher5(led5, 1000, 200);
*/
Flasher flasher1(led1, 983, 732);
Flasher flasher2(led2, 663, 721);
Flasher flasher3(led3, 567, 817);
Flasher flasher4(led4, 331, 621);
Flasher flasher5(led5, 783, 593);
void setup() {
flasher1.setup();
flasher2.setup();
flasher3.setup();
flasher4.setup();
flasher5.setup();
}
void loop()
{
flasher1.loop();
flasher2.loop();
flasher3.loop();
flasher4.loop();
flasher5.loop();
}
By using Arrays inside the class, we can reduce the code complexity of a user code further as shown below.
// www.mekanizmalar.com
// 2019/04/04
class Flasher
{
// Class Member Variables
// These are initialized at startup
// milliseconds of on-time
long onT[11];
// milliseconds of off-time
long offT[11];
// current miliseconds for each LED
unsigned long currentMs[11];
unsigned long previousMs[11];
// the number of the LED pin
int ledPins[11];
// current state of LEDs
int ledState[11];
public:
int _length;
Flasher(int pins[], int lengt)
{
_length = lengt;
for (int i = 0; i < _length; i++) {
ledPins[i] = pins[i];
previousMs[i] = 0;
}
}
void setup(long onAndOff[][2]) {
for (int i = 0; i < _length; i++)
{
pinMode(ledPins[i], OUTPUT);
onT[i] = onAndOff[i][0];
offT[i] = onAndOff[i][1];
}
}
void loop()
{
// check to see if it's time
// to change the state of the LED
for (int i = 0; i < _length; i++) {
currentMs[i] = millis();
if (currentMs[i] - previousMs[i] <= (onT[i] + offT[i]))
{
if (currentMs[i] - previousMs[i] >= onT[i])
{
ledState[i] = 0; // Turn it off
}
else
{
ledState[i] = 1; // turn it on
}
// Update the actual LED
digitalWrite(ledPins[i], ledState[i]);
} else {
// Remember the time
previousMs[i] = currentMs[i];
}
}
}
};
int ledPins[5] = {8, 9, 10, 11, 12};
Flasher flasher(ledPins, 5);
void setup() {
//long onOffTimes[5][2] = {{20,20},{40,40},{80,80},{160,160},{320,320}};
//long onOffTimes[5][2] = {{200,1000},{400,800},{600,600},{800,400},{1000,200}};
//long onOffTimes[5][2] = {{983,732},{663,721},{567,817},{331,621},{783,593}};
long onOffTimes[5][2] = {{33,33},{63,63},{93,93},{123,123},{153,153}};
flasher.setup(onOffTimes);
}
void loop()
{
flasher.loop();
}