Components and supplies
32x8 LED matrix display
Arduino Nano R3
Capacitor 100 nF
Resistor 10k ohm
Resistor 100k ohm
Resistor 4.75k ohm
Pushbutton switch 12mm
Tools and machines
Soldering iron (generic)
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#include <arduinoFFT.h> 22#include <MD_MAX72xx.h> 23#include <SPI.h> 24 25#define SAMPLES 64 //Must be a power of 2 26#define HARDWARE_TYPE MD_MAX72XX::FC16_HW // Set display type so that MD_MAX72xx library treets it properly 27#define MAX_DEVICES 4 // Total number display modules 28#define CLK_PIN 13 // Clock pin to communicate with display 29#define DATA_PIN 11 // Data pin to communicate with display 30#define CS_PIN 10 // Control pin to communicate with display 31#define xres 32 // Total number of columns in the display, must be <= SAMPLES/2 32#define yres 8 // Total number of rows in the display 33 34 35int MY_ARRAY[]={0, 128, 192, 224, 240, 248, 252, 254, 255}; // default = standard pattern 36int MY_MODE_1[]={0, 128, 192, 224, 240, 248, 252, 254, 255}; // standard pattern 37int MY_MODE_2[]={0, 128, 64, 32, 16, 8, 4, 2, 1}; // only peak pattern 38int MY_MODE_3[]={0, 128, 192, 160, 144, 136, 132, 130, 129}; // only peak + bottom point 39int MY_MODE_4[]={0, 128, 192, 160, 208, 232, 244, 250, 253}; // one gap in the top , 3rd light onwards 40int MY_MODE_5[]={0, 1, 3, 7, 15, 31, 63, 127, 255}; // standard pattern, mirrored vertically 41 42 43double vReal[SAMPLES]; 44double vImag[SAMPLES]; 45char data_avgs[xres]; 46 47int yvalue; 48int displaycolumn , displayvalue; 49int peaks[xres]; 50const int buttonPin = 5; // the number of the pushbutton pin 51int state = HIGH; // the current reading from the input pin 52int previousState = LOW; // the previous reading from the input pin 53int displaymode = 1; 54unsigned long lastDebounceTime = 0; // the last time the output pin was toggled 55unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers 56 57 58MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); // display object 59arduinoFFT FFT = arduinoFFT(); // FFT object 60 61 62 63void setup() { 64 65 ADCSRA = 0b11100101; // set ADC to free running mode and set pre-scalar to 32 (0xe5) 66 ADMUX = 0b00000000; // use pin A0 and external voltage reference 67 pinMode(buttonPin, INPUT); 68 mx.begin(); // initialize display 69 delay(50); // wait to get reference voltage stabilized 70} 71 72void loop() { 73 // ++ Sampling 74 for(int i=0; i<SAMPLES; i++) 75 { 76 while(!(ADCSRA & 0x10)); // wait for ADC to complete current conversion ie ADIF bit set 77 ADCSRA = 0b11110101 ; // clear ADIF bit so that ADC can do next operation (0xf5) 78 int value = ADC - 512 ; // Read from ADC and subtract DC offset caused value 79 vReal[i]= value/8; // Copy to bins after compressing 80 vImag[i] = 0; 81 } 82 // -- Sampling 83 84 85 // ++ FFT 86 FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD); 87 FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD); 88 FFT.ComplexToMagnitude(vReal, vImag, SAMPLES); 89 // -- FFT 90 91 92 // ++ re-arrange FFT result to match with no. of columns on display ( xres ) 93 int step = (SAMPLES/2)/xres; 94 int c=0; 95 for(int i=0; i<(SAMPLES/2); i+=step) 96 { 97 data_avgs[c] = 0; 98 for (int k=0 ; k< step ; k++) { 99 data_avgs[c] = data_avgs[c] + vReal[i+k]; 100 } 101 data_avgs[c] = data_avgs[c]/step; 102 c++; 103 } 104 // -- re-arrange FFT result to match with no. of columns on display ( xres ) 105 106 107 // ++ send to display according measured value 108 for(int i=0; i<xres; i++) 109 { 110 data_avgs[i] = constrain(data_avgs[i],0,80); // set max & min values for buckets 111 data_avgs[i] = map(data_avgs[i], 0, 80, 0, yres); // remap averaged values to yres 112 yvalue=data_avgs[i]; 113 114 peaks[i] = peaks[i]-1; // decay by one light 115 if (yvalue > peaks[i]) 116 peaks[i] = yvalue ; 117 yvalue = peaks[i]; 118 displayvalue=MY_ARRAY[yvalue]; 119 displaycolumn=31-i; 120 mx.setColumn(displaycolumn, displayvalue); // for left to right 121 } 122 // -- send to display according measured value 123 124 displayModeChange (); // check if button pressed to change display mode 125} 126 127void displayModeChange() { 128 int reading = digitalRead(buttonPin); 129 if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) // works only when pressed 130 131 { 132 133 switch (displaymode) { 134 case 1: // move from mode 1 to 2 135 displaymode = 2; 136 for (int i=0 ; i<=8 ; i++ ) { 137 MY_ARRAY[i]=MY_MODE_2[i]; 138 } 139 break; 140 case 2: // move from mode 2 to 3 141 displaymode = 3; 142 for (int i=0 ; i<=8 ; i++ ) { 143 MY_ARRAY[i]=MY_MODE_3[i]; 144 } 145 break; 146 case 3: // move from mode 3 to 4 147 displaymode = 4; 148 for (int i=0 ; i<=8 ; i++ ) { 149 MY_ARRAY[i]=MY_MODE_4[i]; 150 } 151 break; 152 case 4: // move from mode 4 to 5 153 displaymode = 5; 154 for (int i=0 ; i<=8 ; i++ ) { 155 MY_ARRAY[i]=MY_MODE_5[i]; 156 } 157 break; 158 case 5: // move from mode 5 to 1 159 displaymode = 1; 160 for (int i=0 ; i<=8 ; i++ ) { 161 MY_ARRAY[i]=MY_MODE_1[i]; 162 } 163 break; 164 } 165 166 lastDebounceTime = millis(); 167 } 168 previousState = reading; 169} 170
Source code
arduino
1/* 2Copyright (c) 2019 Shajeeb TM 3 4Permission is hereby granted, 5 free of charge, to any person obtaining a copy 6of this software and associated 7 documentation files (the "Software"), to deal 8in the Software without restriction, 9 including without limitation the rights 10to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell 12copies of the Software, and to permit persons 13 to whom the Software is 14furnished to do so, subject to the following conditions: 15The 16 above copyright notice and this permission notice shall be included in all 17copies 18 or substantial portions of the Software. 19THE SOFTWARE IS PROVIDED "AS IS", 20 WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21IMPLIED, INCLUDING BUT NOT LIMITED TO 22 THE WARRANTIES OF MERCHANTABILITY, 23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 IN NO EVENT SHALL THE 25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 26 OR OTHER 27LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 FROM, 29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 30 IN THE 31SOFTWARE. 32*/ 33 34#include <arduinoFFT.h> 35#include <MD_MAX72xx.h> 36#include 37 <SPI.h> 38 39#define SAMPLES 64 //Must be a power of 2 40#define HARDWARE_TYPE 41 MD_MAX72XX::FC16_HW // Set display type so that MD_MAX72xx library treets it 42 properly 43#define MAX_DEVICES 4 // Total number display modules 44#define 45 CLK_PIN 13 // Clock pin to communicate with display 46#define DATA_PIN 11 // 47 Data pin to communicate with display 48#define CS_PIN 10 // Control pin to 49 communicate with display 50#define xres 32 // Total number of columns in 51 the display, must be <= SAMPLES/2 52#define yres 8 // Total number of rows 53 in the display 54 55 56int MY_ARRAY[]={0, 128, 192, 224, 240, 248, 252, 254, 57 255}; // default = standard pattern 58int MY_MODE_1[]={0, 128, 192, 224, 240, 248, 59 252, 254, 255}; // standard pattern 60int MY_MODE_2[]={0, 128, 64, 32, 16, 8, 4, 61 2, 1}; // only peak pattern 62int MY_MODE_3[]={0, 128, 192, 160, 144, 136, 132, 63 130, 129}; // only peak + bottom point 64int MY_MODE_4[]={0, 128, 192, 160, 208, 65 232, 244, 250, 253}; // one gap in the top , 3rd light onwards 66int MY_MODE_5[]={0, 67 1, 3, 7, 15, 31, 63, 127, 255}; // standard pattern, mirrored vertically 68 69 70 71double vReal[SAMPLES]; 72double vImag[SAMPLES]; 73char data_avgs[xres]; 74 75int 76 yvalue; 77int displaycolumn , displayvalue; 78int peaks[xres]; 79const int buttonPin 80 = 5; // the number of the pushbutton pin 81int state = HIGH; // 82 the current reading from the input pin 83int previousState = LOW; // the previous 84 reading from the input pin 85int displaymode = 1; 86unsigned long lastDebounceTime 87 = 0; // the last time the output pin was toggled 88unsigned long debounceDelay 89 = 50; // the debounce time; increase if the output flickers 90 91 92MD_MAX72XX 93 mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); // display object 94arduinoFFT 95 FFT = arduinoFFT(); // FFT object 96 97 98 99void 100 setup() { 101 102 ADCSRA = 0b11100101; // set ADC to free running mode 103 and set pre-scalar to 32 (0xe5) 104 ADMUX = 0b00000000; // use pin A0 and 105 external voltage reference 106 pinMode(buttonPin, INPUT); 107 mx.begin(); 108 // initialize display 109 delay(50); // wait to get reference 110 voltage stabilized 111} 112 113void loop() { 114 // ++ Sampling 115 for(int 116 i=0; i<SAMPLES; i++) 117 { 118 while(!(ADCSRA & 0x10)); // wait for 119 ADC to complete current conversion ie ADIF bit set 120 ADCSRA = 0b11110101 121 ; // clear ADIF bit so that ADC can do next operation (0xf5) 122 int 123 value = ADC - 512 ; // Read from ADC and subtract DC offset caused 124 value 125 vReal[i]= value/8; // Copy to bins after compressing 126 127 vImag[i] = 0; 128 } 129 // -- Sampling 130 131 132 133 // ++ FFT 134 FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD); 135 136 FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD); 137 FFT.ComplexToMagnitude(vReal, 138 vImag, SAMPLES); 139 // -- FFT 140 141 142 // ++ re-arrange FFT result 143 to match with no. of columns on display ( xres ) 144 int step = (SAMPLES/2)/xres; 145 146 int c=0; 147 for(int i=0; i<(SAMPLES/2); i+=step) 148 { 149 data_avgs[c] 150 = 0; 151 for (int k=0 ; k< step ; k++) { 152 data_avgs[c] = data_avgs[c] 153 + vReal[i+k]; 154 } 155 data_avgs[c] = data_avgs[c]/step; 156 c++; 157 158 } 159 // -- re-arrange FFT result to match with no. of columns on display 160 ( xres ) 161 162 163 // ++ send to display according measured value 164 165 for(int i=0; i<xres; i++) 166 { 167 data_avgs[i] = constrain(data_avgs[i],0,80); 168 // set max & min values for buckets 169 data_avgs[i] = map(data_avgs[i], 170 0, 80, 0, yres); // remap averaged values to yres 171 yvalue=data_avgs[i]; 172 173 174 peaks[i] = peaks[i]-1; // decay by one light 175 if (yvalue > peaks[i]) 176 177 peaks[i] = yvalue ; 178 yvalue = peaks[i]; 179 displayvalue=MY_ARRAY[yvalue]; 180 181 displaycolumn=31-i; 182 mx.setColumn(displaycolumn, displayvalue); // 183 for left to right 184 } 185 // -- send to display according measured value 186 187 188 displayModeChange (); // check if button pressed to change 189 display mode 190} 191 192void displayModeChange() { 193 int reading = digitalRead(buttonPin); 194 195 if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) 196 // works only when pressed 197 198 { 199 200 switch (displaymode) { 201 case 202 1: // move from mode 1 to 2 203 displaymode = 2; 204 for (int 205 i=0 ; i<=8 ; i++ ) { 206 MY_ARRAY[i]=MY_MODE_2[i]; 207 } 208 break; 209 210 case 2: // move from mode 2 to 3 211 displaymode = 3; 212 for 213 (int i=0 ; i<=8 ; i++ ) { 214 MY_ARRAY[i]=MY_MODE_3[i]; 215 } 216 break; 217 218 case 3: // move from mode 3 to 4 219 displaymode = 4; 220 for 221 (int i=0 ; i<=8 ; i++ ) { 222 MY_ARRAY[i]=MY_MODE_4[i]; 223 } 224 break; 225 226 case 4: // move from mode 4 to 5 227 displaymode = 5; 228 for 229 (int i=0 ; i<=8 ; i++ ) { 230 MY_ARRAY[i]=MY_MODE_5[i]; 231 } 232 break; 233 234 case 5: // move from mode 5 to 1 235 displaymode = 1; 236 237 for (int i=0 ; i<=8 ; i++ ) { 238 MY_ARRAY[i]=MY_MODE_1[i]; 239 } 240 241 break; 242 } 243 244 lastDebounceTime = millis(); 245 } 246 previousState 247 = reading; 248} 249
Downloadable files
Schematic diagram - updated
Schematic diagram - updated
Comments
Only logged in users can leave comments