---
title: "Arduino:  Chasing LEDs with millis()"
description: "A popular LED project is the \"Larson Scanner.\" This scanner emulates the effect seen on KIT from Knight Rider and the Cylons in Battlestar Galactica. The code is usually…"
canonical: "https://www.baldengineer.com/arduino-chasing-leds-with-millis.html"
author: "James Lewis"
date: "2013-12-12T12:00:34Z"
lastmod: "2022-04-03T07:46:40Z"
image: "https://www.baldengineer.com/wp-content/uploads/2012/09/millis-chasing-led-larson-scanner-banner.png"
categories: ["arduino","microcontrollers","millis"]
tags: ["arduino-stuff","arrays","larson-scanner","led","millis-cookbook"]
---

# Arduino:  Chasing LEDs with millis()


A popular LED project is the "Larson Scanner."  This scanner emulates the effect seen on KIT from Knight Rider and the Cylons in Battlestar Galactica.  The code is usually written using "delay()" which means you can't combine it with anything else.  The following code could be put into a function, called periodically and allow your code to scan while doing other things.

[YouTube video m_FNZMPwqOc](https://www.youtube.com/watch?v=m_FNZMPwqOc)


One thing to note, a proper Larson Scanner has some persistence to the next and previous LEDs, this code does not.  Maybe that would be a good exercise for the reader?

Inspired from this [Arduino Forum post](http://forum.arduino.cc/index.php?topic=203918.0).

## The Code

```c
// Simple macros to remember which direction to shift LEDs
#define UP true
#define DOWN false

// Will be used to track how long since last event "fired"
unsigned long previousMillis=0;

// Delay to determine when we see the next LED
unsigned long interval = 250;

// Array with Arduino pins containing LEDs in sequence
byte LEDpins[] = {
2,3,4,5,6,7};

// Variable to track which LED to turn on, start at 000001
int LEDstate=0x01;

// State variable to know which direction to shift
boolean direction=UP;

void setup() {
	// Optional: Push Button to turn on all LEDs (to test)
	pinMode(12, INPUT_PULLUP);

	// Set Pins with LEDs to OUTPUT
	for (int x=0; x < 6; x++)
		pinMode(LEDpins[x], OUTPUT);
}

void loop() {
	// Set the pins of each LED during each iteration
	// You'll only see something change when "LEDpins" gets updated
	for (int x=0; x < 6; x++)
		digitalWrite(LEDpins[x], bitRead(LEDstate,x));

	// Test Funciton to turn on all LEDs with pushbutton
	if (digitalRead(12) == LOW)
		turnOnAll();

	// Get current time and determine how long since last check
	unsigned long currentMillis = millis();
	if ((unsigned long)(currentMillis - previousMillis) >= interval) {
		// We've waited "interval" amount of time, so let's do some stuff!

		// "Reset" our clock
		previousMillis = currentMillis;

		if (direction==UP) {
			// Use "<<" to "bit-shift" everything to the left once
			LEDstate = LEDstate << 1;
			// 0x20 is the "last" LED, another shift makes the value 0x40
			if (LEDstate == 0x40) {
				// turn on the one before "0x20" and reverse direction
				LEDstate = 0x10;
				direction = DOWN;
			}
		} else {
			// use ">>" to "bit-shift" all bits in LEDstate once to the right
			LEDstate = LEDstate >> 1;
			// This means we ran out of bits!
			if (LEDstate == 0x00) {
				// set one ahead so no extra delay
				LEDstate = 0x02;
				direction = UP;
			}
		}
	}
}

void turnOnAll() {
	// Simple code to turn on all LEDs, this "blocks"
	// so when code returns, the same LED in LEDstate will be "saved"
	while (digitalRead(12)==LOW) {
		for (int x=0; x< 6; x++)
			digitalWrite(LEDpins[x], HIGH);
	}
}
```

## Notes

A couple of notes in this code.

## Defines

The defines give us which direction the counter is running.  I used the arbitrary names "UP" and "DOWN", but could have used "LEFT" and "RIGHT."

## Array of Pins

To simplify addressing which pins are connected to LEDs (and in which order) an array is created with the order which the LEDs are connected.  If this is the only thing you're doing in your project, you'll probably have the pins in order like the example.  Using the array lets you use whatever pins are available.

## LEDstate and Shifting

The "magic" in this code is the shifting done with LEDstate.  The HEX value 0x01 is the initial state.  With each iteration, the variable is shifted once to the left or right.  So this means it'll be:

```
0000 0001
0000 0010
0000 0100
0000 1000
0001 0000
0010 0000
0001 0000
0000 1000
0000 0010
0000 0001
```

When the sequence goes one bit too far, the sequence resets with one bit "seeded."

## turnAllOn

To test to make sure the LEDs are connected correctly, I included a function to turn on all the LEDs.

