SensorFade Arduino Sketch

This sketch is used by Exercise: Sensor Fade.

Full Source Code

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

  1// SensorFade - read a photosensor and control several LEDs at different brightnesses
  2//
  3// Copyright (c) 2016, Garth Zeglin.  All rights reserved. Licensed under the
  4// terms of the BSD 3-clause license as included in LICENSE.
  5//
  6// This program assumes that:
  7//
  8//  1. A sensor is attached to analog input A0.  The exercise uses a photocell
  9//     with a 5.6K pull-down resistor in a voltage divider.
 10//
 11//  2. Pins 5 and 6 are attached via dropping resistors to LEDs which connect to
 12//     ground.  The output pin is used to source current; the logic will be
 13//     positive (HIGH = ON).
 14
 15// ================================================================================
 16// Definitions of constant values.
 17const int LED1PIN = 5;
 18const int LED2PIN = 6;
 19const int SENSORPIN = A0;
 20
 21const int BLINKDELAY = 500;  // interval between fixed blinks, in milliseconds
 22
 23// The following declarations define scaling constants and thresholds for
 24// interpreting the analog input signal.  The input range for a typical
 25// photocell with a 5.6K bias resistor is centered around 4 volts.  This can be
 26// verified using a voltmeter to check the range of inputs on A0 and adjust the
 27// following V_DARK and V_LIGHT values.  Note the use of the scaling factors to
 28// scale the measured voltages into ADC units.
 29
 30// These are physically measured voltages defining the typical dark and light
 31// input voltages.  You may need to change these:
 32const float V_DARK  = 3.5; // in Volts
 33const float V_LIGHT = 4.2; // in Volts
 34
 35// These are properties of the Arduino analog-to-digital converter:
 36const float ADC_MAX_VOLTAGE = 5.0;  // in Volts
 37const int   ADC_RANGE       = 1024; // in dimensionless ADC units
 38
 39// These thresholds are calculated from the other constants.
 40const int V_LOW  = V_DARK  * (ADC_RANGE/ADC_MAX_VOLTAGE);  // in dimensionless ADC units
 41const int V_HIGH = V_LIGHT * (ADC_RANGE/ADC_MAX_VOLTAGE);  // in dimensionless ADC units
 42
 43// ================================================================================
 44// Global variable declarations.
 45
 46// Counter variable to keep to track of the number of update periods for
 47// defining the blinks of the onboard LED.
 48int led_cycle_count = 0;
 49
 50// ================================================================================
 51// Configure the hardware once after booting up.  This runs once after pressing
 52// reset or powering up the board.
 53
 54void setup(void)
 55{
 56  // Initialize the hardware digital pin 13 as an output.  The 'OUTPUT' symbol
 57  // is pre-defined by the Arduino system.
 58  pinMode(LED_BUILTIN, OUTPUT);
 59
 60  // Initialize the external LEDs as outputs.
 61  pinMode(LED1PIN, OUTPUT);
 62  pinMode(LED2PIN, OUTPUT);
 63
 64  // Produce a timed sequence of blinks to indicate the start of the program.
 65  fixed_blink_pattern();  // this function is defined below
 66}
 67
 68// ================================================================================
 69// Run one iteration of the main event loop.  The Arduino system will call this
 70// function over and over forever.
 71
 72// This function continuously maps changes of the photocell input level into
 73// pulse-width-modulated (PWM) output on the LED.
 74
 75void loop(void)
 76{
 77  // Read the voltage on the sensor input.  This function returns a value
 78  // between 0 and 1023 representing a voltage between 0 and 5V.
 79  int sensor = analogRead(SENSORPIN);
 80    
 81  // Compute proportional signals to drive the LEDs by mapping an input range to
 82  // the output range.  The input thresholds are defined above in this file.  The
 83  // PWM output is scaled from 0 to 255.
 84  int led1_value = map(sensor, V_LOW, V_HIGH,   0, 255);
 85  int led2_value = map(sensor, V_LOW, V_HIGH, 255,   0);  // symmetric scaling
 86    
 87  // Emit PWM signals with a proportional average power; the LEDs will have
 88  // variable brightness.  The constrain function will ensure the values stay
 89  // within the correct limits.
 90  analogWrite(LED1PIN, constrain(led1_value, 0, 255));
 91  analogWrite(LED2PIN, constrain(led2_value, 0, 255));
 92
 93  // Blink the onboard LED.  led_cycle_count is a global variable defined above.
 94  if (led_cycle_count == 0) {
 95    digitalWrite(LED_BUILTIN, LOW);
 96  } else if (led_cycle_count == 32) {
 97    digitalWrite(LED_BUILTIN, HIGH);
 98  }
 99  // Increase the cycle count for the next iteration.
100  if (led_cycle_count < 63) {
101    led_cycle_count += 1;
102  } else {
103    led_cycle_count = 0;
104  }
105
106  // Delay for a short interval to create a periodic sampling rate.
107  delay(20);
108}
109
110// ================================================================================
111// Subroutine definitions.
112
113// Flash a fixed pattern for a few cycles.  This uses binary digital outputs so
114// the LEDS will be either full brightness or off.
115void fixed_blink_pattern(void)
116{
117  // Loop once for each iteration of the blink pattern.
118  for (int i = 0; i < 3; i = i+1) {
119    digitalWrite(LED1PIN, HIGH);   // turn LED1 on
120    delay(BLINKDELAY);
121    
122    digitalWrite(LED1PIN, LOW);    // turn LED1 off
123    digitalWrite(LED2PIN, HIGH);   // turn LED2 on
124    delay(BLINKDELAY);
125    
126    digitalWrite(LED2PIN, LOW);    // turn LED2 off
127    delay(BLINKDELAY);
128  }
129}
130
131// ================================================================================