## In Youth and Beauty

I bought two pieces of art to hang from my son’s elementary school. I loved them immediately. The abstract tiles where done by my son’s 3rd and 4th grade class. The tree was made by a 1st and 2nd grade class. Both pieces of art are really lovely. The tree has a cool property, like a scene in Ferris Bueller. The art changes its character from far away to as close anyone would care to get. First, the tiles of abstract images of persons and animals was made under the rule that the student not pick up the pen during the drawing and then there are rules for filling with color, like a graph coloring rule.

The other artwork is a sort of mosaic of paper circles colored and glued to a black foam core board. The tree shots zoom in with three steps doubling the zoom at each step.

## Arduino Flickering Candle

Update December 24, 2013: Mokus refined his code so that the distribution is now well-behaved (nearly normal) and the PSD no longer turns up at high frequencies). The plots and post have been updated to reflect this change. He will push code to the same link as available.

In my previous post on Candle Flame Flicker I describe the statistics of the optical intensity flicker from a candle in terms of the probability density of the brightness samples and in terms of the power spectral density of the brightness. In this article I discuss how to make an Arduino drive an LED to flicker in a way that is statistically similar to the measurements I took on a real candle.

In the measurements I observed the spectral roll-off of the candle to start between about 5 and 8 Hz, and to decline at a nominal rate of around 44 dB for each decade increase in frequency. The 2nd-order infinite impulse response filter is computationally efficient in terms of using a small amount of memory and requiring few calculations. However, the Arduino is not good at floating point arithmetic. On the Arduino, floating point is done in software, has relatively few bits of precision, and is about 4 to 40 times slower than fixed point (integer) math. It is quite difficult to find useful benchmarks. The basic process is to create white noise and then filter it to the correct spectral shape. Afterward, the signal is scaled to have the appropriate variance and offset with a constant to represent the average brightness of the “flame”.

The approach I used was to design the IIR in Python with scipy’s signal module. I specified a 2nd order lowpass Butterworth filter, specifying a cutoff frequency of 8 Hz, and a sample frequency of 60 Hz. I normalized the coefficients to work in a 16 bit integer space, following Randy Yates’ 2010 Practical Considerations in FIR Fixed Filter Implementations, mainly. From a synthesis perspective, there is some prior art. Philip Ching, a student at Cornell synthesized candle noise quite cleverly, though he neither reported nor replicated the correct statistics. A fellow with the handle Mokus did a very, very tiny implementation for a microcontroller with only 64 bytes of RAM. He helped me modify his code so I could compare his statistics, and after adjustment his spectrum and distribution match fairly well. The high-frequency of his PSD looks a little different from the other methods, but these may not be noticeable to the observer. Finally, there was Eric Evenchick’s coincidental post on hackaday. Mokus reported that Evanchick’s implementation has too slow an update rate; I noticed that Evanchick did not report on the statistics he was targeting nor what he achieved. I did not recreate his work to test.

Then, on to the tests. I really was interested in building and comparing statistics from a 16 bit implementation, a 32 bit implementation in both a Direct Form I and a Direct Form II implementation. Indeed, I had great difficulty getting the filters to perform because I kept misdesigning the integer coefficients and overflowing the registers. As I sought a solution to the 2nd-order filter approach, I also created a 4-stage digital equivalent of an RC filter. The 4-stage RC approach was always stable though it needed a higher sample rate and used much more processor power to create statistically consistent results. On the other hand, it has a more accurate spectrum. A comparison of three different 16-bit methods to Mokus’ and to the actual measurements is shown in the figure below. The legend shows the mean, standard deviation, and their ratio to the right of the label. The All my filters did a credible job of reconstructing the histogram.

The power spectral density (PSD) of the different methods tells a different story. The Direct Form II 16 bit filter is the most visually appealing of the methods I tried. It rolls off more like the physical data than the other methods, except compared to the 4-stage RC filter. The Direct Form II filter is more computationally efficient.

The results for the 32-bit versions show greater variance than the 16-bit versions, but the quality is not markedly better.

I wrote a proof code for the Arduino UNO both to see it flicker and to test the processor speed—separate parts of the code. The results are that compiling with 1.0.3 resulted in a 4,722 byte program that calculated 10,000 new values in 6,292 ms, or 629 microseconds per value. In theory this could produce a sample rate of nearly 1.6 KHz. Or another way of thinking about this is that the final code uses about 629 us/17 ms or about 4% of the processor capability of the Arduino UNO. That leaves a lot of resources available to do other Arduino work or maybe means it can fit in a cheaper processor.

I have released two pieces of code under the GNU Public License 3, you can get the Python I used for filter design and the Arduino test code at the links. If you want the data, please contact me through the comments and I am willing to provide it.

## Candle Flame Flicker

For a project I wanted to make an LED flicker like a candle. I searched for the signal statistics of candle flicker, and I found no data. One student web site suggests that candle flame flicker is a 1/f-type random signal with roll-off of 20 dB per decade increase in frequency. Similar processes are typical for turbulence, so this student’s plan seemed reasonable. However, the student did not discuss whether the signal is Gaussian or not, and did not describe the low-frequency characteristics of the signal. 1/f noises may have a spectrum that follows the 1/f curve to very low frequencies, but because they would require infinite power at f=0 they always have some lower frequency change. I had no data.

Candles aren’t hard to get, and I already had a silicon photodiode for an absorptive smoke density measurement system I’m working on. I also had an analog-to-digital converter (ADC) in an ADS1015 on a breakout board from Adafruit. I made the very simple circuit shown below and attached it to a Raspberry Pi to sample the data. There are a lot more details, but those are later.

The voltage measured by the ADC is directly proportional to the current through the resistor. The current through the reverse-biased diode is directly proportional to the incident optical power. Very simple. I recorded a minute of data at a low 250 Hz sample rate, and subjected the data to analysis. The setup was a nominally dark room with the sensor a few inches from the flame. I flapped my hand at the candle to get it to flicker while recording.

The first graph below is a histogram of sample values.

The histogram is about normally distributed, but the right-hand tail is not Gaussian; it is too fat. In other words the candle is occasionally much brighter than normal. The time series (below) shows the same properties. There are clearly visible large excursions.

For human eyes the candle’s flicker will be well represented if the frequency spectrum of the flicker and the distribution of the flicker approximately match a natural source. The spectrum below can be thought of as an average brightness (the peak at the left), a flat spectral region out to about 4 Hz, and then a 1/f-style roll off at 44 dB per decade.

Numerically, we have the recipe for a flickering candle:

• Samples should be normally distributed with a standard deviation equal to 0.25 of the mean.
• The power spectral density of the signal should roll off at about 40 dB per decade with a 3 dB cutoff frequency around six cycles per second.

To make this work on the Arduino using the pulse-width modulated outputs, we can further constrain the problem:

• The maximum value cannot exceed 255 counts—or make the limit that the mean plus two standard deviations is 255.
• From this, we can derive that 2s+m = 255, use the fact that 0.25m=s to find that the mean m=170 and the standard deviation is about 42.
• A sample rate of between 30 and 120 Hz should be more than adequate to satisfy the Nyquist criterion for human vision (see Wikipedia).
• Values may not go below zero or above 255
• A second-order infinite impulse response (IIR) filter has a roll-off of 40 dB per decade

If we can find a numerically efficient way to generate a time-series of Gaussian random variables inside the Arduino, filter them with a 2nd-order fixed-point IIR, scale them (if needed) then we should be able to make a flickering candle.

Unfortunately, I have failed repeatedly to get a stable fixed point IIR filter. The cookbook solution specification above should be easy to implement, but I have not found it so. A better solution will have to wait for another post.