11.1. SoftBlink1 Arduino Sketch

This sketch is used by Exercise: Soft Blink.

11.1.1. Full Source Code

The full code is all in one file SoftBlink1.ino.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
// SoftBlink1 - fades the onboard LED on and off.
//
// Copyright (c) 2016, Garth Zeglin.  All rights reserved. Licensed under the
// terms of the BSD 3-clause license as included in LICENSE.
//
// The Arduino UNO we use has an onboard LED on pin 13.  This sketch varies the
// visible LED intensity using a form of "pulse width modulation" (PWM)
// implemented in software.  The example turns the LED on and off very fast
// using short delays within a loop; the average energy emitted is lower than
// constantly being ON.
//
// The output voltage signal looks something like this as a function of time:
//
//      ----      ----      ----     ----
//     |    |    |    |    |    |   | 
//  ---      ----      ----      ----
//
//  For even dimmer output, the proportion of 'ON' time can be reduced:
//
//      --        --        --       --
//     |  |      |  |      |  |     | 
//  ---    ------    ------    -----
//
// This sketch also introduces several conventional programming structures.
//
// ================================================================================
// Configure the hardware once after booting up.  This runs once after pressing
// reset or powering up the board.

void setup()
{
  // Initialize the hardware digital pin 13 as an output.  The 'OUTPUT' symbol
  // is pre-defined by the Arduino system.
  pinMode(LED_BUILTIN, OUTPUT);
}

// ================================================================================
// Define constant values.  The following lines defines "pre-processor macros"
// which can be used to replace one text symbol with a value as the first step
// in compiling the code.  In general, this a recommended practice for making
// the intent of the code more legible.

// Define the period of the PWM waveform in milliseconds.  E.g., the text
// 'PWMPERIOD' will be replaced by the text '10' in the code which follows.
const int PWMPERIOD = 10;

// Define the duration of each fade ramp in millisconds.
const int RAMPPERIOD = 1000;

// Note that constant values can include expressions.  The following line
// determines how many discrete steps will be required to complete the ramp in
// approximately the specified time:
const int RAMPSTEPS = RAMPPERIOD/PWMPERIOD;

// ================================================================================
// Run one iteration of the main event loop.  The Arduino system will call this
// function over and over forever.

void loop()
{
  // Ramp from off to on.  The next code line begins a 'for loop' which will
  // iterate the block delineated by curly braces, with details as follows:
  //
  //  int i = 0;       Declare a new integer variable named 'i' and assign it an initial value of zero.
  //  i < RAMPSTEPS;   This condition determines whether to keep iterating.
  //  i = i+1          Increment the value of i after the completion of each iteration.
  //
  // The net effect is that the loop with execute RAMPSTEPS times, with the
  // value of i counting up on each iteration: 0, 1, 2, ...  On the last
  // iteration i will be equal to RAMPSTEPS-1.
  
  for(int i = 0; i < RAMPSTEPS; i = i+1) {

    // Declare a new local integer value to hold the duration of time the LED should remain on.
    // This uses the highly convenient map() function which remaps a value from one range to another.
    // i has values over range (0,RAMPSTEPS) which are remapped to the range (0,PWMPERIOD).
    int time_on = map(i, 0, RAMPSTEPS, 0, PWMPERIOD);

    // Similarly for the off time.  Note that (time_on + time_off) always equals PWMPERIOD.
    int time_off = PWMPERIOD - time_on;

    digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on
    delay(time_on);                   // wait the specified number of milliseconds
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED off
    delay(time_off);                  // wait the specified number of milliseconds
  }

  // Ramp from on to off.  Note the code is nearly identical; the only
  // difference is that the roles of time_on and time_off are switched.
  
  for(int i = 0; i < RAMPSTEPS; i++) {
    int time_off = (i * PWMPERIOD) / RAMPSTEPS;  // equivalent to map() above
    int time_on = PWMPERIOD - time_off;

    digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on
    delay(time_on);
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED off
    delay(time_off);
  }

  // After this event loop iteration exits, the loop() function will be immediately called again.
}
// ================================================================================