fft_led/main.c

135 lines
2.7 KiB
C

#include<util/delay.h>
#include<avr/io.h>
#include"fix_fft.h"
#include"avr_adc.h"
#include"light_ws2812_AVR/Light_WS2812/ws2812_config.h"
#include"light_ws2812_AVR/Light_WS2812/light_ws2812.h"
#include"main.h"
#define STARTADC ADCSRA |= (1<<ADSC)
#define PB_mic PB0
#define NOISE 100
#define SCALE_FACTOR 8
//resolution fft calc:
//https://3roam.com/fft-resolution-bandwidth-calculator/
//128 samples , 1kSPS = 7.8Hz
//interested in 0-10000 Hz
//
//128 bins a 7.8hz = 0...1000Hz
//
//we have 8 leds:
//bands 125hz/band -> 16 bins
//
//1-7.8 - ca 130hz
//2- 255hz
//3- 380
//4- 505
//5- 630
//6- 755
//7- 880
//8- 1kHz
//
const float log_scale = 64./log(64./SCALE_FACTOR + 1.);
int main (void)
{
int i,i2;
int colorb;
int colora;
int sum,avg;
char sample[64];
char im[64];
char buff[64];
char temp;
struct cRGB led_bar1[8];
//DDRB = (1<<mic);//would be setting output, default is input so no need for setting
setupADC();
OSCCAL = 250;//overclock!!! to 30MHz
for(i=0;i<8;i++)
{
led_bar1[i].r=0;
led_bar1[i].g=0;
led_bar1[i].b=0;
}
for(i=0;i<64;i++)
{
buff[i]=0;
}
while(1)
{
//######RECORD SAMPLES######
sum = 0;
for(i=0;i<64;i++)
{
STARTADC;
sample[i] = (ADCH-128); //read Analog value register 8bit center -128
//sample[i] = (sample[i] <= NOISE) ? 0 : (sample[i] - NOISE); //noise reduction
im[i]=0; //pseudo data for funciton
//
sum+=sample[i];//dc-bias
}
avg = sum/64;//calculate bias
for(i=0;i<64;i++)
{
sample[i]-=avg;//remove bias
}
fix_fftr(sample,6,0);//im[i] is always zero
//####Averaging Data####
//
for(i=0;i<64;i++)
{
sample[i] = sample[i] *SCALE_FACTOR;
sample[i] = (sample[i]*0.6 + buff[i]*0.5);
buff[i] = sample[i];
if(sample[i]<0) sample[i] = 0;
}
for(i=0;i<8;i++)
{
for(i2=1;i2<=4;i2++)
{
sample[i] = ((sample[i] + sample[i*6+i2])/2);
}
//avg written to sample[0..7]
//contains values scaled to int boundarys
//scale them to 0..256
//sample[i]= map(sample[i],0,50,0,255);
if(sample[i]<30)
{
led_bar1[i].r=0;
led_bar1[i].g=0;
led_bar1[i].b=sample[i];
}
else if(sample[i]<50)
{
led_bar1[i].r=0;
led_bar1[i].g=sample[i];
led_bar1[i].b=0;
}
else if(sample[i]<100)
{
led_bar1[i].r=sample[i];
led_bar1[i].g=0;
led_bar1[i].b=0;
}
}
ws2812_setleds(led_bar1,8);
}
return 0;
}
int map(int value, int old_min, int old_max,int new_min, int new_max)
{
return (new_max/old_max*value);
}