Mirko Pavleski
Published © GPL3+

Arduino FFT Spectrum analyzer on VFD display GP1287

How to make an audio FFT spectrum analyzer on a 256x50 pixel VFD display.

BeginnerFull instructions provided2 hours931
Arduino FFT Spectrum analyzer on VFD display GP1287

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
GP1287 VFD Display
×1
Rotary Potentiometer, 10 kohm
Rotary Potentiometer, 10 kohm
×1
Resistor 10k ohm
×2
Capacitor 10 µF
×1
Digilent 5V 2.5A Switching Power Supply
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Schematics

Circuit diagram

...

Code

Arduino code

C/C++
.
#include "U8g2lib.h"
#include "fix_fft.h"
#include <SPI.h>
int buttonPin = 2; 
int oldButtonVal = 0;
// u8g2 set up, bar, line position L & R
#define LINEY 40
#define LINEXL 0
#define LINEXR 256

#define SAMPLES 128

#define AUDIO A0
 U8G2_GP1287AI_256X50_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8GLIB_ST7920_128X64_1X lcd(EN, RW, CS); // serial use, PSB = GND

char im[SAMPLES];
char data[SAMPLES];
int barht[SAMPLES];
int nPatterns = 2;
int lightPattern = 1;
void setup()
{
  u8g2.begin(); // inti u8g2
  u8g2.setContrast(25); 
  pinMode(2, INPUT_PULLUP);
}

void loop()
{
  static int i, j;
  int val;
  

  // get audio data
  for(i = 0; i < SAMPLES; i++)
  {
    val = analogRead(AUDIO)* 50; // 0-1023
    data[i] = (char)(val/4 - 128); // store as char
    im[i] = 0; // init all as 0
  }


  // run FFT
  fix_fft(data, im, 7, 0);

  // extract absolute value of data only, for 64 results
  for(i = 0; i < SAMPLES/2; i++)
  {
    barht[i] = (int)sqrt(data[i] * data[i] + im[i] * im[i]);
  }
  
  for(i = 0, j = 0; i < SAMPLES/2; i++, j += 2)
  {
    barht[i] = barht[j] + barht[j + 1];
  }
  
  // u8g2 barchart
  barchart(SAMPLES/4, barht); // plot SAMPLES / 4 = 32 as barchart gen cannot handle 128 bars
} 

// plot line and bar at position and height
void barchart(int n, int bh[])
{
  int i, s, w; // bars, spacing and width
  
  s = (LINEXR - LINEXL) / n;
  int buttonVal = digitalRead(buttonPin);
  if (buttonVal == LOW && oldButtonVal == HIGH) {// button has just been pressed
    lightPattern = lightPattern + 1;
  }
  if (lightPattern > nPatterns) lightPattern = 1;
  oldButtonVal = buttonVal;
  
  switch(lightPattern) {
    case 1:
     w = s / 2;
      break;
    case 2:
     w = s / 1;
  }
  
  u8g2.firstPage();
  do
  {
    u8g2.setFont(u8g2_font_6x12_tf);
    u8g2.drawStr(80, 7, "FFT Audio Spectrum");
    u8g2.drawLine(LINEXL, LINEY, LINEXR, LINEY);
    u8g2.drawStr(0, LINEY + 10, "0");
    u8g2.drawStr(50, LINEY + 10, "1k");
    u8g2.drawStr(110, LINEY + 10, "2k");
    u8g2.drawStr(164, LINEY + 10, "3k");
    u8g2.drawStr(220, LINEY + 10, "4k");
    u8g2.drawStr(240, LINEY + 10, "Hz");
    for(i = 0; i < n; i++)
    {
      u8g2.drawBox(LINEXL + s * i, LINEY - bh[i], w, bh[i] + 1); // u8glib doesn't accept box height of 0
    }
      
  }while(u8g2.nextPage()); 
}

Lib.

C/C++
.
No preview (download only).

Credits

Mirko Pavleski

Mirko Pavleski

120 projects • 1174 followers

Comments