This is based on lessons 3 (LED), 4 (RGB LED) and 5 (Buttons) of the Elegoo UNO Project Super Starter Kit. I set up a multi-colour LED to fade through various colours, and a button to toggle it on or off. The fading is random, not predefined.

Components

It requires:

  • 1x multi-colour (RGB) LED (these have 4 pins)
  • 3x 1000 ohm resistors (colour-coded brown, black, black, brown, gap, brown, which means 1 0 0 * 10 ± 1%)
  • 1x button

Note: I originally used 220 ohm resistors, as recommended in the tutorial, but it was too bright. I could have decreased the brightness in the code, but then it would have been less sensitive.

Circuit

Using a breadboard (useful connection diagram here) and some wires, connect:

RGB LED

  • Red leg → Resistor → Pin 11
  • Cathode leg (longest) → GND (negative) (Note: No resistor)
  • Green leg → Resistor → Pin 10
  • Blue leg (shortest) → Resistor → Pin 9

Button

The buttons have 4 legs in two pairs. The legs that point towards each other are connected together; there’s also a valley on the base of the button which indicates this (similar to the breadboard).

Connect one side of the button to GND, and the other to pin 12.

Note: Different pins can be used by changing the constants in the code below, but make sure to use the pins with a ~ symbol for the LED as those support Pulse Width Modulation (PWM, via the analogWrite() function).

Random seed

To get half-decent slightly more varied random values (i.e. not the same every time), connect a wire from A0 to nothing in particular. This improves the variety of values generated by analogRead(0) and passed to randomSeed(). (Not that you’re likely to notice with something this simple.)

Code

#include <USBAPI.h>

// Pins
#define RED 11
#define GREEN 10
#define BLUE 9
#define BUTTON 12

// Settings
#define MIN_VALUE 0
#define MAX_VALUE 255

#define MIN_CHANGE 1
#define MAX_CHANGE 10

#define DELAY 150

// Variables
bool active = true;
int lastButtonState = HIGH;
int r, g, b, dr, dg, db;

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

    pinMode(RED, OUTPUT);
    pinMode(GREEN, OUTPUT);
    pinMode(BLUE, OUTPUT);
    pinMode(BUTTON, INPUT_PULLUP);

    // Random starting colour & direction
    randomSeed(analogRead(0));

    r = random(MIN_VALUE, MAX_VALUE + 1);
    g = random(MIN_VALUE, MAX_VALUE + 1);
    b = random(MIN_VALUE, MAX_VALUE + 1);

    dr = random(2) ? 1 : -1; // +1 or -1 to determine direction
    dg = random(2) ? 1 : -1;
    db = random(2) ? 1 : -1;

    analogWrite(RED, r);
    analogWrite(GREEN, g);
    analogWrite(BLUE, b);

    // Display the starting values in the serial monitor to ensure it's working correctly
    Serial.println(String("r=") + r + "  g=" + g + "  b=" + b + "  dr=" + dr + "  dg=" + dg + "  db=" + db);
}

void loop() {

    // Button pressed - toggle LED
    const int buttonState = digitalRead(BUTTON);
    if (buttonState == LOW && buttonState != lastButtonState) {
        active = !active;
    }
    lastButtonState = buttonState;

    // LED switched on?
    if (active) {

        // Advance to the next colour
        r += random(MIN_CHANGE, MAX_CHANGE) * dr;
        g += random(MIN_CHANGE, MAX_CHANGE) * dg;
        b += random(MIN_CHANGE, MAX_CHANGE) * db;

        // When the min/max values are reached, switch direction
        r = constrain(r, MIN_VALUE, MAX_VALUE);
        if (r == MIN_VALUE || r == MAX_VALUE) {
            dr = -dr;
        }

        g = constrain(g, MIN_VALUE, MAX_VALUE);
        if (g == MIN_VALUE || g == MAX_VALUE) {
            dg = -dg;
        }

        b = constrain(b, MIN_VALUE, MAX_VALUE);
        if (b == MIN_VALUE || b == MAX_VALUE) {
            db = -db;
        }

        // Set the new LED colour
        analogWrite(RED, r);
        analogWrite(GREEN, g);
        analogWrite(BLUE, b);

        // Display it in the serial monitor to ensure it's working correctly
        Serial.println(String("r=") + r + "  g=" + g + "  b=" + b + "  dr=" + dr + "  dg=" + dg + "  db=" + db);

    } else {

        // Turn the LED off
        analogWrite(RED, 0);
        analogWrite(GREEN, 0);
        analogWrite(BLUE, 0);

    }

    delay(DELAY);
}

References