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


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.


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;) Jun 22 '18 at 0:12
  • I'd really like to understand this anwser, but there is no explanation as to whats going on here. I don't know what the "reg" keyword is, nor what these bitwise operations are accomplishing, or why they aren't just defined, as they appear to be constants. On an Arduino, how is this better than using the "random" function with the values between the min and max frequency?
    – Danielle
    Feb 4 '19 at 22:03
  • Also the shift register reg must be (a) defined as either a global or as static and (b) assigned an non-zero value. I used global: uint32_t reg = 0xfeedfaceUL ; . The solution in the answer by Dave X works without changes.
    – 6v6gt
    May 12 '19 at 9:25

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:
   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());

  • 1
    be great for this to have more comments on this code to explain whats going on here for people still learning bitwise. I'm getting throw off because if "lfsr" is defined by the constant every time the function is called and then bitwised by another constant, how is this generating random numbers. why is the definition for LFSR_MASK so complex if its just a constant? please help?
    – Danielle
    Feb 4 '19 at 22:11
  • @dprogramz: In C, the static keyword in the declaration protects against just what you are worried about--the initialization with the constant only happens once on the initial declaration of the function, and the changing lfsr state is maintained through successive calls to the function. The bit-shifting definition of LFSR_MASK looks complicated, but it is easier to check, explain, change, and maintain than constants like 0b10100010100000000000000000000000UL The actual selection of the mask is more complicated, so see the refs.
    – Dave X
    May 13 '19 at 3:53
  • 1
    Thanks for the reply, that makes total sense now. I had a misunderstanding of the use to the Static keyword, but it's much more clearer now how it functions, thanks again!
    – Danielle
    May 20 '19 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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