Hi,
I've been having problems with using the following section of code within a switch case.
The full code without comments is as follows.
#include <arduinoFFT.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
#define SAMPLES 128
#define SAMPLING_FREQUENCY 660
arduinoFFT FFT = arduinoFFT();
unsigned int samplingPeriod;
unsigned long microSeconds;
double vReal[SAMPLES];
double vImag[SAMPLES];
const int E4 = 280.41; //Avergae Piezo value for E4
const int B = 213.30; //Avergae Piezo value for B
const int G = 164.76; //Avergae Piezo value for D
const int D = 125.15; //Avergae Piezo value for D
const int A = 92.23; //Avergae Piezo value for A
const int E = 70.71; //Avergae Piezo value for E4
const int led_yellow = 9;
const int led_green = 10;
const int led_red = 11;
const int led_E4 = 6;
const int led_B = 5;
const int led_G = 4;
const int led_D = 3;
const int led_A = 2;
const int led_E = 1;
const int buttonPin = 0;
int buttonState;
int string = 0;
int prestate = 0;
double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
delay(2000);
display.clearDisplay();
pinMode(led_yellow, OUTPUT);
pinMode(led_green, OUTPUT);
pinMode(led_red, OUTPUT);
pinMode(led_E4, OUTPUT);
pinMode(led_B, OUTPUT);
pinMode(led_G, OUTPUT);
pinMode(led_D, OUTPUT);
pinMode(led_A, OUTPUT);
pinMode(led_E, OUTPUT);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH);
digitalWrite(led_E4, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_green, HIGH);
digitalWrite(led_red, HIGH);
digitalWrite(led_E4, HIGH);
digitalWrite(led_B, HIGH);
digitalWrite(led_G, HIGH);
digitalWrite(led_D, HIGH);
digitalWrite(led_A, HIGH);
digitalWrite(led_E, HIGH);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == LOW && prestate == 0) {
string++;
if (string > 5) {
string = 0;
}
prestate = 1;
} else if (buttonState == HIGH) {
prestate = 0;
}
switch (string) {
case 0:
display.clearDisplay();
samplingPeriod = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
digitalWrite(led_E4, HIGH);
digitalWrite(led_E, LOW);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("E String");
display.display();
delay(500);
for (int i = 0; i < SAMPLES; i++) {
microSeconds = micros();
vReal[i] = analogRead(A0);
vImag[i] = 0;
}
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
//peak = 70.71; //Avergae Piezo value for E
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("E String");
display.setTextSize(1);
display.setCursor(0, 32);
display.println(peak);
display.display();
delay(500);
if (((E - 5) <= peak) && (peak <= (E + 5))) {
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Tuned");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_green, LOW);
} else if ((E - 5) > peak) {
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Flat");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_yellow, LOW);
} else if ((E + 5) < peak) {
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Sharp");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_red, LOW);
}
delay(250);
digitalWrite(led_green, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_red, HIGH);
break;
case 1:
display.clearDisplay();
samplingPeriod = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
digitalWrite(led_E, HIGH);
digitalWrite(led_A, LOW);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("A String");
display.display();
delay(500);
for (int i = 0; i < SAMPLES; i++) {
microSeconds = micros();
vReal[i] = analogRead(A0);
vImag[i] = 0;
}
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
//peak = 92.23; //Avergae Piezo value for A
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("A String");
display.setTextSize(1);
display.setCursor(0, 32);
display.println(peak);
display.display();
delay(500);
if ((A - 5) <= peak && peak <= (A + 5)) {
// if sample is between +5hz or -5hz it is considered in tune
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Tuned");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_green, LOW);
} else if ((A - 5) > peak) {
// if sample is more than 5Hz lower it is condidered flat
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Flat");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_yellow, LOW);
} else if ((A + 5) < peak) {
// if sample is more than 5Hz higher it is condidered sharp
display.setTextSize(1);
display.setCursor(0, 16);
// Display Peak frequency
display.println("Sharp");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_red, LOW);
}
delay(250);
digitalWrite(led_green, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_red, HIGH);
break;
case 2:
display.clearDisplay();
samplingPeriod = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
digitalWrite(led_A, HIGH);
digitalWrite(led_D, LOW);
display.setTextSize(1);
display.setCursor(0, 0);
// Display static text
display.println("D String");
display.display();
delay(500);
for (int i = 0; i < SAMPLES; i++) {
microSeconds = micros();
vReal[i] = analogRead(A0);
vImag[i] = 0;
}
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
//peak = 125.15; //Avergae Piezo value for D
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("D String");
display.setTextSize(1);
display.setCursor(0, 32);
display.println(peak);
display.display();
delay(500);
if ((D - 5) <= peak && peak <= (D + 5)) {
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Tuned");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_green, LOW);
} else if ((D - 5) > peak) {
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Flat");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_yellow, LOW);
} else if ((D + 5) < peak) {
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Sharp");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_red, LOW);
}
delay(250);
digitalWrite(led_green, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_red, HIGH);
break;
case 3:
display.clearDisplay();
samplingPeriod = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
digitalWrite(led_D, HIGH);
digitalWrite(led_G, LOW);
display.setTextSize(1);
display.setCursor(0, 0);
// Display static text
display.println("G String");
display.display();
delay(500);
for (int i = 0; i < SAMPLES; i++) {
microSeconds = micros();
vReal[i] = analogRead(A0);
vImag[i] = 0;
}
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
//peak = 125.15; //Avergae Piezo value for G
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("G String");
display.setTextSize(1);
display.setCursor(0, 32);
display.println(peak);
display.display();
delay(500);
if ((G - 5) <= peak && peak <= (G + 5)) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("Tuned");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_green, LOW);
} else if ((G - 5) > peak) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("Flat");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_yellow, LOW);
} else if ((G + 5) < peak) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("Sharp");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_red, LOW);
}
delay(250);
digitalWrite(led_green, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_red, HIGH);
break;
case 4:
display.clearDisplay();
samplingPeriod = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
digitalWrite(led_G, HIGH);
digitalWrite(led_B, LOW);
display.setTextSize(1);
display.setCursor(0, 0);
// Display static text
display.println("B String");
display.display();
delay(500);
for (int i = 0; i < SAMPLES; i++) {
microSeconds = micros();
vReal[i] = analogRead(A0);
vImag[i] = 0;
}
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
//peak = 213.30; //Avergae Piezo value for B
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("B String");
display.setTextSize(1);
display.setCursor(0, 32);
display.println(peak);
display.display();
delay(500);
if ((B - 5) <= peak && peak <= (B + 5)) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("Tuned");
display.display();
delay(500);
display.clearDisplay();
} else if ((B - 5) > peak) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("Flat");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_yellow, LOW);
} else if ((B + 5) < peak) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("sharp");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_red, LOW);
}
delay(250);
digitalWrite(led_green, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_red, HIGH);
break;
case 5:
display.clearDisplay();
samplingPeriod = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
digitalWrite(led_B, HIGH);
digitalWrite(led_E4, LOW);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("E4 String");
display.display();
delay(500);
for (int i = 0; i < SAMPLES; i++) {
microSeconds = micros();
vReal[i] = analogRead(A0);
vImag[i] = 0;
}
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
//peak = 280.41; //Avergae Piezo value for E4
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("E4 String");
display.setTextSize(1);
display.setCursor(0, 32);
// Display Peak frequency
display.println(peak);
display.display();
delay(500);
if ((E4 - 5) <= peak && peak <= (E4 + 5)) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("Tuned");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_green, LOW);
} else if ((E4 - 5) > peak) {
display.setTextSize(1);
display.setCursor(0, 16);
display.println("Flat");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_yellow, LOW);
} else if ((E4 + 5) < peak) {
display.setTextSize(1);
display.setCursor(0, 16);
// Display static text
display.println("Sharp");
display.display();
delay(500);
display.clearDisplay();
digitalWrite(led_red, LOW);
}
delay(250);
digitalWrite(led_green, HIGH);
digitalWrite(led_yellow, HIGH);
digitalWrite(led_red, HIGH);
break;
}
}
The code is functional without the following lines
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
by replacing this declaring "peak" the average reading of the sensor for that string the code functions as intended.
peak = 125.15; //Avergae Piezo value for G
I have changed the compiler to display all warnings and no errors are returned only " Low memory available which I believe is the cause of the problem. For reference, I am using an Arduino UNO R3.
Any advice on fixing this would be greatly appreciated, many thanks.
Adam