I2C device addressing

I worked on the 32-bit random seed, see below for the code.

I originally tried a simple shift and OR of four calls to analogRead() but the results were anything but random.

I then tried a hash algorithm to randomize the 32-bit seed. It came from the One-at-a-Time Hash in A Hash Function for Hash Table Lookup I chose the One-at-a-Time Hash because it seemed fast and just as importantly didn't require a static table of values.

In any case, these are the values from Arduino #1:

=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2012.12.30 13:47:47 =~=~=~=~=~=~=~=~=~=~=~=
Setup: starting
seed: 6A60AA2E  val: 1883564177
seed: C4FE6FC4  val: 475762328
seed: 2632BF6C  val: 1303731979
Setup: starting
seed: 82D6BB73  val: 1605122770
seed: 4A19CB4C  val: 1668419733
seed: 8C4A9682  val: 1960768884
seed: 278A61DB  val: 1847493924
Setup: starting
seed: E317FC10  val: 1000697756
seed: C4881F55  val: 1153492722
Setup: starting
seed: EE2A2EAB  val: 324916071
seed: 3CA34E8A  val: 91841824
seed: 6BCDC084  val: 286937447

I pushed the reset button every so often (that's the "Setup: starting"). But a software reset does not change the state of the analog pin and therefore is not the same as a power cycle of the chip. So I tried power cycling the Arduino several times and there was no duplication in any of the seeds that I could see.

I was also concerned about the values across multiple Arduinos. I loaded the code into Arduino #2 and got similar (but different) output:

=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2012.12.30 13:49:00 =~=~=~=~=~=~=~=~=~=~=~=
Setup: starting
seed: CB93CE3C  val: 1422436928
seed: EC10751D  val: 746109105
seed: 37225535  val: 789063386
Setup: starting
seed: 9A7DAC36  val: 817158441
seed: 4A19CB4C  val: 1668419733
Setup: starting
seed: 16561981  val: 1856270235
seed: 732AA691  val: 1964881064
seed: 4A19CB4C  val: 1668419733
seed: 53EACBA0  val: 1541316714

One thing I considered to get even more randomness was to use a hash of the contents of SRAM. Given the results here, it doesn't seem necessary, for my purposes anyway.

Note: there is not a hint of formality in this testing, take it with a grain of salt.

John

// for hash algorithm used in getSeed, see One-at-a-Time Hash
//    http://burtleburtle.net/bob/hash/doobs.html
#include "WProgram.h"

//===========================
void setup()
  {
  Serial.begin(115200);
  Serial.println("Starting");
  }

//===========================
// calculate a 32 bit seed from 4 reads from analog pin
// use a hash algorithm to mix/combine the reads into a "more random" value
unsigned long getSeed(const int pin)
  {
  unsigned long seed;
  unsigned long i;
  for (seed = 0, i = 0; i < 4; ++i)
    {
    seed += analogRead(pin);
    seed += (seed << 10);
    seed ^= (seed >> 6);
    }
  seed += (seed << 3);
  seed ^= (seed >> 11);
  seed += (seed << 15);
  return seed;
  }

//===========================
void loop()
  {
  unsigned long seed = getSeed(0);

  Serial.print("seed: ");
  Serial.print(seed, HEX);
  srandom(seed);

  unsigned long val = random();
  Serial.print("  val: ");
  Serial.println(val);

  delay(1000);
  }