#include <LiquidCrystal_I2C.h>
#include "fix_fft.h"
#define LCHAN A1
int load;
int decaytest = 1;
int x = 0, y = 0, z = 0;
int i = 0, val;
char im[64], data[64];
char data_avgs[32];
float peaks[32];
const int channels = 1;
const int gain = 3;
const int yres = 8;
// VU METER CHARACTERS
byte v1[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F};
byte v2[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F};
byte v3[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F};
byte v4[8] = {0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F};
byte v5[8] = {0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
byte v6[8] = {0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
byte v7[8] = {0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
byte v8[8] = {0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
lcd.init();
lcd.backlight();
lcd.createChar(1, v1);
lcd.createChar(2, v2);
lcd.createChar(3, v3);
lcd.createChar(4, v4);
lcd.createChar(5, v5);
lcd.createChar(6, v6);
lcd.createChar(7, v7);
lcd.createChar(8, v8);
lcd.setCursor(0, 0);
lcd.print(" FM 91.9 MHz ");
}
void loop()
{
mono();
}
void vu()
{
for (i = 0; i < 64; i++)
{
val = ((analogRead(LCHAN) / 4 ) - 128); // chose how to interpret the data from analog in
data[i] = val;
im[i] = 0;
};
fix_fft(data, im, 6, 0); // Send the data through fft
// get the absolute value of the values in the array, so we're only dealing with positive numbers
for (i = 0; i < 32 ; i++)
{
data[i] = sqrt(data[i] * data[i] + im[i] * im[i]);
}
// todo: average as many or as little dynamically based on yres
for (i = 0; i < 32; i++)
{
data_avgs[i] = (data[i]);// + data[i*2+1]);// + data[i*3 + 2]);// + data[i*4 + 3]); // add 3 samples to be averaged, use 4 when yres < 16
data_avgs[i] = constrain(data_avgs[i], 0, 9 - gain); //data samples * range (0-9) = 9
data_avgs[i] = map(data_avgs[i], 0, 9 - gain, 0, yres); // remap averaged values
}
} // end Vu
void decay(int decayrate)
{
// reduce the values of the last peaks by 1
if (decaytest == decayrate)
{
for (x = 0; x < 32; x++)
{
peaks[x] = peaks[x] - 1; // subtract 1 from each column peaks
decaytest = 0;
}
}
decaytest++;
}
void mono()
{
vu();
decay(1);
// repeat for each column of the display horizontal resolution
for (x = 1; x < 15; x++)
{
y = data_avgs[x]; // get current column value
z = peaks[x];
if (y > z)
{
peaks[x] = y;
}
y = peaks[x];
if (y <= 8)
{
lcd.setCursor(x, 1); // draw second row
if (y == 0)
{
lcd.print(" "); // save a glyph
}
else
{
lcd.write(y);
}
}
else
{
lcd.setCursor(x, 1);
lcd.write(8);
} // end display
} // end xres
}