Knight Rider Without Flicker

So now we already created a flicker free bouncing ball. But stay with me. The generator based approach is somewhat uncool. Unlike in the picture experiment we do not need to load some bitmap. The whole information required to produce the sketch is available at compile time. Wouldn’t it be cool to push these computations to the compiler? Of course – but how? There are two routes. The more modern approach is template meta programming. The older approach is to use the macro preprocessor. Here I will stick to the macro processor. The reason is that unlike the template approach the macro based approach is slightly simpler to debug. That is: if something fails the macros can be expanded by compiling with “avr-gcc -E” from the command line. This then allows to look at the expanded macros and hopefully find the issue. With templates I am not aware of a similar mechanism.

So how does this sketch work? At runtime it is similar to what we already had before. The main loop will cycle through the PWM pattern. The timer2 library will compute a new index every 60ms which will then make the main loop go through the next PWM pattern. The more interesting issue is how this pattern is computed.
Let’s have a look at the macros. There are two different set of macros. In the first set are the macros

These macros will expand to (constant) integer expressions if they are fed with integer constants. The compiler can and will compute the results at compile time. The most important trick here is that this applies to obvious integer operators like „+“, „-“, „*“, „<<“ or others but also to the ternary „?“ operator. Hence we can compute the desired port bits per phase and cycle and combine them into a portstate.

The other set of macros are the

Ports(phase, cycle)
pwm(phase)

These will expand into a large comma separated list of port states as determined by the previous macros. This list is the array which is then processed at runtime.
Notice that these macros only look simple. At compile time the macro processor will expand them recursively. So the sheer size of the expanded macros will give the compiler something to chew. The compile time may be higher than you might expect. Use avr-gcc -E to get an idea how large they actually are.

Once you run this sketch you may want to move the Blinkenlight Shield in front of you to see the difference. Or you can use a camera with long exposure time. Compare the different effects with and without flicker.

Knight Rider PWM Flicker

Knight Rider Without Flicker

But this story is not yet finished. Of course I want to have a mode switch like for the basic effects. As it turns out this is now somewhat more complicated. Read on to learn how to switch multiple flicker free effects.