- Get link
- X
- Other Apps
- Get link
- X
- Other Apps
Today I am make an Arduino
OLED Spectrum Analyzer its work with 0 to 3.3v Analog input. This is very
smooth and clear Visualization of audio frequencies. This is very important to
make an audio spectrum analyser for DVD Music player, IPod, MP3 player and
other Music player not only its look good it also represents any kind of music.
You can make a box to fit it and attached in car or anywhere you want but I
make just simple in breadboard.
Here is the complete video:
Note: This project is only for
simple audio device, a Real Spectrum Analyser devices are use in Microwave
signal, Radar Signal, Dish Antenna Signal, Cable frequencies Signal, etc. Do
not try to use for these proposes your Arduino will burn or crash and it cause permanently Damage.
In this blog you are learning about a Arduino Spectrum
Analyzer which follows:
>>SSD1306 Oled Display
>>Needed Parts
>>Libraries in we need to use
>>Super Easy Breadboard connection
>>Complete Code
SSD1306 Oled Display:
This very common and simple OLED Display for Arduino
that very less count of Pin to connect in arduino that called I2C two wire
interface the I2C stands for (I2C=IIC=Inter-Integrated Circuit) and OLED stands
for Organic Light-Emitting Diodes. The size of this oled display is 0.96 inch
that make it too much small and the total pixel is 128X64 px resolution you can
convert a pic to bitmap and program to show in this display. In 16X2 LCD
Display We need a backlight pin but in OLED this pin not required.
This is very simple to connect an OLED to Arduino Just
follow these wiring:
OLED Pins : Arduino Pins
Vin
| 5V //this is power Pin
GND
| GND //this is GND Pin
SCL
| A5 // this is I2C Pins
SDA
| A4 //this is I2C Pins
Varieties of Arduino Pin If you use:
Arduino Uno: SDA
(A4), SCL (A5)
Arduino Nano: SDA (A4), SCL (A5)
Arduino Leonardo: SDA (20), SCL (21)
Arduino MEGA: SDA (20), SCL (21)
Parts :
Arduino Nano or https://amzn.to/2RTdsLe
Arduino Uno https://amzn.to/3cD1hcy
128x68 I2C OLED Display https://amzn.to/35iybec
Jumper Wires https://amzn.to/3xuOaCn
Breadboard https://amzn.to/35e2Klr
Libraries Used in This Project:
If you are beginner for this project, you need to
download the Adafruit SSD1306 Master zip Library From here available in Github
and also need one more Adafruit GFX Library master.zip also available in
Github. Open Arduino IDE Software go to the sketch tab, then here click include
library and click Add Zip Library here you can add your downloaded library you
can also download and install from Manage Library Option just search these
library in this box.
And Now for This Project need to download FIX_FFT.h master zip from here fix_fft.git and nano_engine.h library here: nano_engine.h (if you are already installed ssd1306 then Nano engine is not necessary or if not then paste it in new tab with same name).
Breadboard Connection:
This is very simple connection for Arduino Nano and oled. Here I am using 10k variable for adjust the volume of Music it connected with A0 pin and Audio input plug for connect with audio devices.
Audio Input:
Make sure always check voltage and current level in
Analog Input of Arduino Board as Music or Sound Input, some amplifiers and
Sound Devices are too much high Current as Output, do not plug on it. This
Device needs only 3.8 to 4V and 40mA to 300mA Max voltage and current that come
from mini portable amplifier, IPod, Portable Speaker, Mp3 Players, etc.
// Copyright [2019] [colonelwatch] #include <fix_fft.h> // 8-bit FFT library modified for Arduino #include <ssd1306.h> // library for OLED #include <nano_engine.h> // To get this program to operate, the SDA and SCL pins must be reassigned to 0 and 2 respectively in the library header file // The file is located in libraries\ssd1306\src\intf\i2c\ssd1306_i2c_conf.h // Make sure to undo this if the library will be used again in the future // These are user-adjustable //#define LOG_OUTPUT // Uncomment to enable logarithmic output (exchanges absolute resoluton for more readable output; may require different below params) #define SAMPLING_FREQUENCY 15000 // Sampling frequency (Actual max measured frequency captured is half) #define TIME_FACTOR 3 // Smoothing factor (lower is more dynamic, higher is smoother) ranging from 1 to 10+ #define SCALE_FACTOR 12 // Direct scaling factor (raise for higher bars, lower for shorter bars) #ifdef LOG_OUTPUT const float log_scale = 64./log(64./SCALE_FACTOR + 1.); // Attempts to create an equivalent to SCALE_FACTOR for log function #endif const float coeff = 1./TIME_FACTOR; // Time smoothing coefficients (used to factor in previous data) const float anti_coeff = (TIME_FACTOR-1.)/TIME_FACTOR; const unsigned int sampling_period_us = round(1000000 * (2.0 / SAMPLING_FREQUENCY)); // Sampling period (doubled to account for overclock) int8_t data[64], buff[32]; // used to store FFT input/output and past data unsigned long microseconds; // used for timekeeping int summ, avg; // used for DC bias elimination NanoEngine<TILE_32x32_MONO> engine; // declares nanoengine void setup() { OSCCAL = 240; // Overclocks the MCU to around 30 MHz, set lower if this causes instability, raise if you can/want ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2)); // clear ADC prescaler bits ADCSRA |= bit (ADPS2); // sets ADC clock in excess of 10kHz ADCSRA |= bit (ADPS0); ssd1306_128x64_i2c_init(); // initializes OLED ssd1306_clearScreen(); // clears OLED engine.begin(); // inititalizes nanoengine }; void loop() { summ = 0; for (int i = 0; i < 64; i++) { microseconds = micros(); data[i] = ((analogRead(A0)) >> 2) - 128; // Fitting analogRead data (range:0 - 1023) to int8_t array (range:-128 - 127) summ += data[i]; while (micros() < (microseconds + sampling_period_us)) { // Timing out uC ADC to fulfill sampling frequency requirement } } // Eliminating remaining DC component (produces usable data in FFT bin #0, which is usually swamped by DC bias) avg = summ/64; for (int i = 0; i < 64; i++){ data[i] -= avg; } fix_fftr(data, 6, 0); // Performing real FFT // Time smoothing by user-determined factor and user-determined scaling for(int count = 0; count < 32; count++){ if(data[count] < 0) data[count] = 0; // Eliminating negative output of fix_fftr #ifdef LOG_OUTPUT else data[count] = log_scale*log((float)(data[count]+1)); // Logarithmic function equivalent to SCALING_FACTOR*log2(x+1) #else else data[count] *= SCALE_FACTOR; // Linear scaling up according to SCALE_FACTOR #endif data[count] = (float)buff[count] * anti_coeff + (float)data[count] * coeff; // Smoothing by factoring in past data buff[count] = data[count]; // Storing current output as next frame's past data if(data[count] > 63) data[count] = 63; // Capping output at screen height } // Output to SSD1306 using nanoengine canvas from library engine.refresh(); // Mark entire screen to be refreshed engine.canvas.clear(); // Clear canvas as previous data for(int i = 0; i < 8; i++){ engine.canvas.drawVLine(i*4,31-(data[i]+1),31); // Draw to canvas data for lower-leftest sector (FFT bins 0 - 7, lower half) } engine.canvas.blt(0,32); // Outputs canvas to OLED with an offset (x pixels, y pixels) engine.canvas.clear(); for(int i = 0; i < 8; i++){ if(data[i] > 31) engine.canvas.drawVLine(i*4,31-(data[i]-31),31); // Draw to canvas data for upper-leftest sector (FFT bins 0 - 7, upper half) } engine.canvas.blt(0,0); engine.canvas.clear(); for(int i = 8; i < 16; i++){ engine.canvas.drawVLine((i-8)*4,31-(data[i]+1),31); // FFT bins 8 - 15, lower half } engine.canvas.blt(32,32); engine.canvas.clear(); for(int i = 8; i < 16; i++){ if(data[i] > 31) engine.canvas.drawVLine((i-8)*4,31-(data[i]-31),31); // FFT bins 9 - 15, upper half } engine.canvas.blt(32,0); engine.canvas.clear(); for(int i = 16; i < 24; i++){ engine.canvas.drawVLine((i-16)*4,31-(data[i]+1),31); // FFT bins 16 - 23, lower half } engine.canvas.blt(64,32); engine.canvas.clear(); for(int i = 16; i < 24; i++){ if(data[i] > 31) engine.canvas.drawVLine((i-16)*4,31-(data[i]-31),31); // FFT bins 16 - 23, upper half } engine.canvas.blt(64,0); engine.canvas.clear(); for(int i = 24; i < 32; i++){ engine.canvas.drawVLine((i-24)*4,31-(data[i]+1),31); // FFT bins 24 - 31, lower half } engine.canvas.blt(96,32); engine.canvas.clear(); for(int i = 24; i < 32; i++){ if(data[i] > 31) engine.canvas.drawVLine((i-24)*4,31-(data[i]-31),31); // FFT bins 24 - 31, upper half } engine.canvas.blt(96,0); }
Now Enjoy Music!
- Get link
- X
- Other Apps
Comments
How would be the performance if Two oleds are used ?
ReplyDeleteNot much but change some code and divide for two OLEDs one for Left channel and second for right channel audio.
DeleteCan I use in Car Amplifier.....?
ReplyDeleteYes You can but make sure use resistor or check current or voltage of input audio.
Delete