@johnboyman
I did look into generating white noise some time ago for a purpose not dissimilar to yours. That is for a charging mat with audio privacy for mobile phones
What I did notice was that (a) white noise is actually quite well specified. That is, it is random within certain constraints and (b) if you attempt to use a hardware method, say the noise of a zener diode, then most of the circuits appear to need 9 or more volts for best effect.
These two sketches, collected from various bits I found, are as far as I got with this project:
// https://arduino.stackexchange.com/questions/6715/audio-frequency-white-noise-generation-using-arduino-mini-pro
const uint8_t speakerPin = 8 ;
uint32_t reg = 0xfeedfaceUL ;
//uint32_t reg = 0x33333333UL ;
void generateNoise()
{
uint32_t newr;
unsigned char lobit;
unsigned char b31, b29, b25, b24;
b31 = (reg & (1UL << 31)) >> 31;
b29 = (reg & (1UL << 29)) >> 29;
b25 = (reg & (1UL << 25)) >> 25;
b24 = (reg & (1UL << 24)) >> 24;
lobit = b31 ^ b29 ^ b25 ^ b24;
newr = (reg << 1) | lobit;
reg = newr;
digitalWrite (speakerPin, reg & 1);
delayMicroseconds (50); // Changing this value changes the frequency. //was 50
}
void setup() {
Serial.begin(115200) ;
// put your setup code here, to run once:
pinMode(speakerPin, OUTPUT) ;
}
void loop() {
// put your main code here, to run repeatedly:
generateNoise() ;
}
and
// https://arduino.stackexchange.com/questions/6715/audio-frequency-white-noise-generation-using-arduino-mini-pro
#if 0
/*
* ORIGINAL
*/
#define speakerPin 8
unsigned long lastClick;
void setup() {
// put your setup code here, to run once:
pinMode(speakerPin,OUTPUT);
lastClick = micros();
}
/* initialize with any 32 bit non-zero unsigned long value. */
#define LFSR_INIT 0xfeedfaceUL
/* Choose bits 32, 30, 26, 24 from http://arduino.stackexchange.com/a/6725/6628
* or 32, 22, 2, 1 from
* http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
* or bits 32, 16, 3,2 or 0x80010006UL per http://users.ece.cmu.edu/~koopman/lfsr/index.html
* and http://users.ece.cmu.edu/~koopman/lfsr/32.dat.gz
*/
#define LFSR_MASK ((unsigned long)( 1UL<<31 | 1UL <<15 | 1UL <<2 | 1UL <<1 ))
unsigned int generateNoise(){
// See https://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs
static unsigned long int lfsr = LFSR_INIT; /* 32 bit init, nonzero */
/* If the output bit is 1, apply toggle mask.
* The value has 1 at bits corresponding
* to taps, 0 elsewhere. */
if(lfsr & 1) { lfsr = (lfsr >>1) ^ LFSR_MASK ; return(1);}
else { lfsr >>= 1; return(0);}
}
void loop() {
/* ... */
if ((micros() - lastClick) > 50 ) { // Changing this value changes the frequency.
lastClick = micros();
digitalWrite (speakerPin, generateNoise());
}
}
*/
#endif
#define speakerPin 8
unsigned long lastClick;
void setup() {
// put your setup code here, to run once:
pinMode(speakerPin,OUTPUT);
lastClick = micros();
}
/* initialize with any 32 bit non-zero unsigned long value. */
#define LFSR_INIT 0xfeedfaceUL
/* Choose bits 32, 30, 26, 24 from http://arduino.stackexchange.com/a/6725/6628
* or 32, 22, 2, 1 from
* http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
* or bits 32, 16, 3,2 or 0x80010006UL per http://users.ece.cmu.edu/~koopman/lfsr/index.html
* and http://users.ece.cmu.edu/~koopman/lfsr/32.dat.gz
*/
#define LFSR_MASK ((unsigned long)( 1UL<<31 | 1UL <<15 | 1UL <<2 | 1UL <<1 ))
unsigned int generateNoise(){
// See https://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs
static unsigned long int lfsr = LFSR_INIT; /* 32 bit init, nonzero */
/* If the output bit is 1, apply toggle mask.
* The value has 1 at bits corresponding
* to taps, 0 elsewhere. */
if(lfsr & 1) { lfsr = (lfsr >>1) ^ LFSR_MASK ; return(1);}
else { lfsr >>= 1; return(0);}
}
void loop() {
/* ... */
if ((micros() - lastClick) > 50 ) { // Changing this value changes the frequency.
lastClick = micros();
digitalWrite (speakerPin, generateNoise());
}
}