In need of a quick-and-easy way to generate interesting data that would make an LED array do something and, what with radioactivity being the canonical source for random numbers, an ancient Aware Electronics RM-60 (*) emerged from the heap. The manual will get you up to speed on radiation detection, if you can read past the DOS-era program description.
It produces a 100 µs (-ish) pulse for each detection:

The minimum period seems to be around 500 µs, but I lack a sufficiently fierce radioactive source to verify that in any finite amount of time.
Seeing as how all we need is a little randomness, measuring the time when a pulse occurs will suffice; we’re not talking hardcore crypto.
With the pulse arriving on the Arduino D2 input, define an interrupt handler that sets a flag, bumps a counter, and records the current time in microseconds:
void GeigerHandler(void) { if (!GeigerTicked) { // stop recording until loop() extracts the data GeigerTicked = true; GeigerTicks++; GeigerTime = micros(); } }
Define D2 as an input, turn on the pullup, and trigger that handler on the falling edge of the pulse:
pinMode(PIN_GEIGER,INPUT_PULLUP); // RM-60 has its own pullup, but add this one, too attachInterrupt((PIN_GEIGER - 2),GeigerHandler,FALLING);
Because an absolute timestamp of each event will produce an obviously non-random sequence of monotonically increasing numbers, I ran each four byte timestamp through a simple hash function to whiten the noise:
//------------------ // Jenkins one-at-a-time hash // From http://en.wikipedia.org/wiki/Jenkins_hash_function uint32_t jenkins_one_at_a_time_hash(char *key, size_t len) { uint32_t hash, i; for(hash = i = 0; i < len; ++i) { hash += key[i]; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; }
Then the only thing left to do is spin around the loop()
while waiting for a particle to arrive:
if (GeigerTicked) { digitalWrite(PIN_HEARTBEAT,HIGH); // show a blip analogWrite(PIN_DIMMING,LEDS_OFF); // turn off LED array to prevent bright glitch Hash = jenkins_one_at_a_time_hash((char *)&GeigerTime,4); // whiten the noise GeigerTicked = false; // flag interrupt handler to resume recording // printf("%9ld %08lx %08lx ",GeigerTicks,GeigerTime,Hash); SetLED(Hash); }
The Heartbeat LED gets turned off every 25 ms.
In the spirit of “video or it didn’t happen”: there’s a movie about that.
(*) Circuit Cellar readers of long memory will recognize the RM-60 as the McGuffin for the Radioactive Randoms column in 1990 that explained features of interrupt-driven code in a Micromint BASIC-52 board. Decades later, the hardware & software served as Prior Art in a patent suit that forced me to write some Rules of Engagement. Selah.
Looks kinda like a multicolored version of Go or Reversi.
A simple matter of software… [grin]