random problem with guitar tuner project

Thread Starter

arduinolego611

Joined Jan 23, 2022
76
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)
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);
}
 
Top