Hi all, I' currently attempting to produce a TFT based spectrum visualiser, and have run into a small problem. I'm using an Adafruit 480x320 TFT (3.5" TFT 320x480 + Touchscreen Breakout Board w/MicroSD Socket (HXD8357D) | The Pi Hut) and am attempting to use some code based on the fix_fft library that I have slightly modified (Project#20 OLED Spectrum Analyzer using Fixed-point FFT; FHT on free-running mode - myscratchbooks).
So far I have got the actual spectrum working and displaying on the TFT display, however I'm having trouble making it actually fit onto the screen. Seeing as the original guide is using a much smaller OLED display, I understand that is why the visualiser is only appearing as small in the top left corner of my own TFT display. While attempting to fix this, I have managed to get as far as expanding the visualiser along the X axis, in order to fill the screen horizontally, by adding gaps in between each of the frequency bars.
However, when I try and adjust the "ylim" variable to expand the visualiser vertically, I run into some problems. Initially, when doubling the original ylim value from 60 to 120, the visualiser does expand vertically. But when I change the ylim variable to 180/240/300 etc the visualiser simply completely disappears. I cannot for the life of me figure out why this is happening.
I've attached the code I am using, any help would be very appreciated
#include "fix_fft.h" // library to perfom the fixed-point in-place Fast Fourier Transform
//#include <SPI.h> // SPI library
#include <Adafruit_GFX.h> // graphics library for OLED
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
#define WHITE 0xFFFF
#define BLACK 0x0000
// https://arduino.stackexchange.com/questions/699/how-do-i-know-the-sampling-frequency
// http://www.dellascolto.com/bitwise/2017/05/25/audio-spectrum-analyzer/
// For a 16 MHz Arduino the ADC clock , default (prescaler=128) fs=9615 Hz=> fmax =fs/2
// if FFT_N=128, (9615/2)/(128/2) = 75 hz per bin
// if FFT_N=256, (9615/2)/(256/2) = 37.6 hz per bin
const int FFT_N =256; // The Arduino Uno does not have enough memory to support 256 samples.
// many samples you will get a larger resolution for the results.
// set FFT_N to 256 by using an Arduino Mega 2560.
char im[FFT_N], data[FFT_N]; // variables for the FFT
char x = 0, ylim = 60; // variables for drawing the graphics
int i = 0, val,fall; //counters
int dropMax = 0;
int curMax;
int dat2[FFT_N];
void setup()
{
Serial.begin(9600); // serial comms for debuging
uint16_t identifier = tft.readID();
tft.begin(identifier);
tft.setRotation(1);
tft.setTextSize(1); // set OLED text size to 1 (1-6)
tft.setTextColor(WHITE); // set text color to white
tft.fillScreen(BLACK); // clear display
analogReference(DEFAULT); // Use default (5v) aref voltage.
};
void loop()
{
int mini=1024, maxi=0; // set minumum & maximum ADC values
for (i = 0; i < FFT_N; i++) { // take 128 or 256 point fft samples
val = analogRead(A15); // get audio from Analog 0
data[i] = val / 4 - 128; // the reason it is divided by 4 and subtracted by 128 is because the "data" is of type "char" which is an 8 bit variable (-128 to 127).
// So because analogRead returns 0-1023, dividing it by 4 gives you 0-255, subtracting it by 128 gives you -128-127.
// scale from 10 bit (0-1023) to 8 bit (0-255)
im[i] = 0; //
if(val>maxi) maxi=val; //capture maximum level
if(val<mini) mini=val;
//if(fall<mini) mini=fall; //capture minimum level
};
fix_fft(data, im, 8, 0); // perform the FFT on data for log2 (256) = 8
//fix_fft(data, im, 7, 0); // perform the FFT on data for log2 (128) = 7
// /* display graphic, un-comment here
// clear display
// result array is a bin.
// interessted in the absolute value of the transformation
// The number of bins you get is half the amount of samples spanning the frequency range from zero to half the sampling rate.
// the first half of array elements contain the real values after fix_fft
// In the end we get N/2 bins, each covering a frequency range of sampling_rate/N Hz.
for (i = 1; i < FFT_N/2; i++) { // full spectrum; here 4.8kHz bandwith, has 128 bins each 37.5Hz
// 1st bin = 37.5Hz, 2nd bin = 37.5*2 Hz etc.
// change for loop values for specific range of interested frequency
// ex: for (i = 1; i < 64; i++) // intersted in first 63 bins
int dat = sqrt(data[i] * data[i] + im[i] * im[i]); // filter out noise and hum
dat = (2-dat/60)*dat; // multiplication factor makes it look better with the microphone board (runs from 2 to 1)
if (dat>=dat2[i]) tft.drawLine(i*3 + x, ylim - dat2[i], i*3 + x, ylim - dat, WHITE);
else tft.drawLine(i*3 + x, ylim - dat2[i], i*3 + x, ylim - dat, BLACK);
dat2[i] = dat;
tft.drawLine(i*3 + x, ylim, i*3 + x, ylim - dat, WHITE); // if using FFT_N=256; draw bar graphics for freqs
};
tft.setCursor(0,0); // set cursor to top of screen
tft.print("->Spectrum Analyzer<-"); // print title to buffer
// */ display graphic, un-comment here
}; // end of loop()
FFT_v2.ino (8.1 KB)