Math Functions

Lesson 89: Using random() Function

Learn how random() generates pseudo-random values, how ranges work, and how randomSeed() improves variability.

Progress indicator

Lesson 89 of 89

Learning Objectives

  • Understand what random() does and why it is pseudo-random, not truly random.
  • Use random() syntax with one-argument and two-argument forms.
  • Understand random range behavior and inclusive/exclusive boundaries.
  • Learn the difference between random() and randomSeed().
  • Build safer random logic by controlling ranges and validating outputs.
  • Debug random behavior by reading Serial output and checking sequence patterns.

Concept Explanation

What is random()

random() returns pseudo-random numbers. That means values look random, but are generated by a repeatable internal algorithm.

Without a changing seed, the same sequence can repeat after every reset.

For beginners: pseudo-random is usually good enough for blinking patterns, game logic, and simulation demos. For cryptography/security use cases, this function is not sufficient.

random() Syntax

  • random(max): returns from 0 to max - 1
  • random(min, max): returns from min to max - 1

The upper limit is excluded, which is a common beginner confusion.

Example: random(5) can return 0, 1, 2, 3, or 4 only. It will not return 5.

How random() Works

  1. Use an internal pseudo-random generator state.
  2. Compute next value in the sequence.
  3. Map that value into the requested range.

The generator is deterministic, so seed selection matters if you want variation after reboot.

If two devices start with the same seed and call random() in the same order, they will produce the same sequence.

Random Range Concept

For random(min, max), min is included and max is excluded.

Example: random(200, 1001) can return 200..1000.

Use ranges that match your hardware limits. For timing, avoid values that are too short (flicker) or too long (unresponsive behavior).

random() vs randomSeed()

random() generates numbers. randomSeed() sets starting state for the generator.

If you use the same seed, you get the same sequence. Using changing inputs (for example analog noise) gives better variability.

Typical pattern: call randomSeed(...) once in setup(), then call random(...) inside loop() whenever you need a new value.

When to Use random()

  • Randomized blink delays and test patterns.
  • Simple game or quiz behavior on embedded displays.
  • Non-repeating demo effects for LEDs and actuators.
  • Simulation-style inputs for learning and testing.

Real-life example: vary status LED blink interval slightly so it looks more natural and less robotic in prototype demos.

Example Code

This example randomizes LED off-time delay so each blink cycle changes timing.

const int LED_PIN = 2;
int blinkDelay = 500;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(115200);

  // Seed from floating analog input noise.
  randomSeed(analogRead(34));
}

void loop() {
  // Generate delay between 200 and 1000 ms.
  blinkDelay = random(200, 1001);

  digitalWrite(LED_PIN, HIGH);
  delay(120);
  digitalWrite(LED_PIN, LOW);
  delay(blinkDelay);

  Serial.print("Random delay(ms): ");
  Serial.println(blinkDelay);
}

Example Code Explanation

  1. Configure LED pin as output and start Serial monitor in setup().
  2. Seed random generator once using analog input noise.
  3. Generate a random delay using random(200, 1001).
  4. Turn LED ON briefly, then OFF.
  5. Wait using the random delay value for changing blink rhythm.
  6. Print random delay to Serial so you can verify behavior.
  7. Because the range is 200..1000, every loop gives a safe delay that keeps blink behavior visible.
  8. Seeding in setup makes reboot behavior less repetitive compared to fixed-seed startup.

What Happens Inside

  1. randomSeed() initializes pseudo-random internal state.
  2. random(min, max) advances state and creates next sequence value.
  3. Value is bounded to requested interval before returning.
  4. Returned value is stored in blinkDelay.
  5. Program uses that delay to change timing behavior each loop.
  6. Serial log prints observed output for debugging.
Internal model: seed initializes sequence -> generator advances state -> bounded value is returned -> application logic uses value -> Serial confirms runtime behavior.

Common Mistakes with random()

  • Assuming the upper limit is included in random(min, max).
  • Calling randomSeed() repeatedly inside loop() and reducing randomness quality.
  • Forgetting seed initialization and getting same sequence each reset.
  • Using ranges that are too wide for the intended hardware behavior.
  • Not printing values during testing, making debugging harder.

Best Practices for random()

  • Seed once in setup() with changing input like analog noise.
  • Choose tight, safe ranges based on hardware constraints.
  • Remember max is exclusive in random(min, max).
  • Log generated values while tuning behavior.
  • Keep fallback logic if random values drive critical control actions.

Try it now

Open the simulator workspace and inspect changing random delays in the timeline and serial monitor.

Run in Simulator