Offline
Newbie
Karma: 0
Posts: 33
|
 |
« on: March 14, 2012, 02:29:43 pm » |
I am making a circuit that produces a square wave whose frequency changes. However I want my Arduino to read the frequency and be able to display it on the Serial Monitor. Does anyone know how to read a frequency on the Arduino? Are there any libraries that would help? Thanks!
|
|
|
|
|
Logged
|
|
|
|
|
Offline
God Member
Karma: 9
Posts: 764
|
 |
« Reply #1 on: March 14, 2012, 02:58:32 pm » |
That shouldn't be too hard. What's the frequency range?
If you have a nice clean "digital" square wave that goes between zero and 5V. All you have to do is check the time (microseconds) when the input goes positive (or low), and check it again when the input goes positive (or low) again. Subtract for the period (the time for one cycle) and invert to get frequency (microseconds -> megahertz, etc.).
This is probably a case where interrupts are appropriate. (Trigger an interrupt when the input goes high (or low).
For better performance, you'll want to take several readings and calculate an average.
|
|
|
|
|
Logged
|
|
|
|
|
Montreal
Offline
Edison Member
Karma: 16
Posts: 2207
Per aspera ad astra.
|
 |
« Reply #2 on: March 14, 2012, 04:27:37 pm » |
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 33
|
 |
« Reply #3 on: March 14, 2012, 05:48:22 pm » |
Yes, it is a pure square wave and a duty cycle of about 50% with a tolerance of 1-2%. I'll try the time passed method with the inversion to convert to hertz. Seems pretty easy, however why would I need an interrupt?
|
|
|
|
« Last Edit: March 15, 2012, 10:49:45 am by ebird97 »
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15310
Measurement changes behavior
|
 |
« Reply #4 on: March 14, 2012, 07:03:58 pm » |
Yes, it is a pure square wave and a tolerance of about 50% with a tolerance of 1-2%. I'll try the time passed method with the inversion to convert to hertz. Seems pretty easy, however why would I need an interrupt?
Well using interrupts is one way to make sure you get a frequent update on frequency changes that won't be effected by what other things your sketch has to accomplish. If all you need to do is measure the frequency and print the results then you probably could do it simple using the pulseIn() function and a easy calculation to convert period to frequency. Again the maximum frequency is an important spec to know before deciding on best method to use. Lefty
|
|
|
|
|
Logged
|
|
|
|
|
Toronto, Canada
Offline
Edison Member
Karma: 2
Posts: 1233
"Keep it R.E.I.L. - "Research, Experiment, Investigate and Learn"
|
 |
« Reply #5 on: March 14, 2012, 11:02:51 pm » |
I did a code to read a frequency. It is basic, mind you but it work. It just use an interrupt, count for 1 second, and during that one second, count the pulse. Here the tread. http://arduino.cc/forum/index.php/topic,88358.0.htmlCheck it out. Your frequency being tested, what is the frequency ? Lowest to Highest. Maybe Nick Gammon code is better.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 33
|
 |
« Reply #6 on: March 16, 2012, 01:46:33 pm » |
Hello, So I'm back and I wrote a basic code. However, it doesn't seem to output any value other than 0. I'm a little confused to why it won't read it. Perhaps I'm using the wrong data types? Here's my code.
int sensor = 12; unsigned long highTime; float totalTime; float frequency;
void setup() { Serial.begin(9600); //begin serial communication pinMode(sensor,INPUT); }
void loop() { highTime = pulseIn(sensor, HIGH); //find time the pin goes high. totalTime = highTime*2/1000; //total time is highTime*2 because you need //to complete a whole wave cycle. Then divide by //1000 to get seconds from milliseconds frequency = 1/totalTime; //convert period to frequency by inversing it.
Serial.println(frequency); //print frequency to Serial monitor. delay(1000); //wait a second. }
|
|
|
|
|
Logged
|
|
|
|
|
Toronto, Canada
Offline
Edison Member
Karma: 2
Posts: 1233
"Keep it R.E.I.L. - "Research, Experiment, Investigate and Learn"
|
 |
« Reply #7 on: March 16, 2012, 02:30:50 pm » |
First. Do you have a 555 chip in astable mode to test your code ? int sensor = 12; unsigned long highTime; float totalTime; // Notice float here float frequency; // <----- Notice float here
void setup() { Serial.begin(9600); //begin serial communication pinMode(sensor,INPUT); }
void loop() { highTime = pulseIn(sensor, HIGH); //find time the pin goes high. // let me re-phrase that // totalTime = ( float( highTime ) * 2.0 ) / 1000.0; // <-- the correct way
// I did that what is written , and I end up nothing. // The incorrect way totalTime = highTime*2/1000; //total time is highTime*2 because you need //to complete a whole wave cycle. Then divide by //1000 to get seconds from milliseconds // let me re-phrase that // frequency = 1.0 / totalTime; // Correct way
frequency = 1/totalTime; //convert period to frequency by inversing it.
// Let me re-phrase that // Serial.println( frequency, 3 ); // < -- Display 3 decimal point. Serial.println(frequency); //print frequency to Serial monitor. delay(1000); //wait a second. }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 33
|
 |
« Reply #8 on: March 16, 2012, 05:23:03 pm » |
Can you explain what the third to last line means? This one: Serial.println(frequency, 3); What is the 3 for? And I tested the circuit, works great! Thank you so much!
|
|
|
|
|
Logged
|
|
|
|
|
Toronto, Canada
Offline
Edison Member
Karma: 2
Posts: 1233
"Keep it R.E.I.L. - "Research, Experiment, Investigate and Learn"
|
 |
« Reply #9 on: March 16, 2012, 11:27:18 pm » |
Here http://arduino.cc/en/Serial/PrintRead the reference. I always go check the reference.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 33
|
 |
« Reply #10 on: March 16, 2012, 11:46:45 pm » |
Thank You  .
|
|
|
|
|
Logged
|
|
|
|
|
|