A Tale of Managing LED Displays

Last Modified: 2/12/97

[email protected] / My Home Page

Introduction

This is a story on designing software for managing LEDs, you know, those little colored blinking things on hardware. This may seem a silly a subject, but on a recent project we spent an outrageous amount of time on LED design and came up with a suprisingly cool solution I felt worth sharing.

Note, this paper doesn't cover hardware. It's assumed there's an object that speaks to the LED hardware and can make it change colors. The design of the serial protocols needed to make this happen may be complicated and interesting, but are not covered here.

Another note, there aren't any diagrams or code. Just a discussion. The fun parts are left as an exercise :-)

LEDs seem simple. You just make them flash colors. What could be simpler? I go by the saying if someone says something is simple they are lying. This is so true for LEDs.

Of course it does depend on the system. If a system just has to blink green when everything is going fine or amber when things are going OK then it should be fairly simple (oh oh, i'm lying again). LEDs however always grow more complex as every nuance of a system's operation must be shown in the LEDs. LEDs are the facial expressions of a device.

People in the field find expressive LEDs very useful as will advanced users. Good LED desing can prevent the use of more intrusive testing equipment and possibly prevent a service call or two. The real reason LED displays get complicated is people can see LEDs which compels them to make changes. If people couldn't see LEDs they would never change :-)

From a programmers perspective your design will start simple and clean. When this or that happens show this or that colour. Then the special cases start getting added. Don't display this if that and the other thing happened. Eventually your original clean design breaks, it can't handle the added complexity. In defense against the inevitable you may want to consider the following approach which is pretty flexible, simple, and robust.

Knobs We Can Twist

What can we do to LEDs to reflect system state:

Use Events

This design assumes a system where events are emitted when interesting things happen. Many events should be reflected in the LEDs.

The Led Agent is driven by events and only events. MIB requests are considered a type of event. No part of the system touches the LEDs except for the Led Agent. Decoupling LED management from the rest of the system makes for a very robust and easily modifiable system. Modules in the system only care about emiting the events they are responsible for, they are not concerned at all about how those events are reflected in the LEDs. Led Agent can make radical changes without any other part of the system caring. It's all in the events.

Detect Events Not States

My first design instinct was to make the LED agent a state machine. Events would flow in triggering the state machine on to the next state and color pattern.

The problem with this approach is Led Agent grew very complex as it eventually incorperated parts of every other state machine in the system. Don't make this mistake. Assume other modules in the system will only emit events when they should. There's no reason to validate events using a state machine. LEDs should only reflect events in the system.

Handling Events

Events are streaming into Led Agent. How do you decide which events are displayed? Is the current event interrupted? What happens when an event has displayed its number of cycles and is done? Your project may come to different answers but here are some.

Don't Interrupt

Don't interrupt the current LED display unless it's an infinite cycle display. To do so means the colour pattern is arbitrarily ended at a certain point in the sequence and the next event display started. Unless you are very careful desinging the color sequences the colour sequences between the two events are merged and it's difficult to tell what is happening.

When Done Go Next

The LED display engine has to signal when a sequence has completed. At that time display the next event.

What's Next?

Here's the key. What event is next to display? My first design was stuck on the concept of having a current event displayed and a saved event. When a new event came in the current event was saved and the new event displayed. When the new event was done the old current was displayed again.

This was a fundamentally wrong approach and took some time to get out of my head. The problem with that approach was every thing became a special case. For example, some events should only be cleared by another event of a specific type. Other events are transient and should only be displayed for a while. Some event type should cancel the current saved event and become the new current event. And on and on. It becomes very difficult to incorperate any kind of complexity with a current state/saved state approach.

The solution is to introduce the idea of event categories and priority. Always display the event associated with the highest priority event category.

Event Categories

A system has a defined set of events. For Led Agent purposes events naturally fall into several categories, in highest to lowest priority order:

Memory and Priority

An event (or no event) is remembered for each event category. All categories are simultaneously active. Priority decides which event is display. If a stable category event comes in then replace the current stable event. It may not be shown on the LED because a higher priority category may have an event.

Implementation Notes

Timer Fire

When the Led Agent starts start a timer running at the fundamental time unit. When the timer fires its main job is to call the Paint method of the current Sequence for the current highest priority category. If the Sequence indicates it has completed its sequence, say for a transient event, then the timer handler calls Led Agent's Next(SHOW_NEXT) method to calculate the next highest priority event category. Notice by using a fundamental time unit we never have to start or stop timers again. Simple and clean.

Sequence Descriptor

We want to be able to easily add new events into the system. When the Led Agent is created it should create all the event sequences it handles and store them in a array (or whatever). You can think all sorts of way to make this configurable.

You may want a Sequence object that has:

Incoming Events

Events arriving into Led Agent are immediately mapped to their internal event number and Next(event) is called to figure out what to do with the new event. Next calculates what events should be dropped, if for example the incoming event is in the transient category then if there is a current transient category event then the new event should be dropped. Same for locked category events. Stable category events should just replace each other. Preempt events need to take the steps to clear all other events. The Next method of Led Agent doesn't need to call the Paint method, the next timer firing will automatically start displaying the new event.

Category Values

Make your event category value such that they can index into an array. This makes getting the event for a category simpler.

Wrapping Up

I hope you both understood the above explanation and got something out of it. If you have any questions or improvements please contact me at [email protected].


Home

© Copyright 1995-1997. Todd Hoff. All rights reserved.