Showing posts with label experimental circuits. Show all posts
Showing posts with label experimental circuits. Show all posts

Friday, October 2, 2009

Goertzel Algorithm for PIC16F

Here's an experimental circuit(actual and simulation) of Goertzel algorithm using Microchip's PIC16F876A @20MHz crystal.

mathematical proof using MathCad:
initial simulation using Proteus ISIS:
code excerpt:
 #define SAMPLING_RATE    2003.21  
#define MAX_BINS 6
#define GOERTZEL_N 96
#define pi 3.141592654
#define threshold 2E4
#define true 1
#define false 0
const float freqs[MAX_BINS] = { 83, 110, 147, 196, 247, 330 };
unsigned int sample_count = 0;
unsigned char levels[ MAX_BINS];
unsigned char samples[GOERTZEL_N];
unsigned char sample_complete = false;
float prev1[ MAX_BINS ];
float prev2[ MAX_BINS ];
float magnitude[ MAX_BINS ];
float coeffs[ MAX_BINS ];
void interrupt isr() // Interrupt Handler
{
if(ADIF)// A/D conversion complete interrupt
{
samples[++sample_count] = ADRESH; // Read 8-bit ADC result
if (sample_count == GOERTZEL_N)
{
TMR0IE = 0; //disable TMR0 interrupt
sample_complete = true;
}
ADIF = 0; // clear the flag
}
if (TMR0IF) // Timer0 Interrupt
{
ADGO = 1; // initiate ADC conversion
TMR0 = 100; // reset the timer0 preset count
TMR0IF = 0; // clear the flag
}
}
void calc_coeffs() // calculate coefficients
{
unsigned int k, n;
for(n = 0; n < MAX_BINS; n++)
{
k = (unsigned int)(0.5 + (float)GOERTZEL_N * freqs[n] / SAMPLING_RATE);
coeffs[n] = 2.0 * cos(2.0 * pi * (float)k/GOERTZEL_N);
}
}
void main(void)
{
unsigned int i;
float val, max;
calc_coeffs();
// initializations
init_display(); // initialize LCD
init_adc(); // initialize PIC ADC module
init_timer(); // initialize Timer0
while(1)
{
if( sample_complete == true )
{
for(i = 0; i < MAX_BINS; i++) {
prev2[i] = prev1[i] = 0.0;
}
for(sample_count=0; sample_count < GOERTZEL_N; sample_count ++)
{
//GOERTZEL Algorithm
for ( i = 0; i < MAX_BINS; i++ )
{
val = coeffs[i] * prev1[i] - prev2[i] + (float)samples[sample_count];
prev2[i] = prev1[i];
prev1[i] = val;
}
}
sample_count = 0;
sample_complete = false;
TMR0IE = 1; // enable TMR0 interrupt, restart storing samples
max = threshold;
for ( i=0; i<MAX_BINS; i++ ) // compute the amplitudes/magnitudes
{
magnitude[i] = (prev1[i] * prev1[i]) + (prev2[i] * prev2[i]) - (coeffs[i] * prev1[i] * prev2[i]);
if (magnitude[i] > max) max = magnitude[i];
}
/*for ( i=0; i<MAX_BINS; i++ )
{
levels[i] = (unsigned char)(magnitude[i] / max);
}
display_spectrum();*/
}
}
}

then, build the actual circuit with this schematic:
the actual testing using a guitar(two strings pick):
another simulation (simple spectrum analyzer):

forum link: PIC-based Guitar Tuner

Wednesday, September 16, 2009

Chua's Circuit

Chua's circuit is a simple electronic circuit, developed by Leon O. Chua, that exhibits classic chaos theory behavior.

schematic:

Actual waveforms:





Simulations using Simetrix (SPICE simulator):