For DIY, how to program Arduino Mini Pro to act as an Audio Frequency White Noise generator?

Presumably,

a) using one Digital Output pin

b) feed to a simple passive RC low pass filter to reduce out of band signal

c) feed to a simple class-D IC chip audio amplifier and speaker

d) since it is DIY and noise, lo-fi (not hi-fi) is good enough.

Specific questions,

a) How to program?

b) Wonder if it is better to use to chip act a Pulse Width Modulated 'digital to analogue converter'?

c) How to calculate value for RC filter (assume amplifier has high input impedance)?

Many years ago, I have programmed a hardware sound generator chip as part of a game machine. It has two registers for amplitude and 'frequency' control (band of 'white' noise). It worked very well. I once looked at the output using oscilloscope and it was square wave. I believe that it works, basically, using the above principles. Since I do not have the chip now, I cannot verify it. Now, I would like to duplicate its function using Arduino in software.

up vote 4 down vote accepted

I don't know that you need all that - just an Arduino and a piezo speaker and a pot if you want to play with the volume.

     void generateNoise(){
   unsigned long int newr;
   unsigned char lobit;
   unsigned char b31, b29, b25, b24;
   b31 = (reg & (1L << 31)) >> 31;
   b29 = (reg & (1L << 29)) >> 29;
   b25 = (reg & (1L << 25)) >> 25;
   b24 = (reg & (1L << 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.
  • After reading your answer, I did some searching and realize that your answer is based on, quoted from wikipedia, "pseudo-random binary sequence (PRBS) generated by a linear feedback shift register (LFSR)". Any pointers to non-pure-maths (and simple) information on how to choose the "polynomial" (bit 24, 25, 29 and 31 in your example) so as to achieve the white-noise property? – EEd Dec 28 '14 at 18:29
  • The en.wikipedia.org/wiki/Linear_feedback_shift_register article points to tables of good polynomials for different bit-length shift registers at xilinx.com/support/documentation/application_notes/xapp052.pdf . The main difference between a good polynomial and a less good one is whether the length of the cycle until it repeats is as long as possible (2^n-1 is the max). users.ece.cmu.edu/~koopman/lfsr/index.html points to a table with 67,108,864 equally good 32 bit alternatives. – Dave X Nov 24 '15 at 15:10
  • I think you need to edit unsigned long int newr; to be unsigned long int reg, newr; (and add const int speakerPin = 8;) – Greenonline Jun 22 at 0:12

Mike's answer uses a Fibonacci Linear Feedback Shift Register configuration, but the compactness Galois Linear Feedback Shift Register Configuration could be faster:

#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());
      }

}

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.