element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum Measure square wave frequency
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 29 replies
  • Subscribers 396 subscribers
  • Views 4433 views
  • Users 0 members are here
  • square
  • arduino
  • frequency
Related

Measure square wave frequency

Former Member
Former Member over 11 years ago

Hello,

 

I'm working with the Arduino Due ans I used the following code:

 

// period of pulse accumulation and serial output, milliseconds

#define MainPeriod 100

long previousMillis = 0; // will store last time of the cycle end

volatile unsigned long duration=0; // accumulates pulse width

volatile unsigned int pulsecount=0;

volatile unsigned long previousMicros=0;

 

void setup()

{

  Serial.begin(19200);

  attachInterrupt(6, myinthandler, RISING);

}

 

void loop()

{

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= MainPeriod)

  {

    previousMillis = currentMillis;  

    // need to bufferize to avoid glitches

    unsigned long _duration = duration;

    unsigned long _pulsecount = pulsecount;

    duration = 0; // clear counters

    pulsecount = 0;

    float Freq = 1e6 / float(_duration);

    Freq *= _pulsecount; // calculate F

    // output time and frequency data to RS232

    Serial.print(currentMillis);

    Serial.print(" "); // separator!

    Serial.print(Freq);

    Serial.print(" ");

    Serial.print(_pulsecount);

    Serial.print(" ");

    Serial.println(_duration);

  }

}

 

void myinthandler() // interrupt handler

{

  unsigned long currentMicros = micros();

  duration += currentMicros - previousMicros;

  previousMicros = currentMicros;

  pulsecount++;

}

 

to measure the frequency.

 

I can measure frequencies higher than 1.5kHz accurately, but I can't seem to measure lower frequencies.

 

How can I measure lower frequencies, say 400Hz and above?

 

Thanks.

  • Sign in to reply
  • Cancel

Top Replies

  • jw0752
    jw0752 over 11 years ago +1
    Hi Matt, I don't know about this situation but usually sampling over a longer time period will improve accuracy. John
  • D_Hersey
    D_Hersey over 11 years ago in reply to jw0752 +1
    John is right, there I said it! You might be able to get more accurate timing by latching the wdt upon interrupt. Reset the Arduino Due board using the watchdog - Arduino Forum
  • Former Member
    Former Member over 11 years ago in reply to D_Hersey +1
    I tried setting mainPeriod to be longer but it still didn't measure accurately lower frequencies. Regarding the wdt , I don't understand how can it help, can you elaborate? thanks.
  • ravi_butani
    ravi_butani over 11 years ago in reply to Former Member

    do same thing with this code for getting more accurate readings...obviously it takes some more time...

    if(millis() - time_stamp > 1000)// 1sec window

    output0 = count0;

    elaboration..

    There are two ways to measure frequency..

    1. measure time period of signal by taking mcu clock as reference... example is your code with timer library   code uses hardware timer its much accurate but for multiple input signal multiple timers needed

    2. measure no of pulse in unit time .... code I have posted 

    here single hardware timer with with multiple pin interrupts used its less accurate

     

    best way is combining Hardware timer to generate accurate time window... and hardware counters for count no of pulses in this time window..

    unfortunately i havnt find any arduino contributed library for this purpose... And i havnt gone for backbone programming of atmega mcus... I can do it with msp430 bcoz I have long experience with msp430 backbone programming...

    any way I am happy that my help is useful for your project... all the best... and keep posting ur queries... we r always here to help you out..

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 11 years ago in reply to ravi_butani

    Thanks again, you really helped me.

     

    One last question, I understand that we count the number of pulses in a time window, what I don't understand is the multiplication in 2 of the number of pulses to get the frequency. Can you please explain that?

     

    Thanks.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 11 years ago in reply to Former Member

    In ravi's example, the time window is 500 milliseconds (1/2) of a second. Since frequency is cycles per second, you multiply the number of pulses recorded in time period t by 1000 milliseconds (1 second) over time period t in milliseconds, which gives us 2.  The result is the number of pulses (cycles) in one full second, aka frequency.  It is the average frequency over that 500 millisecond time period.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 9 years ago in reply to ravi_butani

    Dear Ravi Butani...

    Thanks for sharing the knowledge. I am facing the problem with measurement of square wave from freq range 100KHz to 10 MHz....

    Please explain how it is possible using Arduino Due

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • clem57
    clem57 over 9 years ago in reply to Former Member

    At some point, the 16 Mhz processor cannot run the code fast enough to respond to the frequency you are trying to measure. My guess is 10 Mhz is at that point.

    Clem

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Robert Peter Oakes
    Robert Peter Oakes over 9 years ago in reply to Former Member

    The trick to counting high frequency signals with the Arduinos is not to, let the hardware do it using a timer counter register clocked by your signal, then what you do is read the value at a fixed interval and compare the difference, this will tell you the frequency with a little simple math

     

    Here is a library that works upto 8Mhz or so the docs say

     

    Lab3 - Laboratory for Experimental Computer Science

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • D_Hersey
    D_Hersey over 9 years ago

    I gotta call BS on myself.  uP systems that disallow multi-threading in the name of simplicity obviate half the utility of uPs.  Expensive and quirky and needlessly complex compilers and cryptic, inchoate operating systems finish the job.  Jellybeans and op-ams get me on my way in a coupla days.  uPs and programmable logics are just a miasma.  It is only a matter of whether the gotchas are today or tomorrow. 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • michaelkellett
    michaelkellett over 9 years ago

    When you measure frequency you need to adopt different strategies if your pulse frequency is not much faster than the gate period and of course your clock frequency needs to be much higher than the pulse frequency. If you are counting input pulses per gate period then the best you can do with 1 second gate is 0.5% resolution at 200Hz.

    If you count clock pulses per input pulse then an 8MHz clock gives you 0.0025% resolution at 200Hz but only 0.05% resolution at 4kHz.

    You'll get better results if you count clock pulses per n input pulses and adjust n to keep the gate period constant, and even better results if you generate a new count after every input pulse but then calculate the frequency over the last n input pulses and average the results.

     

    The timer in the AVR offers input capture - I'm not sure which Arduino you have but if based on a atmega328 you have 16 bit resolution at  up to 16 MHz  - you will need to able to service an interrupt at the pulse frequency and read the timer capture register on each rising or falling edge. This will probably need you to code in C at register level but you should be able to measure 200Hz to 4kHz with 1part in 4 - 8million resolution over that range (using a 1 second gate time and variable n (see above)). The accuracy will depend on the accuracy of the processor clock.

     

    MK

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • D_Hersey
    D_Hersey over 9 years ago

    Years and years ago I read a paper where they used a phase detector to charge a capacitor in proportion to the residue to get past roundoff.  This was during a period of fervid work on PLLs and FLLs.  Too sophisticated a method to use here, but there are many ways to skin a cat.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
<
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube