Three-speaker Chladni Patterns
From Mech
Team Members
- Christopher Chow (Mechanical Engineering, Class of 2010)
- Anup Tapase (Electrical Engineering, Class of 2010)
- Lingyu Xie (Electrical Engineering, Class of 2009)
Overview
Theory
Mechanical Design
Primary Components
Base Box
Three-Speaker Base
Chladni Plate
Electrical Design
Code
#include <18f4520.h> #DEVICE ADC=8 // set ADC to 8 bit accuracy #use delay(clock=40000000) #include "flex_lcd.c" //must include in order to output to LCD #use spi(DO = PIN_A3, CLK = PIN_A2, ENABLE = PIN_A1, BITS = 16, MASTER, ENABLE_ACTIVE = 0, MSB_FIRST, IDLE = 1) int16 freq,target_freq; int16 target_freq_reg, old_target_freq_reg; int8 knob_val=0; void check_input(); void main() { int16 ct; target_freq_reg=2000+16384; // initialize starting frequency of speakers to 298 Hz (non-resonant) old_target_freq_reg=2000+16384; // set old target freq variable to equal target freq setup_adc_ports(AN0); // Set up analog input port as pin A0 setup_adc(ADC_CLOCK_INTERNAL); lcd_init(); // Always call this first. //INITIAL FREQUENCY FOR AD9833 spi_xfer(0b0010000100000000); //format command, output sine wave spi_xfer(target_freq_reg); //1st set of bits, 14 LSB, this range is good enough for our use //send the target frequency register value (freq + 16384) to AD9833 chip spi_xfer(0b0100000000000000); //2nd set of bits, 14 MSB spi_xfer(0b1100000000000000); //phase register: 0 phase shift (B0-B13) spi_xfer(0b0000000000000000); //unformat freq=(float).149011 * (float)(target_freq_reg - 16384); //convert the target freq register value to actual freq value target_freq=freq; // initialize target freq as current freq printf(lcd_putc,"\fFreq: %Lu\n",freq); //display current freq printf(lcd_putc,"Target: %Lu\n",target_freq); //display target freq while(TRUE) { check_input(); //check the knob input to see if target frequency has changed if(old_target_freq_reg != target_freq_reg) //go in here if target freq changed after calling check_input() { if(target_freq_reg > old_target_freq_reg) //sweep up to target freq { for(ct=old_target_freq_reg; ct<=target_freq_reg; ct=ct+7) { spi_xfer(0b0010000100000000); spi_xfer(ct); //set AD9833 frequency to ct, which is freq register that is sweeping up by 7 each time loop is run spi_xfer(0b0100000000000000); spi_xfer(0b1100000000000000); spi_xfer(0b0000000000000000); freq=(float).149011 * (float)(ct - 16384); target_freq=(float).149011 * (float)(target_freq_reg - 16384); printf(lcd_putc,"\fFreq: %Lu\n",freq); //display current freq printf(lcd_putc,"Target: %Lu\n",target_freq); //display target freq check_input(); //see if knob position has selected different target freq delay_ms(90); //delay to allow speakers to play freq for 90 ms + 10 ms (in check_input() function) } old_target_freq_reg = target_freq_reg; //reached target freq, set both variables equal until knob position changed } else if(target_freq_reg < old_target_freq_reg) //sweep down to target freq { for(ct=old_target_freq_reg; ct>=target_freq_reg; ct=ct-7) { spi_xfer(0b0010000100000000); spi_xfer(ct); //set AD9833 frequency to ct, which is freq register that is sweeping down by 7 each time loop is run spi_xfer(0b0100000000000000); spi_xfer(0b1100000000000000); spi_xfer(0b0000000000000000); freq=(float).149011 * (float)(ct - 16384); //convert current freq register value (ct) to frequency value target_freq=(float).149011 * (float)(target_freq_reg - 16384); //convert target freq register to target freq value printf(lcd_putc,"\fFreq: %Lu\n",freq); //display current freq printf(lcd_putc,"Target: %Lu\n",target_freq); //display target freq check_input(); //see if knob position has selected different target freq delay_ms(90); //delay to allow speakers to play freq for 90 ms + 10 ms (in check_input() function) } old_target_freq_reg = target_freq_reg; //reached target freq, set both variables equal until knob position changed } } } } void check_input() //check knob position to see if target freq has changed { set_adc_channel(0); // Set the analog input channel to 0 delay_us(10); // wait 10uS for ADC to settle to a newly selected input knob_val = read_adc(); // Read in knob user input to tell speakers what resonant freq to sweep up to delay_ms(10); // delay 10 ms to allow reading of analog input //check and set target_freq_reg according to knob position (0-255 values split into 8 discrete levels) if (knob_val >= 0 && knob_val< 22 ) target_freq_reg = 2281+16384; //339 Hz else if(knob_val >= 22 && knob_val< 54) target_freq_reg = 3308+16384; //493 Hz else if(knob_val >= 54 && knob_val< 86) target_freq_reg = 3778+16384; //563 Hz else if(knob_val >= 86 && knob_val< 117) target_freq_reg = 3986+16384; //594 Hz else if(knob_val >= 117 && knob_val< 147) target_freq_reg = 4207+16384; //627 Hz else if(knob_val >= 147 && knob_val< 178) target_freq_reg = 4362+16384; //650 Hz else if(knob_val >= 178 && knob_val< 209) target_freq_reg = 5006+16384; //746 Hz else if(knob_val >= 209 && knob_val< 239) target_freq_reg = 5308+16384; //791 Hz else if(knob_val >= 239 && knob_val< 255) target_freq_reg = 5872+16384; //875 Hz }