Components and supplies
Resistor 100k ohm
Capacitor 100 nF
Through Hole Resistor, 22 kohm
Arduino Nano R3
Alphanumeric LCD, 16 x 2
Through Hole Resistor, 1 kohm
Project description
Code
Source code
arduino
1/* 2Copyright (c) 2019 Shajeeb TM 3 4Permission is hereby granted, free of charge, to any person obtaining a copy 5of this software and associated documentation files (the "Software"), to deal 6in the Software without restriction, including without limitation the rights 7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the Software is 9furnished to do so, subject to the following conditions: 10The above copyright notice and this permission notice shall be included in all 11copies or substantial portions of the Software. 12THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18SOFTWARE. 19*/ 20 21/* 22Changed by ThomAce 23*/ 24 25#include <arduinoFFT.h> 26#include <LiquidCrystal.h> 27 28#define SAMPLES 64 //Must be a power of 2 29 30#define xres 16 // Total number of columns in the display, must be <= SAMPLES/2 31#define yres 8 // Total number of rows in the display 32 33LiquidCrystal lcd(11, 10, 7, 6, 5, 4); // pins to LCD 34 35//LCD Bars. 36byte v1[] = { 37 B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111 38}; 39byte v2[] = { 40 B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111 41}; 42byte v3[] = { 43 B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111 44}; 45byte v4[] = { 46 B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111 47}; 48byte v5[] = { 49 B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111 50}; 51byte v6[] = { 52 B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111 53}; 54byte v7[] = { 55 B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111 56}; 57byte v8[] = { 58 B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 59}; 60byte v9[] = { 61 B00000, B00000, B00000, B00000, B00000, B00000, B00000, B00000 62}; 63 64int MY_ARRAY[]={0, 1, 2, 3, 4, 5, 6, 7, 8}; 65 66double vReal[SAMPLES]; 67double vImag[SAMPLES]; 68char data_avgs[xres]; 69 70double vRReal[SAMPLES]; 71double vRImag[SAMPLES]; 72char Rdata_avgs[xres]; 73 74int yvalue; 75int displaycolumn , displayvalue; 76int peaks[xres]; 77int Rpeaks[xres]; 78 79int steps = (SAMPLES / 2) / xres; 80 81unsigned long lastDebounceTime = 0; // the last time the output pin was toggled 82unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers 83 84arduinoFFT FFT = arduinoFFT(); // FFT object 85 86void setup() 87{ 88 ADCSRA = 0b11100101; // set ADC to free running mode and set pre-scalar to 32 (0xe5) 89 ADMUX = 0b00000000; // use pin A0 and external voltage reference 90 91 lcd.createChar(1, v1); 92 lcd.createChar(2, v2); 93 lcd.createChar(3, v3); 94 lcd.createChar(4, v4); 95 lcd.createChar(5, v5); 96 lcd.createChar(6, v6); 97 lcd.createChar(7, v7); 98 lcd.createChar(8, v8); 99 lcd.createChar(9, v9); 100 lcd.begin(xres, 2); 101 lcd.clear(); 102 103 String loading = "LOADING.. [0%]"; 104 int percentage = 0; 105 106 for (int i = 0; i < xres; i++){ 107 lcd.setCursor(0, 0); 108 109 percentage = (int) ((i / (float)xres) * 100); 110 111 if (i < (xres / 3) && percentage % 2 == 0) 112 { 113 loading = "LOADING. [" + String(percentage) + "%]"; 114 lcd.print(loading); 115 } 116 else if (i < ((xres / 3) * 2) && percentage % 2 == 0) 117 { 118 loading = "LOADING..[" + String(percentage) + "%]"; 119 lcd.print(loading); 120 } 121 else if (percentage % 2 == 0) 122 { 123 loading = "LOADING...[" + String(percentage) + "%]"; 124 lcd.print(loading); 125 } 126 127 for (int load = 0; load <= i; load++) 128 { 129 lcd.setCursor(load, 1); 130 lcd.write(8); 131 } 132 133 delay(50); 134 } 135 136 lcd.setCursor(0, 0); 137 loading = "LOADING...[100%]"; 138 lcd.print(loading); 139 140 delay(500); // wait to get reference voltage stabilized and show the progress a bit longer time :) 141 lcd.clear(); 142} 143 144 145void Sampling(byte ADCBit, bool Right) 146{ 147 ADMUX = ADCBit;//0b00000000; 148 int value = 0; 149 // ++ Sampling 150 for(int i = 0; i < SAMPLES; i++) 151 { 152 while(!(ADCSRA & 0x10)); // wait for ADC to complete current conversion ie ADIF bit set 153 ADCSRA = 0b11110101 ; // clear ADIF bit so that ADC can do next operation (0xf5) 154 155 value = ADC - 128; //- 256;// - 512 ; // Read from ADC and subtract DC offset caused value 156 157 if (Right) 158 { 159 vRReal[i]= value / 8; // Copy to bins after compressing 160 vRImag[i] = 0; 161 } 162 else 163 { 164 vReal[i]= value / 8; // Copy to bins after compressing 165 vImag[i] = 0; 166 } 167 } 168 // -- Sampling 169} 170 171void loop() { 172 Sampling(0b00000001, false); //Left channel on pin 0 173 Sampling(0b00000000, true); //Right channel on pin 0 174 175 // ++ FFT 176 FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD); 177 FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD); 178 FFT.ComplexToMagnitude(vReal, vImag, SAMPLES); 179 // -- FFT 180 181 // ++ FFT 182 FFT.Windowing(vRReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD); 183 FFT.Compute(vRReal, vRImag, SAMPLES, FFT_FORWARD); 184 FFT.ComplexToMagnitude(vRReal, vRImag, SAMPLES); 185 // -- FFT 186 187 // ++ re-arrange FFT result to match with no. of columns on display ( xres ) 188 Display(0, ReArrange(steps, data_avgs, vReal), peaks); 189 Display(1, ReArrange(steps, Rdata_avgs, vRReal), Rpeaks); 190} 191 192char * ReArrange(int steps, char * dataAvgs, double * realValues) 193{ 194 int c = 0; 195 196 for(int i = 0; i < (SAMPLES / 2); i += steps) 197 { 198 dataAvgs[c] = 0; 199 200 for (int k = 0 ; k < steps ; k++) 201 { 202 dataAvgs[c] = dataAvgs[c] + realValues[i + k]; 203 } 204 205 dataAvgs[c] = dataAvgs[c] / steps; 206 c++; 207 } 208 209 return dataAvgs; 210} 211 212void Display(int line, char * data_avgs, int * data_peaks) 213{ 214 displaycolumn = 0; 215 displayvalue = 0; 216 yvalue = 0; 217 218 // ++ send to display according measured value 219 for(int i = 0; i < xres; i++) 220 { 221 data_avgs[i] = constrain(data_avgs[i], 0, 80); // set max & min values for buckets 222 data_avgs[i] = map(data_avgs[i], 0, 80, 0, yres); // remap averaged values to yres 223 yvalue = data_avgs[i]; 224 225 data_peaks[i] = data_peaks[i] - 1; // decay by one light 226 227 if (yvalue > data_peaks[i]) 228 data_peaks[i] = yvalue ; 229 230 yvalue = data_peaks[i]; 231 232 lcd.setCursor(displaycolumn, line); 233 if (MY_ARRAY[yvalue] == 0) 234 lcd.write(" "); 235 else 236 lcd.write(MY_ARRAY[yvalue]); 237 238 displaycolumn++; 239 } 240}
Source code
arduino
1/* 2Copyright (c) 2019 Shajeeb TM 3 4Permission is hereby granted, free of charge, to any person obtaining a copy 5of this software and associated documentation files (the "Software"), to deal 6in the Software without restriction, including without limitation the rights 7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the Software is 9furnished to do so, subject to the following conditions: 10The above copyright notice and this permission notice shall be included in all 11copies or substantial portions of the Software. 12THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18SOFTWARE. 19*/ 20 21/* 22Changed by ThomAce 23*/ 24 25#include <arduinoFFT.h> 26#include <LiquidCrystal.h> 27 28#define SAMPLES 64 //Must be a power of 2 29 30#define xres 16 // Total number of columns in the display, must be <= SAMPLES/2 31#define yres 8 // Total number of rows in the display 32 33LiquidCrystal lcd(11, 10, 7, 6, 5, 4); // pins to LCD 34 35//LCD Bars. 36byte v1[] = { 37 B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111 38}; 39byte v2[] = { 40 B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111 41}; 42byte v3[] = { 43 B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111 44}; 45byte v4[] = { 46 B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111 47}; 48byte v5[] = { 49 B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111 50}; 51byte v6[] = { 52 B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111 53}; 54byte v7[] = { 55 B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111 56}; 57byte v8[] = { 58 B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 59}; 60byte v9[] = { 61 B00000, B00000, B00000, B00000, B00000, B00000, B00000, B00000 62}; 63 64int MY_ARRAY[]={0, 1, 2, 3, 4, 5, 6, 7, 8}; 65 66double vReal[SAMPLES]; 67double vImag[SAMPLES]; 68char data_avgs[xres]; 69 70double vRReal[SAMPLES]; 71double vRImag[SAMPLES]; 72char Rdata_avgs[xres]; 73 74int yvalue; 75int displaycolumn , displayvalue; 76int peaks[xres]; 77int Rpeaks[xres]; 78 79int steps = (SAMPLES / 2) / xres; 80 81unsigned long lastDebounceTime = 0; // the last time the output pin was toggled 82unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers 83 84arduinoFFT FFT = arduinoFFT(); // FFT object 85 86void setup() 87{ 88 ADCSRA = 0b11100101; // set ADC to free running mode and set pre-scalar to 32 (0xe5) 89 ADMUX = 0b00000000; // use pin A0 and external voltage reference 90 91 lcd.createChar(1, v1); 92 lcd.createChar(2, v2); 93 lcd.createChar(3, v3); 94 lcd.createChar(4, v4); 95 lcd.createChar(5, v5); 96 lcd.createChar(6, v6); 97 lcd.createChar(7, v7); 98 lcd.createChar(8, v8); 99 lcd.createChar(9, v9); 100 lcd.begin(xres, 2); 101 lcd.clear(); 102 103 String loading = "LOADING.. [0%]"; 104 int percentage = 0; 105 106 for (int i = 0; i < xres; i++){ 107 lcd.setCursor(0, 0); 108 109 percentage = (int) ((i / (float)xres) * 100); 110 111 if (i < (xres / 3) && percentage % 2 == 0) 112 { 113 loading = "LOADING. [" + String(percentage) + "%]"; 114 lcd.print(loading); 115 } 116 else if (i < ((xres / 3) * 2) && percentage % 2 == 0) 117 { 118 loading = "LOADING..[" + String(percentage) + "%]"; 119 lcd.print(loading); 120 } 121 else if (percentage % 2 == 0) 122 { 123 loading = "LOADING...[" + String(percentage) + "%]"; 124 lcd.print(loading); 125 } 126 127 for (int load = 0; load <= i; load++) 128 { 129 lcd.setCursor(load, 1); 130 lcd.write(8); 131 } 132 133 delay(50); 134 } 135 136 lcd.setCursor(0, 0); 137 loading = "LOADING...[100%]"; 138 lcd.print(loading); 139 140 delay(500); // wait to get reference voltage stabilized and show the progress a bit longer time :) 141 lcd.clear(); 142} 143 144 145void Sampling(byte ADCBit, bool Right) 146{ 147 ADMUX = ADCBit;//0b00000000; 148 int value = 0; 149 // ++ Sampling 150 for(int i = 0; i < SAMPLES; i++) 151 { 152 while(!(ADCSRA & 0x10)); // wait for ADC to complete current conversion ie ADIF bit set 153 ADCSRA = 0b11110101 ; // clear ADIF bit so that ADC can do next operation (0xf5) 154 155 value = ADC - 128; //- 256;// - 512 ; // Read from ADC and subtract DC offset caused value 156 157 if (Right) 158 { 159 vRReal[i]= value / 8; // Copy to bins after compressing 160 vRImag[i] = 0; 161 } 162 else 163 { 164 vReal[i]= value / 8; // Copy to bins after compressing 165 vImag[i] = 0; 166 } 167 } 168 // -- Sampling 169} 170 171void loop() { 172 Sampling(0b00000001, false); //Left channel on pin 0 173 Sampling(0b00000000, true); //Right channel on pin 0 174 175 // ++ FFT 176 FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD); 177 FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD); 178 FFT.ComplexToMagnitude(vReal, vImag, SAMPLES); 179 // -- FFT 180 181 // ++ FFT 182 FFT.Windowing(vRReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD); 183 FFT.Compute(vRReal, vRImag, SAMPLES, FFT_FORWARD); 184 FFT.ComplexToMagnitude(vRReal, vRImag, SAMPLES); 185 // -- FFT 186 187 // ++ re-arrange FFT result to match with no. of columns on display ( xres ) 188 Display(0, ReArrange(steps, data_avgs, vReal), peaks); 189 Display(1, ReArrange(steps, Rdata_avgs, vRReal), Rpeaks); 190} 191 192char * ReArrange(int steps, char * dataAvgs, double * realValues) 193{ 194 int c = 0; 195 196 for(int i = 0; i < (SAMPLES / 2); i += steps) 197 { 198 dataAvgs[c] = 0; 199 200 for (int k = 0 ; k < steps ; k++) 201 { 202 dataAvgs[c] = dataAvgs[c] + realValues[i + k]; 203 } 204 205 dataAvgs[c] = dataAvgs[c] / steps; 206 c++; 207 } 208 209 return dataAvgs; 210} 211 212void Display(int line, char * data_avgs, int * data_peaks) 213{ 214 displaycolumn = 0; 215 displayvalue = 0; 216 yvalue = 0; 217 218 // ++ send to display according measured value 219 for(int i = 0; i < xres; i++) 220 { 221 data_avgs[i] = constrain(data_avgs[i], 0, 80); // set max & min values for buckets 222 data_avgs[i] = map(data_avgs[i], 0, 80, 0, yres); // remap averaged values to yres 223 yvalue = data_avgs[i]; 224 225 data_peaks[i] = data_peaks[i] - 1; // decay by one light 226 227 if (yvalue > data_peaks[i]) 228 data_peaks[i] = yvalue ; 229 230 yvalue = data_peaks[i]; 231 232 lcd.setCursor(displaycolumn, line); 233 if (MY_ARRAY[yvalue] == 0) 234 lcd.write(" "); 235 else 236 lcd.write(MY_ARRAY[yvalue]); 237 238 displaycolumn++; 239 } 240}
Downloadable files
Wireing diagram
Wireing diagram
Comments
Only logged in users can leave comments
ThomAce
0 Followers
•0 Projects
Table of contents
Intro
5
0