Attempting frequency detection but serial monitor only displays 0 or infinity <Solved>

EDIT: i fixed the problem, the guitar hookup wasnt seated all the way haha. Its always the little things. Thanks for the replies and suggestions!

I am modifying the following instructable https://www.instructables.com/Arduino-Guitar-Tuner/
but instead of having LEDs light up to show if the guitar is in tune or not, I am trying to make an LCD display the frequency. I'm having problems with troubleshooting, when I try different notes nothing is happening with the LCD so I turned on the serial monitor to see what values I was getting and it's just displaying 0 when I first turn the arduino on and then inf forever. Here is my code and there is also a circuit diagram and sample code in the instructable.

// Arduino Frequency Detection

//data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0; //this keeps time and will send vals to store in timer
int timer[10]; //storage for timing
int slope[10]; //storage for slope
unsigned int totalTimer; //int for calculating period
unsigned int period; //storage for period of waveform
byte index = 0; //current storage index
float frequency; //storage for freq calcs
int maxSlope = 0; //calculate max slope
int newSlope = 0; //storage for current slope data

//match variables
byte noMatch = 0;
byte slopeTol = 3; //slope tolerance
int timerTol = 10; //timer tolerance

//amp detection variables
unsigned int ampTimer = 0;
byte maxAmp = 0;
byte checkMaxAmp;
byte ampThreshold = 10; //threshold for signal noise

//LCD display setup
#include <LiquidCrystal.h>
const int LCD_D7 = 2;
const int LCD_D6 = 3;
const int LCD_D5 = 4;
const int LCD_D4 = 5;
const int LCD_EN = 11;
const int LCD_RS = 13;
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
const int LCD_WIDTH = 16;
const int LCD_HEIGHT = 2;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Frequency(Hz)");
  // LCD
  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  lcd.print("Turning on...");
  delay (2500);
  lcd.clear();

  cli();
  // continuous sampling of analog pin 0 @ 38.5kHz
  // clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;
  ADMUX |= (1 << REFS0); //set reference voltage
  ADMUX |= (1 << ADLAR); //left aligning the ADC value allows one to read the highest 8 bits from ADCH register only

  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler-16mHz/32=50
  ADCSRA |= (1 << ADATE); //enable auto trigger
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //enable ADC
  ADCSRA |= (1 << ADSC); //start ADC measurements

  sei();
}

ISR(ADC_vect) {//when new ADC value ready
  PORTB &= B11101111; //set pin 12 low (can change if using other pin)
  prevData = newData; //store prev value
  newData = ADCH; //get new value from A0
  if (prevData < 127 && newData >= 127) { //if increasing and crossing midpoint
    newSlope = newData - prevData; //calculate slope
    if (abs(newSlope - maxSlope) < slopeTol) { //if slopes are equal record new data and reset time
      slope [index] = newSlope;
      timer[index] = time;
      time = 0;
      if (index == 0) { //new max slope just got reset
        PORTB |= B00010000; //set pin 12 high
        noMatch = 0;
        index++; //increment index
      }
      else if (abs(timer[0] - timer[index]) < timerTol && abs(slope[0] - newSlope) < slopeTol) { //if timer duration and slopes match
        //sum timer vals
        totalTimer = 0;
        for (byte i = 0; i < index; i++) {
          totalTimer += timer[i];
        }
        period = totalTimer; //set period
        timer[0] = timer[index];
        slope[0] = slope[index];
        index = 1;
        PORTB |= B00010000; //set pin 12 high
        noMatch = 0;
      }
      else { //crossing midpoint but not match
        index++;
        if (index > 9) {
          reset();
        }
      }
    }
    else if (newSlope > maxSlope) {
      maxSlope = newSlope;
      time = 0;
      noMatch = 0;
      index = 0;
    }
    else {
      noMatch++;
      if (noMatch > 9) {
        reset();
      }
    }
  }
  time++; //increment timer at rate of 38.5 kHz
  ampTimer++; //increment amplitude timer
  if (abs(127 - ADCH) > maxAmp) {
    maxAmp = abs(127 - ADCH);
  }
  if (ampTimer == 1000) {
    ampTimer = 0;
    checkMaxAmp = maxAmp;
    maxAmp = 0;
  }
}

void reset() { //clean some variables
  index = 0;
  noMatch = 0;
  maxSlope = 0;
}

// Determine correct freq and display
void frequencyCheck() {
  // low E
  if (frequency > 83.5 && frequency < 92) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" low E string too high.");
    delay (2000);
    lcd.clear();
  }
  if (frequency < 82) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" low E string too low.");
    delay (2000);
    lcd.clear();
  }
  if (frequency <= 83 && frequency >= 92) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" low E string in tune.");
    delay (2000);
    lcd.clear();
  }
  // A
  if (frequency > 110.5 && frequency < 128) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" A string too high.");
    delay (2000);
    lcd.clear();
  }
  if (frequency < 109.5 && frequency > 93) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" A string too low.");
    delay (2000);
    lcd.clear();
  }
  if (frequency <= 110 && frequency >= 109) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" A string in tune.");
    delay (2000);
    lcd.clear();
  }
  // D
  if (frequency > 147.5 && frequency < 170) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" D string too high.");
    delay (2000);
    lcd.clear();
  }
  if (frequency < 145 && frequency > 128.5) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" D string too low.");
    delay (2000);
    lcd.clear();
  }
  if (frequency <= 146 && frequency >= 147) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" D string in tune.");
    delay (2000);
    lcd.clear();
  }
  // G
  if (frequency > 197 && frequency < 222) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" G string too high.");
    delay (2000);
    lcd.clear();
  }
  if (frequency < 196 && frequency > 171) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" G string too low.");
    delay (2000);
    lcd.clear();
  }
  if (frequency <= 197 && frequency >= 196) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" G string in tune.");
    delay (2000);
    lcd.clear();
  }
  // B
  if (frequency > 248 && frequency < 288) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" B string too high.");
    delay (2000);
    lcd.clear();
  }
  if (frequency < 247 && frequency > 223) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" B string too low.");
    delay (2000);
    lcd.clear();
  }
  if (frequency <= 248 && frequency >= 247) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" B string in tune.");
    delay (2000);
    lcd.clear();
  }
  // high E
  if (frequency > 331.5 && frequency < 400) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" high E string too high.");
    delay (2000);
    lcd.clear();
  }
  if (frequency < 329 && frequency > 289) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" high E string too low.");
    delay (2000);
    lcd.clear();
  }
  if (frequency <= 331 && frequency >= 330) {
    lcd.print("Frequency=");
    lcd.print(frequency);
    lcd.print(" high E string in tune.");
    delay (2000);
    lcd.clear();
  }
}
void loop() {
  // put your main code here, to run repeatedly:
  if (checkMaxAmp > ampThreshold) {
    frequency = 38462 / float(period); //calc frequency timer rate/period
  }
  //stringCheck();
  frequencyCheck();
  Serial.println(frequency);
  delay(100);
}

I don't have a guitar, so I used a function generator to test the code you showed us.
I don't have an LCD display either.

Observing the frequency displayed on the serial monitor, the code is working correctly.

Here are some oscilloscope traces and serial monitor results:

With a 200Hz 4V peak to peak signal:

and with a lower signal level, 250Hz 500mVpk-pk:

For an experiment, I replaced all the lcd.print() statements with Serial.print(), in order to display the LCD results on the serial monitor.

Here are the results with a swept frequency:

I think that the problem you are having is hardware related, rather than software related.

How are you getting a signal from the guitar to the Arduino analogue input?

Hi, @baryonyx-xlsx
Welcome to the forum.

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Can you post some images of your project?
So we can see your component layout.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Hey thanks for the reply. We are following the instructable I linked exactly, the only thing I changed was a bit of code since we replaced all the LEDs with an LCD. So its just an audio jack that we are plugging an electric guitar into and that audio jack is going to the scope probe.

With anything you don't write, and def with anything from a source like instructables, it is highly advised to…

... slavishly duplicate the existing project, software, hardware and power supply and get that working in perfect agreement with the original before…

… making what is not just a little tweak to something.

If you did not do that, and your ability to read code is not at a fairly high level of skill, you will be making your goal harder to achieve.

So, did you build it as you found it first? After that, did you use an example program for the display you have, one you did not alter, to familiarize yourself with it, and verify correct wiring and software?

a7

Did you build the op amp circuit, as described in the instructable?

I did not build it as I first found it, but since the only change made was replacing LEDs with an LCD and the op amp and scope probe circuit was untouched, I figured any problems with the op amp reading frequencies would come from problems with the guitar hookup or the op amp circuit itself, not the LCD, which works fine when asked to display a "starting" message. Another user tested my code with an oscilliscope and it works as intended which makes me think again it is an op amp problem but I will try replicating the instructable exactly and see if that changes anything.

Yes, op amp circuit is as described in the instructable.