# Arduino Pseudo-Random White Noise Source

A reader (you know who you are!) proposed an interesting project that will involve measuring audio passbands and suggested using white noise to show the entire shape on a spectrum analyzer. He pointed me at the NOISE 1B Noise Generator based on a PIC microcontroller, which led to trying out the same idea on an Arduino.

The first pass used the low bit from the Arduino runtime’s built-in `random()` function:

Well, that’s a tad pokey for audio: 54 μs/bit = 18.5 kHz. Turns out they use an algorithm based on multiplication and division to produce nice-looking numbers, but doing that to 32 bit quantities takes quite a while on an 8 bit microcontroller teleported from the mid 1990s.

The general idea is to send a bit from the end of a linear feedback shift register to an output to produce a randomly switching binary signal. Because successive values involve only shifts and XORs, it should trundle along at a pretty good clip and, indeed, it does:

I used the Galois optimization, rather than a traditional LFSR, because I only need one random bit and don’t care about the actual sequence of values. In round numbers, it spits out bits an order of magnitude faster at 6 μs/bit = 160 kHz.

For lack of anything smarter, I picked the first set of coefficients from the list of 32 bit maximal-length values at https://users.ece.cmu.edu/~koopman/lfsr/index.html:
`0x80000057`.

The spectrum looks pretty good, particularly if you’re only interested in the audio range way over on the left side:

It’s down 3 dB at 76 kHz, about half the 160 kHz bit flipping pace.

If you were fussy, you’d turn off the 1 ms timer interrupt to remove a slight jitter in the output.

It’s built with an old Arduino Pro Mini wired up to a counterfeit FTDI USB converter. Maybe this is the best thing I can do with it: put it in a box with a few audio filters for various noise colors and be done with it.

It occurs to me I could fire it into the 60 kHz preamp’s snout to measure the response over a fairly broad range while I’m waiting for better RF reception across the continent.

The Arduino source code as a GitHub Gist:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 // Quick test for random bit generation timing // Ed Nisley KE4ZNU - 2017-10-25 // Observe output bit on an oscilloscope // This code uses the Galois implementation // Coefficients from https://users.ece.cmu.edu/~koopman/lfsr/index.html #define PIN_RND 13 #include uint32_t Rnd; byte LowBit; void setup() { Serial.begin(57600); Serial.println("Random bit timing"); Serial.println("Ed Nisley KE4ZNU - 2017-10-25"); Entropy.initialize(); pinMode(PIN_RND,OUTPUT); uint32_t Seed = Entropy.random(); Serial.print("Seed: "); Serial.println(Seed,HEX); randomSeed(Seed); do { Rnd = random(); } while (!Rnd); // get nonzero initial value } void loop() { // digitalWrite(PIN_RND,Rnd & 1); // about 55 us/bit // Rnd = random(); LowBit = Rnd & 1; digitalWrite(PIN_RND,LowBit); // about 6 us/bit Rnd >>= 1; Rnd ^= LowBit ? 0x80000057ul : 0ul; }
view raw Random_Time.ino hosted with ❤ by GitHub