From a simple blinking LEDLight-emitting diode to candle flicker

Variables, Random and analogWrite.

  • Starting at the blink Example
void setup() {
 pinMode(13,OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}

Exercise One

Change the pin for the LEDLight-emitting diode to pin 3 on your breadboard. Adjust the program so it uses the LEDLight-emitting diode on pin 3 instead pin 13:

void setup() {
 pinMode(3,OUTPUT);
}

void loop() {
  digitalWrite(3, HIGH);
  delay(1000);
  digitalWrite(3, LOW);
  delay(1000);
}

Notice: You had to change the number 13 to 3 in the above program 3 times.

Imagine you would have to set this up on different pins very often - this becomes tedious very quickly.

Luckily there is something called "variables" you can use. Variables can do many things for us - but For now we use the variable to remember numbers in a program, so you don't have to do so many replacements when changing the pin number.

If you write the following somewhere in your program, there is now a new variable given the name Otto:

int Otto;

This is a variable given the more useful name LEDpin:

int LEDpin;

We call this procedure defining a variable. For now we write these kinds of variable definition at the beginning of our code - before everything else:

int LEDpin;

void setup() {    
  pinMode(3,OUTPUT);
}

void loop() {
  digitalWrite(3, HIGH);
  delay(1000);
  digitalWrite(3, LOW);
  delay(1000);
}

In the above source we only defined the variable, but until now nothing different from the code you used before happens. The program will just run and let the LEDLight-emitting diode attached to pin 3 blink.

In order to use the variable we have to do 2 things.

  • let the variable remember the number 3
  • let the program use the variable.
int LEDpin;

void setup() {    
  LEDpin = 3;
  pinMode(3,OUTPUT);
}

void loop() {
  digitalWrite(3, HIGH);
  delay(1000);
  digitalWrite(3, LOW);
  delay(1000);
}

Now the variable we called LEDpin "remembers" the number 3 for us - but still it is not useful for us. So let's finally use the variable. Notice the replacements of the number "3" to LEDpin in the below code:

int LEDpin;

void setup() {    
  LEDpin = 3;
  pinMode(LEDpin,OUTPUT);
}

void loop() {
  digitalWrite(LEDpin, HIGH);
  delay(1000);
  digitalWrite(LEDpin, LOW);
  delay(1000);
}

Now let's adjust the speed of the blinking LEDLight-emitting diode. For now the LEDLight-emitting diode blinks with a pattern of one second on, then one second off. Let's change this to 0.1 seconds on and off.

int LEDpin;
LEDpin = 3;

void setup() {    
  pinMode(LEDpin,OUTPUT);
}

void loop() {
  digitalWrite(LEDpin, HIGH);
  delay(100);
  digitalWrite(LEDpin, LOW);
  delay(100);
}

Firstly- the above code contains a small error. In the second line we try to give LEDpin the value "3" - until now we did this always in the setup function. This has a reason which is a bit too complicated to explain now - but there is an elegant method of doing what we wanted without giving an error. See the next block of code for the solution.

If you have to replace the delay time very often, you have to change the same number 2 times. Your Exercise: replace the 100 or 1000 by a variable called delayTime.

solution:

int LEDpin = 3;
int delayTime = 100;

void setup() {    
  pinMode(LEDpin,OUTPUT);
}

void loop() {
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
}

In the above code there's something new - probably you discoverd it looking for the problem with the variable. The variables are defined, but also an equals sign and a number (value) is following them. This is called "initialization": the variable is initially having the value you gave it. If you don't initialize a variable with a number or generally with a value it will be empty - indicated as the value 0 (zero).

It is also possible (and very common) to modify a variable's value more than one time while a program is running. We want now to let the program blink 5 times very short (for 0.05 seconds) when it is started and then we want to let it blink infinitely in a 0.7 seconds rhythm. We can use the setup for the 5 short blinks and the loop for the infinite slow repetitions. However - how to manage the change of the short and long delay time for the differently fast blinking?

int LEDpin = 3;
LEDpin = 13;
int delayTime;
delayTime = 100;

void setup() {    
  pinMode(LEDpin,OUTPUT);
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  
  delayTime = 700;
}

void loop() {
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
}

at the end of the setup - just before the curly bracket (}) the value of delayTime is modified - to 700. Before that it was holding the value 50.


for now we only changed a variable 2 times. But what about creating random patterns of blinking?

int LEDpin = 13;
int delayTime;

void setup() {    
  pinMode(LEDpin,OUTPUT);
}

void loop() {
  delayTime = 1000;
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  delayTime = 200;
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  delayTime = 100;
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  delayTime = 703;
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  delayTime = 200;
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  delayTime = 50;
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
  delayTime = 70;
}

This looks like randomly blinking for a very short time - but soon you will recognize the repetitions.

To let it look really randomly and we do not notice it repeats all the time: we have to write many more lines of delay=... or there's again something built into arduino which makes life easy...

and yes - there is:

instead of writing delayTime = XXX (where XXX is a number from 0 to 999) we can just use the random function:

by writing this:

  delayTime = random(1000);

we give (or in correct language: we assign) a random number from 0 up to 999 to the variable.

if we use the random function several times after another it will give us a different number each time (mostly - sometimes also random numbers repeat!).

int LEDpin = 13;
int delayTime = 100;

void setup() {    
  pinMode(LEDpin,OUTPUT);
}

void loop() {
  delayTime = random(1000);
  digitalWrite(LEDpin, HIGH);
  delay(delayTime);
  digitalWrite(LEDpin, LOW);
  delay(delayTime);
}

Changing the brightness.

Turning an LEDLight-emitting diode off and on doesn't look much like a candle - so we want also have control about its brightness. For this we can use one of the analog outputs of the Arduino. (Pin 3,5,6,9,10,11 are capable of that)

Modifying our program to analog voltage is very easy. The digitalWrite function can only turn a pin on and off - their analog counterfeit is the analogWrite function. Similarly to the digitalWrite function it has 2 arguments: the first is the the same: the pin number you want to use. Fhe second one is different. Instead the words "HIGH" and "LOW" we can now use a number from 0 to 255:

This will turn on pin 3 "on" (comparable to HIGH):

analogWrite(3,255)

This will turn on pin 3 "off" (comparable to LOW):

analogWrite(3,0)

while this turn on pin 3 to 50% of its maximum level - approximately exactly between HIGH and LOW.

analogWrite(3,127)

Adopting this to our previous program gives us:

int LEDpin = 3;
int delayTime;

void setup() {    
  pinMode(LEDpin,OUTPUT);
}

void loop() {
  delayTime = random(1000);
  analogWrite(LEDpin, 255);
  delay(delayTime);
  digitalWrite(LEDpin, 0);
  delay(delayTime);
}

Not turning the LEDLight-emitting diode entirely off might look more like a candle - so we adjust the low brightness value to 80:

int LEDpin = 3;
int delayTime;

void setup() {    
  pinMode(LEDpin,OUTPUT);
}

void loop() {
  delayTime = random(1000);
  analogWrite(LEDpin, 255);
  delay(delayTime);
  digitalWrite(LEDpin, 80);
  delay(delayTime);
}

looking much more candle-like - but still only 2 different brightnesses - we can still do better:

Homework #1:

  • replace the brightness values above (255 and 80) by a variable called brightness
  • Use a random function to generate values for brightness (from 0 to 255)

Homework #2: Now the random function generates brightnesses from 0 255 to let it look more candle-like we want the random start from 80 and go up to 255. Have a look at the Arduino reference for the the random function. Find out how the random can be used to produce values from 80 to 255.