Reading A Frequency

Hi there! I've been working on this project for a little while now and can seem to get it to work... I can't determine if my problem is in my wiring or my code... I normally would give up at this point but it's a pretty important project... Anyhow, I'll add what I'm using for wiring and post my code here also, you guys can take a look and see if you can see any problems... Basically I'm trying to get a frequency just as some type of tuner would from a microphone... Whenever I try to run the code it reads in the serial monitor "0.00 hz"

Find Wiring Here: http://postimg.org/image/6990p484l/

boolean clipping = 0;

//data storage variables
byte newData = 0;
byte prevData = 0;

//freq variables
unsigned int timer = 0;//counts period of wave
unsigned int period;
int frequency;

void setup(){
  
  Serial.begin(9600);
  
  pinMode(13,OUTPUT);//led indicator pin
  
  cli();//diable interrupts
  
  //set up continuous sampling of analog pin 0
  
  //clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;
  
  ADMUX |= (1 << REFS0); //set reference voltage
  ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
  
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA |= (1 << ADATE); //enabble auto trigger
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //enable ADC
  ADCSRA |= (1 << ADSC); //start ADC measurements
  
  sei();//enable interrupts
}

ISR(ADC_vect) {//when new ADC value ready

  prevData = newData;//store previous value
  newData = ADCH;//get value from A0
  if (prevData < 127 && newData >=127){//if increasing and crossing midpoint
    period = timer;//get period
    timer = 0;//reset timer
  }
  
  
  if (newData == 0 || newData == 1023){//if clipping
    PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led
    clipping = 1;//currently clipping
  }
  
  timer++;//increment timer at rate of 38.5kHz
}

void loop(){
  if (clipping){//if currently clipping
    PORTB &= B11011111;//turn off clippng indicator led
    clipping = 0;
  }

  frequency = 38462/period;//timer rate/period
  //print results
  Serial.print(frequency);
  Serial.println(" hz");
  
  delay(100);
}

Bump

frequency = 38462/period;//timer rate/period

I think at least part of your problem is in this statement. 38462 is too big to fit in a 16-bit integer (which is what the compiler will use unless you tell it otherwise) so it will be truncated and end up with a value of 5694.

Try:

frequency = 38462L/period;//timer rate/period

This forces 38462 to be a 32-bit integer. The division might work out better, but it still depends upon what values 'period' can have.

Pete

el_supremo:
I think at least part of your problem is in this statement. 38462 is too big to fit in a 16-bit integer (which is what the compiler will use unless you tell it otherwise) so it will be truncated and end up with a value of 5694.

Try:
This forces 38462 to be a 32-bit integer. The division might work out better, but it still depends upon what values 'period' can have.

Pete

It currently displays -1 hz... I'm still not sure if it's my wiring or code...

sigilwig444:
I'm still not sure if it's my wiring or code

I haven't checked the code. There's definitely something peculiar about the wiring. The analog input looks to be connected to a voltage divider with 10K resistors, and the divider looks to be connected between 5V and GND. No matter what, that will provide a voltage of 2.5 volts. I'm not sure what you're measuring here.

I can't tell where the input is. There's something funny about the two capacitors, too - it looks to me that they're in series. Is that what you intended?

I also can't find any description of the troubleshooting that you've already done, and what the outcome was. I can't tell what input you used to get an output value of 1 Hz.

There seems to be a lot of information missing here. Can you illuminate?

tmd3:
I haven't checked the code. There's definitely something peculiar about the wiring. The analog input looks to be connected to a voltage divider with 10K resistors, and the divider looks to be connected between 5V and GND. No matter what, that will provide a voltage of 2.5 volts. I'm not sure what you're measuring here.

I can't tell where the input is. There's something funny about the two capacitors, too - it looks to me that they're in series. Is that what you intended?

I also can't find any description of the troubleshooting that you've already done, and what the outcome was. I can't tell what input you used to get an output value of 1 Hz.

There seems to be a lot of information missing here. Can you illuminate?

I don't know too much about wiring... I'm taking a schematic from this project. I paid someone on fiverr.com to convert it to a fritzing image since I'm not too good with schmatics... I wired it up and tried to use it and that's where I am now... What else would you like to know?

I paid someone on fiverr.com to convert it to a fritzing image since I'm not too good with schmatics.

You were had.
Mind you the circuit is up to the normal instructable standards, that is crap. So you have a bad job of a bad circuit.

Remove C2. Replace the reed switch with a real switch, use a double pole switch to switch the -ve supply as well as the +ve one. On the audio input put a 10uF cap and two 10K resistors like on the audio input of the Arduino.

Check the hardware is working by just printing out the value from A0 as fast as you can. When it is working you should see a reading about 512 and steady with no audio. With audio that value will go up and down from the steady value. Until this works there is no point in trying any more software.

Bump , :frowning:

Very bad manners to bump a post especially one that is not your own.
If you have a question just ask it, all the information on this topic has been covered. Bad schematic implemented incorrectly.

Grumpy_Mike:
You were had.
Mind you the circuit is up to the normal instructable standards, that is crap. So you have a bad job of a bad circuit.

Remove C2. Replace the reed switch with a real switch, use a double pole switch to switch the -ve supply as well as the +ve one. On the audio input put a 10uF cap and two 10K resistors like on the audio input of the Arduino.

Check the hardware is working by just printing out the value from A0 as fast as you can. When it is working you should see a reading about 512 and steady with no audio. With audio that value will go up and down from the steady value. Until this works there is no point in trying any more software.

I'm sorry, this is an old thread now, but was a project that I didn't have time to think about for a while... Anyhow, I'm ready to do some more work, but I'm not sure what you're telling me to do... Could you explain more on what I need to do? Thanks!

Well I can only repeat what I said, you have to say what you don't understand and then I will try and explain that bit.

Would you believe just in the last few days a similar conversation has been happening over on the forum for Teensy?

But before that, I should mention the FreqMeasure library. (full disclosure, I'm the author of FreqMeasure and the maker of Teensy) Your original code uses the ADC, but it simply looks for the signal to be above or below a fixed threshold. If you build this with a circuit, using a voltage comparator chip, or transistors, or just feed the signal to a digital pin and how the pin's input threshold is approx what you need, you can use the FreqMeasure library. FreqMeasure is very reliable and accurate. Well, it's at least as accurate as your board's crystal.

However, FreqMeasure using a digital pin, or your original approach of low vs high on a fixed threshold depends on the signal not having much harmonic content. If strong harmonics are present, odds are good the signal will cross the low/high threshold multiple times per cycle.

With that in mind, here's the recent conversation:

Thanks to Collin Duffy's contribution, and the researchers who came up with the YIN algorithm (Alain de Cheveigne and Hideki Kawahara), you can pretty easily connect your sound to either an ADC pin or the Teensy Audio Shield and use the new note frequency object to analyze it. The YIN algorithm is pretty good at finding the fundamental frequency of your sound, even if strong harmonics are present.

The Teensy Audio Library now has an example, which you open with File > Examples > Audio > Analysis > NoteFrequency (this is only available when Teensy is selected in the Tools > Boards menu). The example plays a guitar sound sample and also analyzes it for the frequency, which prints to the Arduino Serial Monitor. This example makes trying the YIN algorithm about as easy as possible. Just open the example, upload it to your Teensy 3.2, and open the serial monitor. You can connect a computer speaker or stereo to the DAC pin to hear the sound it's analyzing. You can uncomment code to play other notes, to see & hear it work on other guitar strings. The bass guitar sounds have strong harmonics which are traditionally very tough to analyze. The YIN algorithm does it very well.

At the moment this stuff is all only on github. It'll be released in Teensyduino 1.27 in a few days. This code will only work on Teensy 3.1 & 3.2. The YIN algorithm requires a lot of computation, so there's really no hope of it ever working in real-time on Arduino Uno. But if you do have compatible hardware, this new feature should make these traditionally very difficult note detection projects pretty easy!

Grumpy_Mike:
Well I can only repeat what I said, you have to say what you don't understand and then I will try and explain that bit.

Sorry for not elaborating more...

Remove C2. Replace the reed switch with a real switch, use a double pole switch to switch the -ve supply as well as the +ve one. On the audio input put a 10uF cap and two 10K resistors like on the audio input of the Arduino.

What is C2? What is the reed switch? What's a double pole switch and the -ve supply and the +ve supply? Where is the audio input? Maybe if you could tell me where things are on my fritzing image would be helpful?

Thank you Paul for your input, but I think I'm going to worry about wiring first, and then I'll worry about the code... Once I do get the wiring down though, I will look into your FreqMeasure library... Just a little bit longer!

On the wiring diagram the capacitors are numbered, one of them is numbered C2.

The reed switch is the switch that is activated by a magnet and is shown as a pair of contacts.

A double pole switch is two sets of contacts that switch form one input to the other through the action of a single throw, or change of switch position.

The supply is the battery it has two ends the positive or +Ve end and the negative or -Ve end.

The audio input is any analogue input on your Arduino.

If you really do not know these things then your project is way too complex for you and you should do some turptorial examples first.

You should buy the Arduino Starter Kit and use it first.

I do have an advanced starter kit, and am proficient in Arduino C... Where I struggle is with wiring things, and that's why I'm asking for your help... I should hopefully be able to work on this project this week and should be able to finish the project based off of the knowledge you guys gave me... Also, what do you mean by tutorial examples? If you mean tutorial examples on the Arduino website, I've done plenty of those, but if you have any examples on audio projects, I'd love to try some out!

but if you have any examples on audio projects, I'd love to try some out!

Check out:-
http://www.thebox.myzen.co.uk/Hardware/MIDI_Shield.html
and the many other projects on the website.

For even more check out my new book at:-

Sorry, we had a bit of a misunderstanding... I was looking at the fritzing image, and you were giving me instructions on how to change the schematic... I really wasn't that dumb I guess... :grinning:

Anyhow, I entirely took apart my project today, and started from scratch with the schematic, I put it all together just like they said in the instructable, and I'm getting something, I get random numbers, sometimes 0 hz, sometimes 4 hz, sometimes 12820 hz, it's pretty unpredictable. If I print the value directly from the analog port, it sometimes is 1024, sometimes is 0, and sometimes hovers right around 512 just as you said. It almost seems something like a bad connection? Anyhow, I'll include a frizzing image that I drew of this project today, and you can compare it to the schematic and check that I read the schematic correctly. Any help that anyone can give is appreciated.

You can find the fritzing image here.

I don't appreciate being sent to a site that Bombards you with pop up windows about being a lucky winner.

Why use two batteries?
If you have to use two then you need a common ground between the two.

Did you not get the point about Instructables being crap and you should only read them if you are smarter than the author, which is not hard. Never use that site to try and learn stuff, it is just sooooo bad.

Grumpy_Mike:
I don't appreciate being sent to a site that Bombards you with pop up windows about being a lucky winner.

Why use two batteries?
If you have to use two then you need a common ground between the two.

Did you not get the point about Instructables being crap and you should only read them if you are smarter than the author, which is not hard. Never use that site to try and learn stuff, it is just sooooo bad.

Sorry about the website, it's just an easy way to post an image...

I also thought that you meant that the person I hired of fiverr was crap, not the
Instructable

Anyhow, I see the point with the two batteries, and I'll fix that, but is there anything else I can try? Or should I just start back at the post where you told me to remove C2, add a capacitor and resistors at the audio input just like the Arduino audio input, etc.

Thanks!