banner

Monday, May 28, 2012

Implementing Discrete Fourier Transform in Atmega32 to make an audio spectrum analyzer


"All waveforms, no matter what you scribble or observe in the universe, are actually just the sum of simple sinusoids of different frequencies."

Hi,
I am just refreshing the basics of fourier transform. I am not an expert. Now I did a small audio spectrum analyzer(0 - 10KHz) on a 16x2 character lcd using an atmega32 microcontroller. Since I am refreshing from the basics, so I started with simple DFT. Also, I believe I should learn to walk before running. So I am not straight away going towads the FFT, which is nothing but the fastest and a bit complicated algorithm to find DFT.(I will try it later, as soon as possible)
        DFT is too slow compared to FFT. My lcd spectum analyzer doesn't need a great speed like that of an FFT, now if it is capable of providing a speed of around 30 frame/second, then it is more than enough for visualizing the audio spectrum on an LCD. But any way, in my case I can roughly achieve around 100 frames/second(any way it is too high refresh rate for a 16x2 lcd, not recommended also :-)). My audio sampling rate is 20KHz for 32 point DFT. Since the transform result is symmetric, I need to use only the first half, ie the first 16 results. So, it means, it can display upto 10KHz spectrum. So the resolution is 10KHz/16 = 625Hz.
         I have tried to improve the speed of DFT computation. If it is an N point DFT, it needs to find (N^2)/2 sin and cos values. For a 32 point DFT, it needs to find 512 sine and cosine. Before finding the sine and cosine, we need to find the angle(degree) which takes some processor time, so I implemented a lookup table for that. Next two tables are for sine and cosine. I didn't used any float or double since it takes more processing time in 8 bit avr, instead I implemented the sine and cosine lookups as 16bit intiger, by multiplying the real sine and cosine values by 10000. Then after finding the transform, finally I need to divide each result by 10000. This eliminates the need of using float or double and makes it more faster. Now I can calculate 120  32-point DFT operation/sec which is more than enough for my small spectrum analyzer.


LCD   
       Now, looking towards the LCD side, I utilized the custom character feature of LCD to make 8 stacked horizontal bars which takes the entire 64bytes of the LCD RAM for custom character bitmap. I ones seen a video is hackaday.com that a person used a 16x2 lcd in the similar manner for his spectrum analyser. So I also adopted the same idea of using the custom character for my spectrometer.

AUDIO INPUT
       Now one of the most important part of this stuff is the audio sampling via an eletret microphone. Special care must be given while designing the pre-amp for the mic. We need to set the zero-level of the ADC input to exactly half of the ADC reference voltage ie to 2.5v. Now it can have positive and negative swing on this 2.5v level according to the input audio signal but it should not cross the limit ie the amplifier gain should be properly adjusted to prevent clipping. I am using an LM324 op-amp for the mic pre-amp to meet the above conditions. 

PHOTO



CIRCUIT DIAGRAM



SOURCE CODE: (main.c)
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#define N 32
#include "lookup.h"
#define RS PD5
#define EN PD6
#define LCD_NIBBLE PORTC

void adc_init();
uint16_t adc_read();
void TRANSFORM();
void timer1_init();
void LCD_STROBE(void);
void lcd_data(unsigned char c);
void lcd_cmd(unsigned char c);
void lcd_clear(void);
void lcd_init();
void lcd_print(char *p, char l);
void lcd_fill_custom();

uint8_t lcd_buf1[16];
uint8_t lcd_buf2[16];
int32_t fx[N];
int32_t Fu[N/2][2];

void main()
{
    uint8_t mag;
    int i,j, temp_value;
    uint8_t temp_index;
    adc_init();
    lcd_init();
    lcd_fill_custom();
    lcd_print("DFT SPECTROMETER",1);
    lcd_print("0Hz - 10KHz(16)",2);
    _delay_ms(5000);
    lcd_clear();
    timer1_init();
    while(1) {
        TCNT1 = 0;
        TIFR |= 1<<OCF1A;
        for(i=0;i<N;i++) {
            while((TIFR & (1<<OCF1A)) == 0);
            fx[i] = ((int16_t)adc_read());
            TIFR |= 1<<OCF1A;
        }
        TRANSFORM();
        lcd_cmd(0xc0);
        for(i =1; i<N/2; i++) {
            if(Fu[i][0]<0)Fu[i][0]*=-1;
            if(Fu[i][1]<0)Fu[i][1]*=-1;
            mag = (uint8_t)(Fu[i][0] + Fu[i][1])/4;
            if((mag)>7) {
                lcd_buf1[i] = (mag) - 7 - 1;
                if(lcd_buf1[i] > 7)
                lcd_buf1[i] = 7;
                lcd_buf2[i] = 7;
            }
            else {
                lcd_buf1[i] = ' ';
                lcd_buf2[i] = mag;
            }
        }
        lcd_cmd(0x80);
        for(i=1;i<16;i++)
        lcd_data(lcd_buf1[i]);
        lcd_cmd(0xc0);
        for(i=1;i<16;i++)
        lcd_data(lcd_buf2[i]);
        
        
    }
}

void TRANSFORM()
{
    int16_t count,degree;
    uint8_t u,k;
    count = 0;
    for (u=0; u<N/2; u++) {
        for (k=0; k<N; k++) {
            degree = (uint16_t)pgm_read_byte_near(degree_lookup + count)*2;
            count++;
            Fu[u][0] +=  fx[k] * (int16_t)pgm_read_word_near(cos_lookup + degree);
            Fu[u][1] += -fx[k] * (int16_t)pgm_read_word_near(sin_lookup + degree);
        }
        Fu[u][0] /= N;
        Fu[u][0] /= 10000;
        Fu[u][1] /= N;
        Fu[u][1] /= 10000;
    }
}

void timer1_init()
{
    TCCR1B = (1<<WGM12)|(1<<CS10);
    OCR1A = 800;
}

void adc_init()
{
    ADMUX = 0b11000000;
    ADCSRA =0b10000010;
}

uint16_t adc_read()
{
    volatile uint16_t retl,reth;
    ADCSRA |= 1<<ADSC;
    while(!ADIF);
    ADCSRA |= 1<<ADIF;
    retl = ADCL;
    reth = ADCH;
    reth<<=8;
    reth|=retl;
    return reth;
}

void LCD_STROBE(void)
{
    PORTD |= (1 << EN);
    _delay_us(1);
    PORTD &= ~(1 << EN);
}

void lcd_data(unsigned char c)
{
    PORTD |= (1 << RS);
    _delay_us(50);
    LCD_NIBBLE = (c >> 4)|(LCD_NIBBLE&0xf0);
    LCD_STROBE();
    LCD_NIBBLE = (c)|(LCD_NIBBLE&0XF0);
    LCD_STROBE();
}

void lcd_cmd(unsigned char c)
{
    PORTD &= ~(1 << RS);
    _delay_us(50);
    LCD_NIBBLE = (c >> 4)|(LCD_NIBBLE&0xf0);
    LCD_STROBE();
    LCD_NIBBLE = (c)|(LCD_NIBBLE&0XF0);
    LCD_STROBE();
}

void lcd_clear(void)
{
    lcd_cmd(0x01);
    _delay_ms(5);
}

void lcd_init()
{
    DDRC = 0b00001111;
    DDRD |= (1 << RS)|(1 << EN);
    PORTC |= (1<<PC4);
    _delay_ms(15);
    lcd_cmd(0x30);
    _delay_ms(1);
    lcd_cmd(0x30);
    _delay_us(100);
    lcd_cmd(0x30);
    lcd_cmd(0x28);
    lcd_cmd(0x28);
    lcd_cmd(0x0c);
    lcd_clear();
    lcd_cmd(0x6);
}

void lcd_print(char *p, char l)
{
    if(l==1)lcd_cmd(0x80);
    else lcd_cmd(0xc0);
    while(*p)
    lcd_data(*p++);
}

void lcd_fill_custom()
{
    uint8_t i,j;
    i=0;j=0;
    lcd_cmd(64);
    for(i=1;i<=8;i++) {
        for(j=8;j>i;j--)
        lcd_data(0);
        for(j=i;j>0;j--)
        lcd_data(0xff);
    }
}
lookup.h
//LOOKUP TABLE//
#include <avr/pgmspace.h>

PROGMEM const int16_t cos_lookup[]= {
    10000,9998,9993,9986,9975,9961,9945,9925,9902,
    9876,9848,9816,9781,9743,9702,9659,9612,9563,
    9510,9455,9396,9335,9271,9205,9135,9063,8987,
    8910,8829,8746,8660,8571,8480,8386,8290,8191,
    8090,7986,7880,7771,7660,7547,7431,7313,7193,
    7071,6946,6819,6691,6560,6427,6293,6156,6018,
    5877,5735,5591,5446,5299,5150,5000,4848,4694,
    4539,4383,4226,4067,3907,3746,3583,3420,3255,
    3090,2923,2756,2588,2419,2249,2079,1908,1736,
    1564,1391,1218,1045,871,697,523,348,174,
    0,-174,-348,-523,-697,-871,-1045,-1218,-1391,
    -1564,-1736,-1908,-2079,-2249,-2419,-2588,-2756,-2923,
    -3090,-3255,-3420,-3583,-3746,-3907,-4067,-4226,-4383,
    -4539,-4694,-4848,-4999,-5150,-5299,-5446,-5591,-5735,
    -5877,-6018,-6156,-6293,-6427,-6560,-6691,-6819,-6946,
    -7071,-7193,-7313,-7431,-7547,-7660,-7771,-7880,-7986,
    -8090,-8191,-8290,-8386,-8480,-8571,-8660,-8746,-8829,
    -8910,-8987,-9063,-9135,-9205,-9271,-9335,-9396,-9455,
    -9510,-9563,-9612,-9659,-9702,-9743,-9781,-9816,-9848,
    -9876,-9902,-9925,-9945,-9961,-9975,-9986,-9993,-9998,
    -10000,-9998,-9993,-9986,-9975,-9961,-9945,-9925,-9902,
    -9876,-9848,-9816,-9781,-9743,-9702,-9659,-9612,-9563,
    -9510,-9455,-9396,-9335,-9271,-9205,-9135,-9063,-8987,
    -8910,-8829,-8746,-8660,-8571,-8480,-8386,-8290,-8191,
    -8090,-7986,-7880,-7771,-7660,-7547,-7431,-7313,-7193,
    -7071,-6946,-6819,-6691,-6560,-6427,-6293,-6156,-6018,
    -5877,-5735,-5591,-5446,-5299,-5150,-5000,-4848,-4694,
    -4539,-4383,-4226,-4067,-3907,-3746,-3583,-3420,-3255,
    -3090,-2923,-2756,-2588,-2419,-2249,-2079,-1908,-1736,
    -1564,-1391,-1218,-1045,-871,-697,-523,-348,-174,
    0,174,348,523,697,871,1045,1218,1391,
    1564,1736,1908,2079,2249,2419,2588,2756,2923,
    3090,3255,3420,3583,3746,3907,4067,4226,4383,
    4539,4694,4848,5000,5150,5299,5446,5591,5735,
    5877,6018,6156,6293,6427,6560,6691,6819,6946,
    7071,7193,7313,7431,7547,7660,7771,7880,7986,
    8090,8191,8290,8386,8480,8571,8660,8746,8829,
    8910,8987,9063,9135,9205,9271,9335,9396,9455,
    9510,9563,9612,9659,9702,9743,9781,9816,9848,
    9876,9902,9925,9945,9961,9975,9986,9993,9998
};

PROGMEM const int16_t sin_lookup[]= {
    0,174,348,523,697,871,1045,1218,1391,
    1564,1736,1908,2079,2249,2419,2588,2756,2923,
    3090,3255,3420,3583,3746,3907,4067,4226,4383,
    4539,4694,4848,4999,5150,5299,5446,5591,5735,
    5877,6018,6156,6293,6427,6560,6691,6819,6946,
    7071,7193,7313,7431,7547,7660,7771,7880,7986,
    8090,8191,8290,8386,8480,8571,8660,8746,8829,
    8910,8987,9063,9135,9205,9271,9335,9396,9455,
    9510,9563,9612,9659,9702,9743,9781,9816,9848,
    9876,9902,9925,9945,9961,9975,9986,9993,9998,
    10000,9998,9993,9986,9975,9961,9945,9925,9902,
    9876,9848,9816,9781,9743,9702,9659,9612,9563,
    9510,9455,9396,9335,9271,9205,9135,9063,8987,
    8910,8829,8746,8660,8571,8480,8386,8290,8191,
    8090,7986,7880,7771,7660,7547,7431,7313,7193,
    7071,6946,6819,6691,6560,6427,6293,6156,6018,
    5877,5735,5591,5446,5299,5150,4999,4848,4694,
    4539,4383,4226,4067,3907,3746,3583,3420,3255,
    3090,2923,2756,2588,2419,2249,2079,1908,1736,
    1564,1391,1218,1045,871,697,523,348,174,
    0,-174,-348,-523,-697,-871,-1045,-1218,-1391,
    -1564,-1736,-1908,-2079,-2249,-2419,-2588,-2756,-2923,
    -3090,-3255,-3420,-3583,-3746,-3907,-4067,-4226,-4383,
    -4539,-4694,-4848,-4999,-5150,-5299,-5446,-5591,-5735,
    -5877,-6018,-6156,-6293,-6427,-6560,-6691,-6819,-6946,
    -7071,-7193,-7313,-7431,-7547,-7660,-7771,-7880,-7986,
    -8090,-8191,-8290,-8386,-8480,-8571,-8660,-8746,-8829,
    -8910,-8987,-9063,-9135,-9205,-9271,-9335,-9396,-9455,
    -9510,-9563,-9612,-9659,-9702,-9743,-9781,-9816,-9848,
    -9876,-9902,-9925,-9945,-9961,-9975,-9986,-9993,-9998,
    -10000,-9998,-9993,-9986,-9975,-9961,-9945,-9925,-9902,
    -9876,-9848,-9816,-9781,-9743,-9702,-9659,-9612,-9563,
    -9510,-9455,-9396,-9335,-9271,-9205,-9135,-9063,-8987,
    -8910,-8829,-8746,-8660,-8571,-8480,-8386,-8290,-8191,
    -8090,-7986,-7880,-7771,-7660,-7547,-7431,-7313,-7193,
    -7071,-6946,-6819,-6691,-6560,-6427,-6293,-6156,-6018,
    -5877,-5735,-5591,-5446,-5299,-5150,-5000,-4848,-4694,
    -4539,-4383,-4226,-4067,-3907,-3746,-3583,-3420,-3255,
    -3090,-2923,-2756,-2588,-2419,-2249,-2079,-1908,-1736,
    -1564,-1391,-1218,-1045,-871,-697,-523,-348,-174
};

PROGMEM const uint8_t degree_lookup[]= {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,5,11,16,22,28,33,39,45,50,56,61,67,
    73,78,84,90,95,101,106,112,118,123,129,135,140,146,151,
    157,163,168,174,0,11,22,33,45,56,67,78,90,101,112,
    123,135,146,157,168,0,11,22,33,44,56,67,78,90,101,
    112,123,134,146,157,168,0,16,33,50,67,84,101,118,135,
    151,168,5,22,39,56,73,90,106,123,140,157,174,11,28,
    45,61,78,95,112,129,146,163,0,22,45,67,90,112,135,
    157,0,22,44,67,90,112,134,157,0,22,45,67,89,112,
    134,157,0,22,45,67,89,112,135,157,0,28,56,84,112,
    140,168,16,44,73,101,129,157,5,33,61,89,118,146,174,
    22,50,78,106,135,163,11,39,67,95,123,151,0,33,67,
    101,135,168,22,56,90,123,157,11,45,78,112,146,0,33,
    67,101,135,168,22,56,90,123,157,11,44,78,112,146,0,
    39,78,118,157,16,56,95,134,174,33,73,112,151,11,50,
    89,129,168,28,67,106,146,5,44,84,123,163,22,61,101,
    140,0,45,90,135,0,44,90,134,0,45,89,134,0,45,
    89,135,0,44,90,135,179,44,89,134,0,45,90,134,179,
    44,90,135,0,50,101,151,22,73,123,174,45,95,146,16,
    67,118,168,39,90,140,11,61,112,163,33,84,134,5,56,
    106,157,28,78,129,0,56,112,168,44,101,157,33,89,146,
    22,78,135,11,67,123,179,56,112,168,45,101,157,33,90,
    146,22,78,134,11,67,123,0,61,123,5,67,129,11,73,
    134,16,78,140,22,84,146,28,89,151,33,95,157,39,101,
    163,44,106,168,50,112,174,56,118,0,67,135,22,90,157,
    45,112,0,67,135,22,90,157,44,112,0,67,134,22,90,
    157,44,112,0,67,134,22,89,157,45,112,0,73,146,39,
    112,5,78,151,45,118,11,84,157,50,123,16,90,163,56,
    129,22,95,168,61,134,28,101,174,67,140,33,106,0,78,
    157,56,134,33,112,11,89,168,67,146,44,123,22,101,179,
    78,157,56,134,33,112,11,89,168,67,146,44,123,22,101,
    0,84,168,73,157,61,146,50,135,39,123,28,112,16,101,
    5,90,174,78,163,67,151,56,140,45,129,33,118,22,106,
    11,95
};

To compile it using avr-gcc in linux, check my previous post (atmega32 based wav player), there I have explained it in detail.

40 comments:

Jorge said...

nice project!
I would like to do almost the same thing for my Amp. :-)

REGISCRUZBR said...

Hi, nice project.

Can you tell how much percent of memory you used and how much still available?

Thanks

Laurens said...

Wouldn't it be faster if you multiply the sin and cos values by a power of 2, instead of 10000? That way multiplying and dividing is only a matter of shifting.

Rupert Hirst said...

nice project

Do you happen to have an Arduino PDE sketch for the code ?

Regards

Rupert

Vinod.S said...

@REGISCRUZBR:
memory used = 9710 bytes (FLASH) out of 32KB


@Laurens:
Yes it will become faster if we are using a value 2^x. But any way in my code, that division operations with 10000 is less in number.So the overall effect will be negligible compared to the total time taken for all other operations. But stil it is a great point which we should remember. Thanks for reminding me....

@Rupert Hirst:
Sorry I don't have it.. But I think already some one have ported an FFT library for arduino. So, you can have a google search for it. I think it is there...

Vinod.S said...

@REGISCRUZBR:
Actually I told it is 9710bytes with optimization -O3 in avr-gcc.
If I am using size optimization -Os then the size become just 3708 bytes. Both are working fine and couldn't feel any problem with the performance with using size optimization.....

openid said...

Why did you put a low pass filter (with a cutoff frequency of 2.821 kHz) between the opamp and the ADC? Are the values for R5 and C8 correct in the schematic? The video clearly showed it was sensitive to frequencies greater than 3k.

Vinod.S said...

Actually that mic pre-amp schematic is copied from my previous post, so I forgot to change the design there. But here, I didn't used it while testing... (We can use .01 uF and 1.5K here) I will update that schematic soon..

thientanvt said...

thank you , it is great
how about , if i do it by 16f877a ???

P/s : my english is not good .

حامد. د said...

Great Work, but a question: You choose to use Mega32 because of bigger SRAM size or it is possible to run the program on smaller AVRs like Mega8?

Vinod.S said...

@thientanvt:
In PICF877a, I believe there is no hardware multiplier. If I am right, then it will be little more slow in PIC16f877a.

@sحامد. د :
RAM will not be a problem here. Possible chance is a fash overflow. But still I think it will not overflow since atmega8 have 8KB flash.

Valentin Heroiu said...

Hello, great work! I have a few questions though. I am trying to compile the source code using AVR Studio (or ATMEL Studio 6.0), and I keep getting the message "main must return int" and the compilation fails. I am not acustomed with creating makefiles (that is why I use AVR studio, not avr-gcc) and I was hoping you could give me a few suggestions on how to solve my issue. Thank you

Vinod.S said...

If it is showing like that, then try using "int main" instead of "void main" and at last (at the END of main, just put "return 0" and try to compile it...

Alex said...

Greetings friend ... I'm really a rookie, I have a problem with the simulation please if you could help me in ISIS Proteus

obat jerawat said...

postingan yang anda buat bagus,,,,,,,,,

Anonymous said...

Can I replace the 16MHz crystal with the smaller one? Does it affect the calculation & result? Please reply..

Goebish said...

Hi, I just tried to build your circuit and I had a hard time figuring out why it wouldn't work...
Turns out that you swapped PD5 and PD6 on your schematics.
PD5 should go to E and PD6 should go to RS.

Thank you for another fun project on your blog :)

Vinod.S said...

Ooops...Actually it was a drawing mistake....;)..
Any way I will modify it in code now...

Goebish said...

No problem, I like to have to debug, it's not fun when something works on the first try ;)

I was wondering... How can I increase the microphone sensitivity, which resistor(s) should I fiddle with ?

avioIO IIST said...

hey vinod

i am a 3rd year btech student and i liked this project of yours very much..
please could you tell me the code which you have given above..in which compiler should i run it..because running it in C is not successful due to header files and libraries not available in C..
reply asap

Goebish said...

@avioIO IIST: you can use AVR Studio if you're running windows (full featured environment), or avr-gcc on linux (command line)

avioIO IIST said...

i have AVR studio 4..created a new source file..copied the code in it..created a new header file..copied the the lookup table and saved it with lookup.h ..... now when i compile the code it is giving no error, however when i buil it it is showing the following error
"avr-objcopy: 'instrue.elf': No such file"

instrue is the name of project and c file..

do i need to connect my hardware and MCU to build it??

and do i have to header files or there are some pre added files to the project??

avioIO IIST said...

please guys i need urgent help..just have a ay's time more

Goebish said...

Ok, now that you've got avr-gcc on your computer (AVR Studio installed it) it may be simpler to build the project using the command line.
First take the Makefile from the atmega32 based wav player project that's somewhere on this website then copy it next to your .c .h files and modify it to work with these sources.
Make sure that the "make" command is in your PATH environment variable.
In a DOS prompt cd to your source folder.
type "make" and it should build the .hex to flash onto your AVR chip.

Vinod.S said...

If you have avr-studio in your windows, then just copy the two files to the build environment (I am not much familiar with avr-studio gui app). Then a simple build will give the hex I guess... Just modify the compiler optimization to -O3, it will be there in build properties.

Now if you are using a command line, things are very easy as goebish said....
avr-gcc -mmcu=atmega32 -O3 -I./ -o project.out main.c
avr-objcopy -j .text -j .data -O ihex project.out project.hex

Now to burn it, the command depends on the tool you are using.... Almost all burning hardware will be there in the avr-dude list...
for example to burn the hex using usbasp programmer, u need to type
avrdude -c usbasp -p m32 -u -U flash:w:project.hex:i

in linux may be u need to create a udev rule for usbasp otherwise need to add a sudo infront of avr-dude . ie "sudo avrdude --------"

Just type

Goebish said...

You may also need to set your fuses correctly before burning the .hex, here's the command line for usbasp too:
avrdude -p m32 -c usbasp -U lfuse:w:0xef:m

avioIO IIST said...

guys..what i did is..
I have downloaded AVR studio 4
Started a new project..added a new file to the project under source files..copied the C code to it..
Then added lookup.h under libraries..
compiled and Build..

it gave the following error

Build started 21.10.2012 at 17:31:45
mmcu=atmega32a -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT instrue.o -MF dep/instrue.o.d -c ../instrue.c
/usr/bin/sh: -Wall: command not found
make: [instrue.o] Error 127 (ignored)
mmcu=atmega32a -Wl,-Map=instrue.map instrue.o -o instrue.elf
/usr/bin/sh: -Wl,-Map=instrue.map: command not found
make: [instrue.elf] Error 127 (ignored)
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature instrue.elf instrue.hex
avr-objcopy: 'instrue.elf': No such file
make: *** [instrue.hex] Error 1
Build failed with 1 errors and 0 warnings...


have no idea what it means..

and
@goebish : i am not able to find the make file..
and how to add it..please help

Goebish said...

Forget about AVR studio, I don't use it a lot neither (only when I need to debug with my AVR Dragon).
Use the command line (just make sure your environment variables are OK for avr-gcc).
You can do just as Vinod explained and you won't require a Makefile, or you can get the AVR wav player Makefile there: http://bit.ly/OTrtQt ,it works with this project too.

Matheus Torquato said...
This comment has been removed by the author.
Matheus Torquato said...

I can't find the post that you explain how to compile it into atmega32.

Can you explain it again or send us the page?

I really have no idea how to do it "/
how can i link my pc to the atmega?
Via arduino or something?

The BroadCaster said...

i can get my preamp to work i think... i should test it on oscilloscope

Андрей Каденчук said...
This comment has been removed by the author.
Manoj Perera said...

why is it in 0 - 10KHz why not in 0~20KHz or in 20Hz~20KHz its the audio rang? my e-mail is manoj_srilanaka@hotmail.com

Valdas Paskevicius said...

You are using external voltage reference for ADC, but adc_init() in source code sets this to internal 2.56V.

Ricardo Zolet said...

Hello, I would like to know how you calculated table values ​​of angles. I know sixteen frequency bands that form the spectrum and the amplitude of each frequency band is given by the sum of 32 words, then the table must have 512-degree terms. However, I did not understand how the values ​​were obtained.

monkeywearsprada said...

What IDE did you use? Was it CodeVision AVR?
thanks for your information. it's very useful for me

mohammad nabidoust said...

hex code sent for the projects tank

Titus said...

its an amazing project...well done sir

Сергей Баранов said...

Please send me the project for ISIS. e-Mail: megalooser@gmail.com
i cant run it on proteus

Андрей Каденчук said...
This comment has been removed by the author.

Post a Comment

SHARE IT on FB