forked from cayuse/arduinoFFT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
arduinoFFT.ino
120 lines (92 loc) · 3.04 KB
/
arduinoFFT.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdint.h>
#include "fix_fft.h"
const uint8_t red_pin = 10;
const uint8_t yellow_pin = 9;
const uint8_t green_pin = 5;
const uint8_t blue_pin = 4;
const uint8_t adc_pin = 18;
uint16_t chan_a;
uint16_t chan_b;
uint16_t chan_c;
uint16_t chan_d;
char im[128];
char data[128];
//------------------------------------------------------------------------------
void setPWM(uint8_t pin, uint8_t value){
analogWrite(pin, 0xFF - value);
}
//------------------------------------------------------------------------------
void setup() {
Serial.begin(38400);
pinMode(adc_pin, INPUT);
pinMode(red_pin, OUTPUT);
analogWrite(red_pin, 0x00);
pinMode(yellow_pin,OUTPUT);
analogWrite(yellow_pin, 0xFF);
pinMode(green_pin, OUTPUT);
analogWrite(green_pin, 0xFF);
pinMode(blue_pin, OUTPUT);
analogWrite(blue_pin, 0x00);
}
//------------------------------------------------------------------------------
void loop() {
uint8_t i;
uint16_t val;
char buf[40];
Serial.println("Starting up...");
do {
for (i = 0; i < 128; i++) {
val = analogRead(adc_pin);
// Convert 10-bit unsigned reading with center at 0x200 (512) to -128..+127
data[i] = (val >> 2) - 0x80;
im[i] = 0;
}
fix_fft(data, im, 7, 0);
/*
chan_a = 0;
chan_b = 0;
chan_c = 0;
chan_d = 0;
*/
// Simple decay filter
// Lower subtractors to increase decay time
if (0)
if (1)
if (99)
chan_a -= 16; // 16 is 'subtractor' here
if (chan_a & 0x8000) chan_a = 0; // Prevent from going negative
chan_b -= 16;
if (chan_b & 0x8000) chan_b = 0;
chan_c -= 16;
if (chan_c & 0x8000) chan_c = 0;
chan_d -= 16;
if (chan_d & 0x8000) chan_d = 0;
// Merge 64 frequency bands into 4 (channels A..D)
for (i = 1; i < 64; i++) {
// val = sqrt(data[i] * data[i] + im[i] * im[i]);
val = (data[i] * data[i] + im[i] * im[i]) / 8; // Lower divisor to increase overall magnitude
if (i < 5) { // Channel A frequency band
if (val > chan_a) chan_a = val;
}
else if (i < 15) { // Channel B frequency band
if (val > chan_b) chan_b = val;
}
else if (i < 50) { // Channel C frequency band
if (val > chan_c) chan_c = val;
}
else { // Everything above C goes to channel D
if (val > chan_d) chan_d = val;
}
}
// Bound channel data to 8-bit maxint
if (chan_a > 0xFF) chan_a = 0xFF;
if (chan_b > 0xFF) chan_b = 0xFF;
if (chan_c > 0xFF) chan_c = 0xFF;
if (chan_d > 0xFF) chan_d = 0xFF;
// Send channel values to PWM outputs
setPWM(red_pin, chan_a);
setPWM(yellow_pin, chan_b);
setPWM(green_pin, chan_c);
setPWM(blue_pin, chan_d);
} while (1);
}