I have been sitting on the hardware for this project for quite a while. The RGB Blaster I added to a SparkFun order over a year ago as an impulse buy. I was struggling with the idea of making a device that just displays a bunch of different colors to look “pretty”. Also, I am not artistic enough to pick the colors out myself so they would have to be random. So, here and there I would look at Pseudo Random Number Generators (PRNG) on the internet. There are a lot of really good ones out there, but I still felt, well, pseudo excited about the “decoration” I was planning to make. I certainly wouldn't purchase such a device if I were to see one in the shops. I'm not sure if it was all the snow outside or seeing Bruce Schneier's latest CRYPTO-GRAM in my inbox that got me thinking, but I decided I would be OK proceeding with this project if I used a True Random Number Generator (TRNG).
TRNGs can be made in a multitude of ways and my first choice was to use radioactive decay because it sounds badass, but alas, the hunt for my Civil Defense Geiger Counter turned up bupkis. My second choice of entropy was diode avalanche noise mainly because it is easy. This page has a good write up and a circuit I used as a white noise generator. Essentially, an NPN transistor is reverse biased producing avalanche noise which is then amplified. Now that we have a source of entropy in the form of a white noise generator we can complete the rest of the TRNG.
There are several tests out there to evaluate RNG's. I did not do that. But, what I did do is observe the white noise on the oscilloscope and you can see here it is, well, noise. In addition, I wrote a program to take 20 million random bit samples and increment or decrement a variable depending on whether the bit was a 1 or a 0. I ran this several times and came back with values ranging from +/-2500 to +/-11! This means that out of the 20 million samples there were at times as few as 11 more 1's than 0's. I am satisfied that this is sufficiently random for the task.
The ATTiny2313 is running on its internal 8Mhz clock. There is no critical timing to be done and the massive frequency tolerance of +/-10% just serves as another source of entropy. The white noise generator/amplifier is connected to PD0. The LED on PD1 is just for debugging. And the three IRF510 MOSFETS for controlling the red green and blue led's on the RGB Blaster, note this is not the the one blinkM sells with a controller board. This is just three LEDs on a board with resistors. IRF510 is pretty overkill for the job since each LED draws less than 100mA, but I had them. The four push buttons don't do anything, they aren't even connected. I wasn't sure where I was going with the software when I did the hardware so they ended up on the board and I may still end up using them for something. The RGB Blaster module has been hot glued to the inside of a semi opaque condiments cup to help blend the 3 colours together.
The software takes two samples from the white noise generator, does an XOR on them, and if true, takes one of the samples as a random bit. It does not matter if you take the first one or the second one, but I use the first bit. This is called the Von Neumann method or filter for unbiasing the bits. Now, it gathers up 8 of these random bits into a byte and that is the value to put into the PWM register. It does this once for each colour and then fades to the new RGB value and holds that colour for a set amount of time. Dead simple really. This makes for a total number of theoretically possible colours to be 255^3 = 16,581,375.
The source code and schematic can be found here.
In this video you can see the lamp operating. I removed a lot of program delay to speed up the colour changes just for the video.
Overall I am pleased with the results. Of course a PRNG would have been sufficient; even cycling through the 16+ million colors in numerical order you would probably get a pretty lamp. But, there is something about visualizing true randomness that appears intentional is, well, I'm not sure, but I like it.