finally started to think about adding color selection to the brain-wave table this morning while flying in to houston. going to the maker faire.
Code: Select all
// trippy rgb brain machine
//
// this software implements a sound and light machine, similar to mitch altman's brain
// machine as described in volume 10 of make: magazine.
//
// the functional differences between this implementation and mitch's are that this
// software attempts to synthesize a sine wave-like audio output and while the red leds
// blink at the intended entrainment frequencies green and blue leds fade in and out.
// admittedly the green and blue channels are more for the benefit of an observer than
// to enhance the entrainment function. i, personally, do find that the visuals are
// enhanced by the blue and green lights.
//
// this software will run on an arduino or any mega168 running at either 8MHz or 16MHz
// with the following connections
//
// PB1 - base frequency audio channel
// PB2 - offset frequency audio channel
// PC0,PC4 - red leds
// PC1,PC2 - green leds
// PC3,PC5 - blue leds
//
// it will also run on an attiny2313, specifically a modified adafruit industries
// minipov 3 kit clocked at either 8MHz or 16MHz. the connections to the tiny2313
// should be
//
// PB3 - base frequency audio channel
// PB4 - offset frequency audio channel
// PB0,PB5 - red leds
// PB1,PB6 - green leds
// PB2,PB7 - blue leds
//
// note that these connections differ from mitch's version most significantly in that
// one of the audio channels is moved from PB2 to PB4 so that it can be connected to
// OC1B output of timer 1. the led outputs can be moved around freely by modifying
// symbols defined in the source code. the green and blue outputs, as previously
// mentioned are primarily cosmetic and need not really be connected. by defining
// the symbols RRED and LRED as PB0 and PB1 one can convert an existing slm with the
// only hardware modification being the movement of one audio channel.
//
// so, uh, how's it work?
//
// all of the outputs are generated in the timer 1 overflow interrupt service routine.
// the only things that happen in the main program are hardware initialization, setting
// up the brainwave sequence, then looping waiting for the sequence to end while
// periodically changing the brightness of the green and blue leds, and finally stopping
// timer 1, turning off all the outputs and putting the mcu to sleep.
//
// timer 1 overflows every 512 ticks of the mcu's clock. at 8MHz this results in an
// interrupt frequency of 15625Hz, at 16MHz it's 31250Hz. the advantage of running at
// 16MHz is that the audio pwm frequency will be well above the range of human hearing.
// at 8MHz one must rely on a low pass filter, cheap headphones and high frequency
// hearing loss. (in 1970 i used to obliterate the rest of the world by getting home
// from school and lying on the floor with a speaker cabinet on either side of my head
// and band of gypsys cranked to about 7.5, so i'm halfway there.)
//
// anyway, at each timer interrupt a pulse is output on OC1A with a width proportional
// to the desired amplitude of the base frequency sine wave. the offset frequency is
// output as a pulse on OC1B. for each channel the integer part of a 24 bit fixed
// point, (8 bit integer, 16 bit fraction), phase accumulator is used as an index into
// a 256 byte table of 8 bit amplitudes. for each entry, i, in the amplitude table,
// sinetab[i] = 127 + sin(i * pi / 128) * 127.
//
// for each frequency to be output a phase step is calculated at compile time. this
// step is the change in phase for the frequency at each interrupt and is calculated
// by multiplying the frequency by the size of the sine wave table and dividing by
// the interrupt frequency. step sizes for the offset frequencies are stored in a
// lookup table and the step size for the base frequency is stored in a separate
// variable. (declaring the base frequency to be a constant breaks the code, so don't
// try it.)
//
// the flash rate of the leds is controlled by comparing the phases of the offset and
// base waveforms. the sign of the result of offset phase - base phase determines the
// state of the leds.
//
// color fading is done with seven bit pwm. so the interrupt frequency of 15625Hz
// is divided by 128 for a pwm frequency of ~120Hz. at every interrupt a counter is
// compared to 128. when it reaches 128 it is reset to zero, the current values of
// all colors are copied to locations to be used for comparisons during the current
// pwm period, and all the leds are turned on.
//
// also, at every interrupt, the stored color values are compared to the counter and
// when they are equal the corresponding leds are turned off. the counter is then
// incremented.
//