I have built a working guitar tuner. Ive got a max9814 mic > op amp > schmitt trigger > arduino.
It works like a charm! However, today it's not working. No OLED display working at all.
I checked my OLED, it works fine under different sketches. I checked my other hardware - the circuit produces real data (in serial monitor) when I upload different sketches.
For some reason, the OLED and hardware are not working together. It doesnt make sense! Everything works individually, but when put together in this specific combination, I get nothing on my little OLED.
could my arduino pin be pulled high? if so, why did it work a few hours ago and not now?
Im so confused! Any help is appreciated
(side note - I am aware that my tolerances for different notes are contradictory in different parts of the code. I left it like that for now on purpose)
It works like a charm! However, today it's not working. No OLED display working at all.
I checked my OLED, it works fine under different sketches. I checked my other hardware - the circuit produces real data (in serial monitor) when I upload different sketches.
For some reason, the OLED and hardware are not working together. It doesnt make sense! Everything works individually, but when put together in this specific combination, I get nothing on my little OLED.
could my arduino pin be pulled high? if so, why did it work a few hours ago and not now?
Im so confused! Any help is appreciated
(side note - I am aware that my tolerances for different notes are contradictory in different parts of the code. I left it like that for now on purpose)
Code:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(
SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET
);
class Note {
public:
const char* name;
float frequency;
float tolerance;
Note(const char* n, float f, float t) {
name = n;
frequency = f;
tolerance = t;
}
};
volatile unsigned long lastPulseTime = 0;
volatile unsigned long period = 0;
volatile bool newReading = false;
float freqHistory[5] = {0, 0, 0, 0, 0}; //collect 5 samples before displaying a measurement
int historyIndex = 0; // index
int historyCount = 0; // count++ , total amount
float freq = 0;
Note notes[] = {
{"E2", 82.41, 0.3},
{"A2", 110.00, 0.4},
{"D3", 146.83, 0.5},
{"G3", 196.00, 0.6},
{"B3", 246.94, 0.8},
{"E4", 329.63, 1.0}
};
void pulse() { // function to collect 5 measurements
unsigned long now = micros(); // start counting microseconds in variable "now" , which will be stored in lastPulseTime
if (lastPulseTime != 0) { // last pulse time = now from last execution
period = now - lastPulseTime;
newReading = true;
}
lastPulseTime = now;
}
float median5(float values[]) { // sort algorithm to sort five measurements
float temp[5];
for (int i = 0; i < 5; i++) {
temp[i] = values[i];
}
// Sort the five readings
for (int i = 0; i < 4; i++) {
for (int j = i + 1; j < 5; j++) {
if (temp[j] < temp[i]) {
float swap = temp[i];
temp[i] = temp[j];
temp[j] = swap;
}
}
}
return temp[2];
}
void setup() {
Serial.begin(9600);
Serial.println("Guitar tuner is alive!");
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED initialization failed!");
while (true) {
delay(100);
}
}
display.clearDisplay();
display.display();
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2), pulse, RISING); // pulse function becomes an interrupt - pin 2, function name, works on rising edge
}
void loop() {
if (newReading) {
noInterrupts(); // execute this when there AREN'T interrupts
unsigned long p = period;
newReading = false;
interrupts(); // now jump to this line when there ARE interrupts
if (p > 0) {
// if p > 0, accept the expected guitar-frequency range
if (p < 2850 || p > 15000) {
return;
}
float rawFreq = 1000000.0 / p; // divide to convert microseconds to cycles per second (there are a million microseconds in a second)
Serial.print("Raw: ");
Serial.println(rawFreq);
freqHistory[historyIndex] = rawFreq;
historyIndex++; // fill array "historyIndex" with rawFreq values & count++
if (historyIndex >= 5) {
historyIndex = 0;
}
if (historyCount < 5) {
historyCount++;
}
// Wait for five valid samples before filtering
if (historyCount < 5) {
return;
}
freq = median5(freqHistory); // median better than average!!!
Serial.print("Filtered: ");
Serial.println(freq);
const char* detectedNote = "---"; // pointer (???)
const char* tuningStatus = "";
float tolerance = 1.5; // WTF??? Do i need this or the tolerance listed in the class called notes???
for (int i = 0; i < 6; i++) {
float difference = freq - notes[i].frequency;
if (abs(difference) < 8) { // this section determines sharp, flat or in tune
detectedNote = notes[i].name;
if (difference > tolerance) {
tuningStatus = "#";
} else if (difference < -tolerance) {
tuningStatus = "b";
} else {
tuningStatus = "in tune";
}
break;
}
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 20);
display.println(detectedNote);
display.println(tuningStatus);
display.print(freq);
display.println(" Hz");
display.display();
}
}
delay(50);
}